简析log4j的实现方式

刚加入新公司,对日志的要求比较严格,对此特意花了几天时间看了一下log4j的源码,大概了解了一下log4j的实现方式,总结如下:

log4j的实现分为两个步骤:log4j.xml的加载,logger的使用

这里主要有两个问题,第一个问题是log4j.xml里的配置信息是怎样被logger使用的;第二个问题是logger的写文件是怎样控制的。

第一个问题

定义一个logger会这样使用

Logger logger = LogManager.getLogger("test");

依次进入getLogger

  /**
     Retrieve the appropriate {@link Logger} instance.  
  */
  public
  static 
  Logger getLogger(final String name) {
     // Delegate the actual manufacturing of the logger to the logger repository.
    return getLoggerRepository().getLogger(name);
  }

这里有两个方法,getLoggerReposityory()和getLogger(),先进入getLoggerRepository 


 static
  public
  LoggerRepository getLoggerRepository() {
    if (repositorySelector == null) {
        repositorySelector = new DefaultRepositorySelector(new NOPLoggerRepository());
        guard = null;
        Exception ex = new IllegalStateException("Class invariant violation");
        String msg =
                "log4j called after unloading, see http://logging.apache.org/log4j/1.2/faq.html#unload.";
        if (isLikelySafeScenario(ex)) {
            LogLog.debug(msg, ex);
        } else {
            LogLog.error(msg, ex);
        }
    }
    return repositorySelector.getLoggerRepository();
  }
这里repositorySelector是关键,最后返回LoggerRepository,repositorySelector是什么呢?是LogManager类下定义的一个静态变量

 static private RepositorySelector repositorySelector;

  static {
    // By default we use a DefaultRepositorySelector which always returns 'h'.
    Hierarchy h = new Hierarchy(new RootLogger((Level) Level.DEBUG));
    repositorySelector = new DefaultRepositorySelector(h);

    /** Search for the properties file log4j.properties in the CLASSPATH.  */
    String override =OptionConverter.getSystemProperty(DEFAULT_INIT_OVERRIDE_KEY,
						       null);
...

加载配置文件的源代码如下

  /**
     A static version of {@link #doConfigure(String, LoggerRepository)}.  */
  static
  public
  void configure(String filename) throws FactoryConfigurationError {
    new DOMConfigurator().doConfigure(filename, 
				      LogManager.getLoggerRepository());
  }

是通过LogManager.getLoggerRepository()来加载的,由此解释第一个问题。

第二个问题,logger的写文件是怎样控制的

这个源代码有点多,简单解释一下,是通过解析log4j.xml或者log4j.property文件,通过反射的方式生成一个一个appender,然后加入到logger维护的一个列表下,当调用info,dubug,error,warn时通过调过遍历appender来实现对输入文件的控制

 

注:看得源码是针对log4j的1.0版本,估计2.0的版本也差不多

大致看懂了原理,自我标注一下,便于提高

转载于:https://my.oschina.net/u/2402401/blog/1835038

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值