java log们的加载过程
1.概述
现在的log框架越来越多,目前我们系统用有使用的包括commons-logging,log4j,slf4j(还有一个号称更快的logback暂时基本没有用到),而这些log系统又常常依赖于一些jar包顺序和静态配置,导致比较混乱,甚至出现一些难以重现的诡异问题,因此在这里就各个log系统的初始化过程介绍一下,方便以后排查问题。
本文主要侧重多个日志系统的混合使用和加载,对于日志级别,格式等等方面不涉及。
?
2.介绍2.1. commons-logging
apache提供的日志门面接口,主要是为了避免程序和具体的log耦合。
基本使用方法:
?
Logger logger =org.apache.log4j.Logger.getLogger(Log4jTest.class); logger.debug("test debug");?
初始化过程:
1.检查系统变量Log4j.configuration,如果有值,使用这个值设定的配置文件,否则先尝试在classpath中加载log4j.xml,没有再尝试加载log4j.properties.找到对应的配置文件后,调用对应的DOMConfigurator或者PropertyConfigurator来初始化
configurator.doConfigure(url, hierarchy);
2.如果都没有配置,那么需要在应用中显示调用DOMConfigurator或者PropertyConfigurator来初始化。
3.如果在程序执行的过程中,代码调用了一次XXXConfigurator.configure(),所有对应的logger的设置都会随之改变。
?
3.分析一个实际例子我们在启动jetty的时候,jetty用的是slf4j,我们在lib中放置了slf4j-api-1.6.4jar,slf4j-log4j12-1.6.4jar和log4j.properites,所以会使用log4j打印log。
?
在应用起来的过程中,由于是自己的classloader,不会复用jetty本身的log配置,首先加载的是,dragoon的filter用了slf4j,而这个时候应用的log4j系统还没有初始化,于是就在类路径的jar包中随便找到了第一个log4j.prpperties,然后正好输出到了控制台。(因此在启动中有几行dragoon的控制台输出)
servelt初始化后,webx利用commons-logging包装了log4j,在war包的WEB-INF下查找log4j配置文件并使用,覆盖掉开始dragoon初始化的log4j提醒,这样在应用中所有的log4j都会使用新的这套配置了。因此除了系统的应用代码外,二方库和3方库如果使用了log4j,commons-logging和slf4j的方式打log,都会使用我们WEB-INF下的log4j配置。未特殊设置的,都会打印到root对应的appender上面去。
?
4.参考文献:http://commons.apache.org/logging/commons-logging-1.1.1/guide.html
http://www.slf4j.org/manual.html
http://logging.apache.org/log4j/1.2/manual.html