作者:聂勇 欢迎转载,请保留作者信息并说明文章来源!
前面介绍了Log4j的总体架构,这篇文章接着介绍Log4j的初始化。
Log4j初始化 | Log4j Initialization
下面分三个步骤来介绍Log4j的初始化:
1、getLogger(String)
在代码中我们以如下的代码来使用Log4j。
在执行Logger.getLogger(Class)方法,在Log4j内部会执行一系列方法。其执行序列图如下所示:
2、LogManager初始化
如果是第一次调用LogManager,这时Log4j会读取配置文件并对自身初始化。其执行序列图如下:
其中:
1)Hierarchy 实现了 LoggerRepository 接口。
2)RootLogger 实现了 Logger 接口。
3)DefaultRepositorySelector 实现了 RepositorySelector 接口。
4)getSystemProperty(String key, String def)) 这一步骤中获取系统变量 log4j.defaultInitOverride、log4j.configuration、log4j.configuratorClass 的值。log4j已经不推荐设置这些系统变量。
5)getResource(String) 这一步骤中获取 log4j.xml、log4j.properties 配置文件。首先获取log4j.xml,然后再获取log4j.properties,如果在log4j.xml 和 log4j.properties 都获取失败的情况下会用 log4j.configuration 来代替(如果log4j.configration存在的话)。
6)selectAndConfigure 这一步骤中,如果class 为空,并且 url 指向的文件名后缀为 xml,则将class设置为“org.apache.log4j.xml.DOMConfigurator”,否则新建一个“org.apache.log4j.PropertyConfigurator”的实例。
3、解析配置文件
获得一个Configurator实例后,调用它的 doConfigure(Url url, LoggerRepository repository)方法传入配置文件完事路径,然后解析配置文件内容。
下面以 log4j.xml 为例来介绍配置文件的解析过程:
1)在执行 doConfigure(ParseAction action, LoggerRepository repository) 方法时,会通过获取系统的环境变量 javax.xml.parsers.DocumentBuilderFactory 获得XML的Document解析器对配置文件log4j.xml进行解析。
2)parse(Element element)的关键代码如下。
1、获取根元素的 tagName。
1)如果 tagName 不是 log4j:configuration 并且 不是已经不推荐的 configuration,输出错误信息。
2)如果 tagName 不是 log4j:configuration 是已经不推荐的 configuration,输出警告信息。
2、获取根元素的 debug 属性。
1)如果 debug 属性的值不等于””且不等于”null”,调用 LogLog.setInternalDebugging(boolean),否则输出调试信息。
3、获取根元素的 reset 属性。
1)如果 reset 属性的值 不等于””且等于”true”,调用 repository.resetConfiguration()。
4、获取根元素的 threshold 属性。
1)如果 threshold 属性不等于””且不等于”null”,调用 repository.setThreshold(String)。
5、循环处理根元素的所有子元素。
1)如果子元素是 categoryFactory 或 loggerFactory,则调用内部方法 parseCategoryFactory(Element factoryElement) 处理;
6、再次循环处理根元素的所有子元素。
1)如果子元素是 category 或 logger,调用内部方法 parseCategory(Element loggerElement) 处理。
2)如果子元素是 root,调用内部方法 parseRoot(Element rootElement) 处理。
3)如果子元素是 renderer,调用内部方法 parseRenderer(Element rootElement) 处理。
4)如果子元素是 throwableRenderer 并且repository instanceof ThrowableRendererSupport,调用内部方法 parseThrowableRenderer(Element rootElement) 处理返回一个ThrowableRenderer,如果没有返回null,调用((ThrowableRendererSupport) repository).setThrowableRenderer(ThrowableRenderer)。
5)如果子元素是 appender 或者 categoryFactory 或者 loggerFactory,调用内部方法 quietParseUnrecognizedElement(Object instance, Element element, Properties props) 处理。
相关文章 | Index
1、Apache Log4j 架构
2、Apache Log4j 架构之初始化
3、Apache Log4j 架构之输出日志