log4j2源码解析
2021-07-21 11:14:57 2 举报
log4j2 启动---> 解析配置-->打印日志
作者其他创作
大纲/内容
PROVIDERS
检查是否符合打印级别
通过classLoader.getResource(resource);加载classpath下的log4j2.xml,其实就是工程的编译打包后的根目录下。封装成一个ConfigurationSource:属性: FileURLstreambyte[]
创建一个日志事件用工厂
callAppenders(event);
getContext
return Log4jLogEvent
isFiltered(event)
doConfigure()
ClassLoaderContextSelector
toByteArray(event)
children.add(childNode);// 例如 关联子节点,这里children 是父节点,childNode 是子节点,例如 properties 对应的子类property 都添加
getLayout()
举例:ConsoleAppender
this.config = config;//完成config解析后赋值到LoggerContext中,config是 XmlConfiguration
reconfigure(configLocation);
LogConfig
loadProvider
ConfigurationFactory.Factory
return Configuration
不是一个方法,只是代码写在了getLogger方法里面
Method:log
lazyInit();
info(final String message)
attribute:loggerConfig
XmlConfiguration
getLogger
PrivateConfig
getConfiguration
拥有所有最后输出打印的信息,封装在这里面
LoggerContext
toSerializable(final LogEvent event)
getLogger(clazz.getName()
put
Logger
ProviderUtil
总结:1加锁2 事件内容转为字节数据3输出流输出到控制台注意:此实现类是ConsoleAppender
PrivateConfig中获取了 XmlConfiguration中的LoggersConfig配置,其中的level 赋值,可以用于后面打印日志判断级别:例如api:logger.isDebugEnbale
setup();
return LoggerContext
log(event);
manager.write(bytes);
readLock.lock();
LogManager
static
logger.info
ProviderUtil();
1
Log4j2的Loggers配置详解https://blog.csdn.net/ThinkWon/article/details/101628736
日志输出啦
ConfigurationFactory
return LoggerContext
start
3
api调用
LogManager.getLogger
reconfigure();//重新配置上下文。
createEvent
Layout
return Logger
画图原则:1 目的画源码图,可追踪源码,2 一个方法里调用复杂属性的方法,应当,把代码写上,不用画方格,直接用代码连接,属性对应的类对应的方法3 每个长方形格最上方一般是方法名字,如果是属性会前缀例如: atttribute:loggerConfig
LogManager的静态块
return Configuration
DefaultLogEventFactory
在构造中会解析log4j2.xml的根节点(Configuration)信息封装
append(event)
模板方法用的真好,所有的appender,都是这样的,样板代码
TreeMap
这里会递归调用,将所有的子节点的Object属性赋值
setParents();// 在log4j2.xml 中的<Loggers> 的子标签包含<Root> 和 <Logger> ,而<Logger> 标签表示继承<Root>标签
Log4jLogEvent
createConfiguration
在这里有很深层次的嵌套,会初始化所有插件类,插件的配置文件是,META-INF下的org.apache.logging.log4j.core.config.plugins.Log4j2Plugins.dat的文件,log4j2 有69个插件!!类型
判断过滤器如果是Filter.Result.DENY;则不打印日志
final byte[] bytes = getLayout().toByteArray(event);
new XmlConfiguration(source);
getProviders()
for循环调用每个appender
2
// 将配置文件里的信息封装成具有层次的节点关联起来
AbstractOutputStreamAppender
readLock.unlock();
LogContextFactory
//开始配置 instance是XmlConfiguration setConfiguration(instance);
在这里我再次深深的感受到,代码的每个api的抽取,太好了,如果是我自己设计,也是会逐个解析每个占位符,大概率我会都写在 一个类里的不同方法中,而像log4j2却对每个占位符有单独的维护类解析,优点太多了1 如果某个占位符不对,则只需要维护这个类,2 排查问题可以直接定位,因为异常啥的可以直接抛出3方便以后扩展,如果新增占位符,就新增一个解析类,符合开闭原则
0 条评论
回复 删除
下一页