Log4J日志输出源码分析

JAVA日志是很成熟的组件,再加上其作用单一,所以大家一般都是拿来就用,对其研究其实并不多。

但有些场景需要对日志组件做些改造,如某项目制的软件,因为jar包太多项目更新时上传、下载会耗费大量时间,对于完全不做更新的一些jar包确实没必要一直堆在war包里,所以就有了tomcat的共享jar包shared.loader方案来改进这个问题。当我们把所有公共jar一股脑共享后造成一个新的问题,不同war的日志居然输出到了同一个文件,这样日志就没法看了。

什么原因?这个不看源码是解决不了了,从LoggerFactory.getLogger切入源码,首先是寻找LoggerFactory,这个过程主要是找出slf4j的实现,最终在找一个StaticLoggerBinder的类。我们顺藤摸瓜找到了AbstractLoggerAdapter适配器,此时我们会注意到一个日志上下文,这里记录了每个war包输出日志的路径,我们注意到官方用到了享元模式来优化性能,这里说明了为什么要传入不同的name或者class,因为依据这个来给不同内容分类输出日志。当我看到上下文的具体获取逻辑(如图),共享包遇到的问题我们瞬间就明白了

protected LoggerContext getContext(final Class<?> callerClass) {
        ClassLoader cl = null;
        if (callerClass != null) {
            cl = callerClass.getClassLoader();
        }
        if (cl == null) {
            cl = LoaderUtil.getThreadContextClassLoader();
        }
        return LogManager.getContext(cl, false);
}

真相只有一个:又是classloader的作妖(大多数场景classloader逻辑是优秀的,可以详细去了解双亲委派机制,但少数业务场景,我们又比较烦classloader)

好在官方同样提供了从线程获取上下文的逻辑,那对于源码改造我们就变得简单了,直接从线程获取即可。

以上就是我们对log4J源码的一次学习。根据官方提供的线程获取上下文的思路,我们同样可以使用线程来获取applicationContext,这种方式对解决共享包问题尤为有效。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值