记一次项目上线后Log4j2不输出日志的坑

    公司项目采用了Log4j2来输出日志,在开发环境和测试环境下均可以输出日志,但在生成环境就没有日志输出。开始毫无头绪,后来通过不断的排查,终于解决了这个问题。在此记录下该问题的解决过程,便于后续查阅。

一、发现问题

     开发环境打印日志但生产环境不打印日志这个问题比较棘手。一直找不到原因,后面突然想到在启动的时候打印信息肯定会有所不同。通过在 2个环境启动同一个项目的控制台打印信息对比有了以下的发现:
(1) 出现了 SL4J 的警告信息,都是提示包冲突
               Multiple bindings were found on the class path
(2) 但是仔细观察发现了 加载这两个冲突的jar包的顺序不同 ,具体见下图:

    ①开发环境日志冲突jar包加载顺序图

记一次项目上线后Log4j2不输出日志的坑_第1张图片
        防止图失效,我把文字复制过来了
SLF4J:Class path contains mutiple SLF4J bindings
SLF4J:Found binding in[jar:file:/WEB-INF/lib/log4j-slf4j-impl-2.6.6.jar!/org/slf4j/impl/StaticLoggerBider.class]
SLF4J:Found binding in[jar:file:/WEB-INF/lib/slf4j-log4j12-1.7.22.jar!/org/slf4j/impl/StaticLoggerBider.class]
3
 
1
SLF4J:Class path contains mutiple SLF4J bindings
2
SLF4J:Found binding in[jar:file:/WEB-INF/lib/log4j-slf4j-impl-2.6.6.jar!/org/slf4j/impl/StaticLoggerBider.class]
3
SLF4J:Found binding in[jar:file:/WEB-INF/lib/slf4j-log4j12-1.7.22.jar!/org/slf4j/impl/StaticLoggerBider.class]

    

    ②生产环境日志冲突jar包加载顺序图

记一次项目上线后Log4j2不输出日志的坑_第2张图片
        防止图失效,我把文字复制过来了

SLF4J:Class path contains mutiple SLF4J bindings
SLF4J:Found binding in[jar:file:/WEB-INF/lib/slf4j-log4j12-1.7.22.jar!/org/slf4j/impl/StaticLoggerBider.class]
SLF4J:Found binding in[jar:file:/WEB-INF/lib/log4j-slf4j-impl-2.6.6.jar!/org/slf4j/impl/StaticLoggerBider.class]
3
 
1
SLF4J:Class path contains mutiple SLF4J bindings
2
SLF4J:Found binding in[jar:file:/WEB-INF/lib/slf4j-log4j12-1.7.22.jar!/org/slf4j/impl/StaticLoggerBider.class]
3
SLF4J:Found binding in[jar:file:/WEB-INF/lib/log4j-slf4j-impl-2.6.6.jar!/org/slf4j/impl/StaticLoggerBider.class]

二、分析

  • 在开发环境,先加载的是 log4j-slf4j-impl ,后加载的是slf4j-log4j12。而生产环境, 先加载的是 slf4j-log4j12 ,后加载的是log4j-slf4j-impl
  • 通过查阅官方资料发现slf4j在绑定时,如果有多个可以绑定的包, SLF4J选择绑定的方式由JVM确定,并且出于所有实际目的应该被认为是随机的
  • 但是 ,经过我12次在slf4j源码打断点测试发现slf4j优先绑定先加载的jar包。所以在开发环境slf4j绑定的是log4j-slf4j-impl这个jar包,而在生产环境中绑定的是slf4j-log4j12这个jar包。
  • 通过查阅log4j2官方资料可知,slf4j集成log4j2时需要的桥接包是 log4j-slf4j-impl 开发环境中slf4j绑定是正确的,因此可以打印日志 。而生产环境中slf4j绑定的jar包是slf4j-log4j12。所以生产环境输出不了日志。产生这个问题的根本原因是lib里面有多个了slf4j可绑定的jar包。

三、解决方案

     由于是slf4j绑定jar包错误而导致打印不了日志。所以我们必须要把这个slf4j-log4j12.jar包排除干净。这个包主要来源有:
1framework-logger(公司自己封装的框架)
2zkclient
3zookeeper
    排除完jar包后,本地进行打包。打包完成后,必须要检查一遍,看一下生成的打包文件的lib文件夹下是否还存在slf4j-log4j12.jar。如果有,应该是jar包没排除干净。可以通过maven命令查看依赖树,看看是那个依赖把这个jar给传递进来的。命令为:dependency:tree

四、小结

(1)使用SLF4j+Log4j2时使用的桥接包是log4j-slf4j-impl
(2)当有多个SLF4j的桥接包时,一定要排除不需要的包
(2)项目启动时控制台输出的信息很重要,耐心观察启动日志可以解决很多问题







转载于:https://www.cnblogs.com/zeng1994/p/df2559e6dc66c99065676e0ee70545eb.html

你可能感兴趣的:(记一次项目上线后Log4j2不输出日志的坑)