Log4j源码三

LogManager
  1 field : 常量和RepositorySelector
  2 静态代码块
  •      创建默认的日志容器  Hierarchy
  •      创建默认的容器选择器 RepositorySelector 
  •      判断加载的配置文件 
  通过判断log4j.default_init_override_key来判断是否初始化配置文件。
 首先来加载xml文件,然后加载properties文件,构建为URL对象。
调用方法来加载文件,configuratorClassName为配置的读取文件类,后面那个是容器。
OptionConverter.selectAndConfigure(url, configuratorClassName, LogManager.getLoggerRepository());
<span style="font-size:14px;">static public void selectAndConfigure(URL url, String clazz, LoggerRepository hierarchy) {// 配置文件地址,指定解析类,容器
        Configurator configurator = null;
        String filename = url.getFile();
        if (clazz == null && filename != null && filename.endsWith(".xml")) { //如果是xml文件,且没有指定解析类
            clazz = "org.apache.log4j.xml.DOMConfigurator"; // 默认指定xml解析类
        }
        if (clazz != null) {
            LogLog.debug("Preferred configurator class: " + clazz);
            configurator = (Configurator) instantiateByClassName(clazz, Configurator.class, null); // 实例化clazz
            if (configurator == null) {
                LogLog.error("Could not instantiate configurator [" + clazz + "].");
                return;
            }
        } else {
            configurator = new PropertyConfigurator(); // 没有解析类 ,则用  property
        }
        configurator.doConfigure(url, hierarchy); // 加载配置
    }</span>
插入 实例化clazz的过程 Class.forName(clazz) 或者 log4j用反射等同Thread.currentThread().getContextClassLoader().loadClass(clazz) 


下面说明属性文件加载过程
doConfigure有四个重载方法,最终调用doConfigure(Properties,LoggerRepository)
先判断了一个log4j.debug属性,默认开启内部日志debug模式
LogLog.setInternalDebugging(OptionConverter.toBoolean(value, true)); // 默认允许
然后判断log4j.reset属性,当且仅当false时,容器重配resetConfiguration()
最后log4j.threshold属性,会解析值,如果值包含${} 变量或者 ${${}} 这种情况,
解析的value可能格式为levle#classname形式,可自定义设置threshold
<ol><li><span style="font-family: Arial, Helvetica, sans-serif;"> configureRootCategory(properties, hierarchy); // 配置 root logger</span></li><li><span style="font-family: Arial, Helvetica, sans-serif;"> configureLoggerFactory(properties); // 配置 logfactory</span></li><li><span style="font-family: Arial, Helvetica, sans-serif;"> parseCatsAndRenderers(properties, hierarchy);  // 解析 logger 和 渲染</span></li><li><span style="font-family: Arial, Helvetica, sans-serif;"> LogLog.debug("Finished configuring.");</span></li><li><span style="font-family: Arial, Helvetica, sans-serif;"> registry.clear(); // 不持有appenders引用,gc回收</span></li></ol>
 第一步

  解析log4j.rootlogger属性,如果不是空字符串且不以逗号开头,得到levelStr,如果levelStr等同于inherited或者null,判断是否为root来设置level
  然后清空logger的appender,在解析配置中的appender,添加到logger中。
  用hashtable来判断是否已加载过appender
 三个属性,后两个要判断appender instanceof OptionHandler
  log4j.appender.appenderName   log4j.appender.appenderName.layout log4j.appender.appederName.errorHandler
 layout 除了实例化外 增加PropertySetter.setProperties操作
 errorhandler 增加解析ref操作和PropertySetter.setProperties操作
解析Filters,log4j.appender.appenderName.filter
PropertySetter.setProperties(); 稍后说明,大意是通过配置获取属性和value,然后通过反射来赋值。

 第二步
 
 读取配置的log4j.loggerfactory 实例、属性赋值

  第三步
  1 解析logger 解析过程同第一步,增加 log4j.additivity的设置
  2 renderer    RendererMap. addRenderer稍后说明
  3  throwablerenderer

另外PropertyConfigurator提供configureAndWatch方法来检查配置的更改。
 PropertyWatchDog extends FileWatchDog  重写父类 doOnchange(),由父类调用,模板方法


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值