问候,亲爱的朋友们!
我想分享有关日志记录及其思想的想法。
也许由于缺乏理论研究,日志记录一直是Java世界中动荡的领域。 随着时间的流逝,这导致出现了一些用于记录的库,例如:
- Log4j
- Java Util记录
- 共用记录
- 退回
- Log4j2
不幸的是,他们试图缩小其余的其余部分,但都引入了自己的缺点。
而且,如果从代码标准化的角度来看,在Slf4j出现之后情况有所改善-作为日志记录的抽象层,现有的实现中仍然存在未解决的问题。
作为一个开放源代码社区,我们正在主动提出一种革命性的新方法-使用脚本等最新开发技术来创建轻量(但同时功能丰富)的记录器。
问题所在
-现有的实现仅对设置中的脚本提供部分支持
这将导致在记录器配置文件(XML,JSON,YAML)中进行声明式编程,尽管使用命令性脚本在运行时动态解释配置值要简单得多。
让我们以Logback中的过滤器配置为例,该配置仅记录日志级别为INFO的消息:
<filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>INFO</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter>
这是声明性XML编程的典型示例。
(是的,Logback支持使用Groovy的过滤器,但它仅适用于特定的附加程序,不适用于记录器)
但是完全缺少用于格式化字符串的脚本支持。
-复杂而冗长的配置
进行Logback和Log4j2:
无法为特定的附加程序配置日志记录级别。
Appender与记录器分开配置,并且记录器使用“ AppenderRef”属性引用附加器-而只有记录器支持设置记录级别和类名称。
假设我们需要从一个特定的日志文件中排除一个Foo类的调试消息,而又不影响其他日志文件和类。
在Logback中,可以使用追加器上的Groovy脚本过滤器来实现-但是,如果我们有多个追加器,则配置的大小将呈指数增长。
-对于每个级别的日志记录-一个单独的文件!
我们找不到这种设置的可能性,在这种设置中,消息按消息级别(调试,信息等)分组到文件中
现有功能需要在每个日志记录级别重复添加器。
-在Root记录器本身中按类名设置过滤
根记录器仅支持设置记录级别,但不可能集中控制应记录哪些类。
-在应用程序中如何生成日志数据与记录器如何使用这些数据之间存在概念上的脱节
历史惯例是,与以文件为中心的记录器(及其配置)相比,它们更以类为中心。
这与人类的感知相矛盾,人类的感知更合乎逻辑地感知围绕日志文件最终内容的期望,而不用担心设置每个单独的类。
实际上,此悖论是现有实现的功能局限性的原因:
Logback在“ SiftingAppender”中最多支持1个“ discriminator”。
SiftingAppender在用于存档的策略设置中有限制
在Log4j2中重新设计了RoutingAppender
解决方案
-配置中的完整脚本支持
Bobbin使用该配置作为Groovy脚本的定位器,这些脚本确定了记录程序在应用程序运行时中的行为。
这是“过滤器”示例的样子:
{ "levels": "['info'].contains(level)" }
记录器的每个方面都支持使用脚本进行自定义:
-简单明了的设置
梭芯不需要编码器,图案,滤波器,鉴别器和许多其他不必要的东西。
它仅配置了一些基本参数:
每个记录级别的文件都分开:只需在Bobbin.json(配置文件)的文件名掩码中放入“ $ {level}”即可。
示例配置文件:
{ "levels": "['debug', 'info', 'warn', 'error'].contains(level)", "destinations": [ { "name": "io.infinite.bobbin.destinations.FileDestination", "properties": { "fileName": "\"./LOGS/PLUGINS/INPUT/${className}/${level}/${className}_${level}.log\"" }, "classes": "className.contains('conf.plugins.input')" }, { "name": "io.infinite.bobbin.destinations.FileDestination", "properties": { "fileName": "\"./LOGS/PLUGINS/OUTPUT/${className}/${level}/${threadName}_${level}_${date}.log\"" }, "classes": "className.contains('conf.plugins.output')" }, { "name": "io.infinite.bobbin.destinations.FileDestination", "properties": { "fileName": "\"./LOGS/THREADS/${threadGroupName}/${threadName}/${level}/${threadName}_${level}_${date}.log\"" }, "classes": "className.contains('io.infinite.')" }, { "name": "io.infinite.bobbin.destinations.FileDestination", "properties": { "fileName": "\"./LOGS/ALL/WARNINGS_AND_ERRORS_${date}.log\"" }, "levels": "['warn', 'error'].contains(level)" }, { "name": "io.infinite.bobbin.destinations.ConsoleDestination", "levels": "['warn', 'error'].contains(level)" } ] }
立即尝试Bobbin:
Gradle: compile "io.infinite:bobbin:2.0.0"
* Bobbin是Apache许可的开放源代码项目。