PatternFormatter
LogEventPatternConverter
### - LevelPatternConverter
### - ThreadPatternConvter
### - DatePatternConverter
FormattingInfo
PatternLayout
在对PatternLayout的pattern字段进行解析(PatternParser的parse(final String pattern, final boolean alwaysWriteExceptions,final boolean noConsoleNoAnsi)中进行)时,会生成 List
formatters
PatternFormatter(LogEventPatternConverter,FormattingInfo) 其中LogEventPatternConverter用来将日志事件LogEvent转换为指定格式的字符串并追加到输出字符串后。
插件的初始化入口在:
PluginManager.collectPlugins里,它会创建一个PluginRegistry单例,其
decodeCacheFiles
方法用于从META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat文件中加载并解析插件对象,并按类别存储。目前共有6中类型插件:converter,lookup,core,configurationfactory,fileconverter,typeconverter
PatternLayout的处理:
在实例化PatternFormatter时,同时会通过PatternParser将 字符串转换成转换器列表
PatternFormater(LogEventPatternConverter,FormattingInfo)
。LogEventPatternConverter是转换类插件的抽象类。
下图演示的就是其对应关系:
个人感觉SLF4J的实现更加灵活,并且它还提供了Maker和MDC的接口
3. SLF4J 与 Common-logging对比
common-logging通过动态查找的机制,在程序运行时自动找出真正使用的日志库。由于它使用了ClassLoader寻找和载入底层的日志库, 导致了像OSGI这样的框架无法正常工作,因为OSGI的不同的插件使用自己的ClassLoader。 OSGI的这种机制保证了插件互相独立,然而却使Common-logging无法工作。
slf4j在编译时静态绑定真正的Log库,因此可以在OSGI中使用。另外,SLF4J 支持参数化的log字符串;其次其避免了之前为了减少字符串拼接的性能损耗而不得不写的if(logger.isDebugEnable()),可以直接写:logger.debug(“current user is: {}”, user)。拼装消息被推迟到了它能够确定是不是要显示这条消息的时候,但是获取参数的代价并没有幸免。