log4j2不打印⽇志或者打印不受控制的⽇志解决办法
起因
前⼏天⼀个跑有java应⽤的⽣产集(200多台物理机)升级了⼀个版本,重启后发现约有50台机器⽇志不能正常输出,但其程序确能正常的运⾏,在⽣产环境中,⽇志是⾮常重要的⼀个监控⼿段,如果没有⽇志输出,⽆疑是⾮常危险的。
排查
log4j2不打印日志发现这⼀情况后,⽴即开始从jdk环境和版本,cpu负载,内存gc,线程stack,死锁,磁盘容量等多⽅⾯排查,但均没有发现异常情况,唯⼀的⼀点信息是Java进程重启时重定向到out⽂件⾥⾯的控制台输出,如下(以下均为复现时的输出):
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/Users/qindongliang/.m2/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.3/log4j-slf4j-impl-2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/Users/qindongliang/.m2/repository/org/slf4j/slf4j-log4j12/1.7.12/slf4j-log4j12-1.7.12.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See /codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory]
起初并没有在意⽇志包冲突的这个细节,因为其他正常启动并能够正常打印log的机器中,也有同样的输出。所以基本肯定与这个冲突关系不⼤。
但苦于没有其他⽇志输出,并且当前的进程是在正常的Runnable状态中,所以⼜把⽬光回到了刚才的out⽂件,经过与正常机器中⼤部分out⽂件⽐较,发现了⼀点端倪。
(1)⼤多数能够正常打印log机器的out⽂件输出是:
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/Users/qindongliang/.m2/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.3/log4j-slf4j-impl-2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/Users/qindongliang/.m2/repository/org/slf4j/slf4j-log4j12/1.7.12/slf4j-log4j12-1.7.12.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See /codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory]
(2)少部分正常打印log的机器和其他不打印log的机器的out⽂件输出是:
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/Users/qindongliang/.m2/repository/org/slf4j/slf4j-log4j12/1.7.12/slf4j-log4j12-1.7.12.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/Users/qindongliang/.m2/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.3/log4j-slf4j-impl-2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See /codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
对⽐上⾯两个输出⽂件中的第三⾏,第四⾏和最后⼀⾏,发现不同的机器有可能输出的不⼀样,另外⼀点能够得到的是正常的机器sfl4j binding 最后⼀⾏都是⼀样的类:
org.apache.logging.slf4j.Log4jLoggerFactory
⽽少数正常和所有不正常的slf4j binding的类是:
org.slf4j.impl.Log4jLoggerFactory
解决
这明显是slf4j binding包冲突造成的,经过调查发现,前者是log4j2.x⽤的⼯⼚实现类,⽽后者是兼容log4j1.x⽤的⼯⼚类,他们分别位于:
log4j-slf4j-impl-2.3.jar
slf4j-log4j12-1.7.12.jar
这两个jar包中,都有各⾃的StaticLoggerBinder类,所以才造成了冲突,因为我们⽤的是log4j2的⽇志组件,所以解决的⽅法就是移除掉与其冲突的log4j 1.x的slf4j-log4j12-1.7.12.jar包即可。
在移除后,我们再次重启任务,发现这下⽇志⼜可以正常输出了,⾄此算是解决了这个问题。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。