sl4j的多种log4j实现导致日志不能打印
前言
目前在做项目过程中,发现部分项目的日志无法打印,一直不知道原因。分析发现是日志jar冲突,由于日志jar冲突是隐式引用,很难排查,加上我们经常不注意日志本身的报错。
1. 冲突jar
模拟jar冲突的project,pom如下
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.10.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.26</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.10.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.10.0</version>
</dependency>
</dependencies>
随意写一个log4j2.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="info">
<Appenders>
<Console name="console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{DATE} %c{1}:%L - %m%n" />
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="console" />
</Root>
</Loggers>
</Configuration>
写一个测试方法,这里说一下sl4j是日志接口,没有实现,可以集成log4j2与logback等,推荐使用打日志。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Slf4jDemo {
private static final Logger logger = LoggerFactory.getLogger(Slf4jDemo.class);
public static void main(String[] args) {
logger.info("----------------------------");
}
}
运行结果如下:
/software/jdk1.8.0_191/bin/java -javaagent:/software/ideaIde/lib/idea_rt.jar=36051:/software/ideaIde/bin -Dfile.encoding=UTF-8 -classpath /software/jdk1.8.0_191/jre/lib/charsets.jar:/software/jdk1.8.0_191/jre/lib/deploy.jar:/software/jdk1.8.0_191/jre/lib/ext/cldrdata.jar:/software/jdk1.8.0_191/jre/lib/ext/dnsns.jar:/software/jdk1.8.0_191/jre/lib/ext/jaccess.jar:/software/jdk1.8.0_191/jre/lib/ext/jfxrt.jar:/software/jdk1.8.0_191/jre/lib/ext/localedata.jar:/software/jdk1.8.0_191/jre/lib/ext/nashorn.jar:/software/jdk1.8.0_191/jre/lib/ext/sunec.jar:/software/jdk1.8.0_191/jre/lib/ext/sunjce_provider.jar:/software/jdk1.8.0_191/jre/lib/ext/sunpkcs11.jar:/software/jdk1.8.0_191/jre/lib/ext/zipfs.jar:/software/jdk1.8.0_191/jre/lib/javaws.jar:/software/jdk1.8.0_191/jre/lib/jce.jar:/software/jdk1.8.0_191/jre/lib/jfr.jar:/software/jdk1.8.0_191/jre/lib/jfxswt.jar:/software/jdk1.8.0_191/jre/lib/jsse.jar:/software/jdk1.8.0_191/jre/lib/management-agent.jar:/software/jdk1.8.0_191/jre/lib/plugin.jar:/software/jdk1.8.0_191/jre/lib/resources.jar:/software/jdk1.8.0_191/jre/lib/rt.jar:/home/huahua/IdeaProjects/demo/target/classes:/home/huahua/.m2/repository/org/slf4j/slf4j-log4j12/1.6.1/slf4j-log4j12-1.6.1.jar:/home/huahua/.m2/repository/log4j/log4j/1.2.16/log4j-1.2.16.jar:/home/huahua/.m2/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.10.0/log4j-slf4j-impl-2.10.0.jar:/home/huahua/.m2/repository/org/slf4j/slf4j-api/1.7.26/slf4j-api-1.7.26.jar:/home/huahua/.m2/repository/org/apache/logging/log4j/log4j-api/2.10.0/log4j-api-2.10.0.jar:/home/huahua/.m2/repository/org/apache/logging/log4j/log4j-core/2.10.0/log4j-core-2.10.0.jar com.feng.demo.Slf4jDemo
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/home/huahua/.m2/repository/org/slf4j/slf4j-log4j12/1.6.1/slf4j-log4j12-1.6.1.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/huahua/.m2/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.10.0/log4j-slf4j-impl-2.10.0.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
log4j:WARN No appenders could be found for logger (com.feng.demo.Slf4jDemo).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Process finished with exit code 0
由于经常忽略wran日志,项目启动后仅有少量的业务日志(估计有些日志不是log4j实现的),所以很难排查问题。
其实上面的日志已经说明了冲突的地方
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/home/huahua/.m2/repository/org/slf4j/slf4j-log4j12/1.6.1/slf4j-log4j12-1.6.1.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/huahua/.m2/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.10.0/log4j-slf4j-impl-2.10.0.jar!/org/slf4j/impl/StaticLoggerBinder.class]
org/slf4j/impl/StaticLoggerBinder.class在2个jar
slf4j-log4j12-1.6.1.jar
log4j-slf4j-impl-2.10.0.jar
都有实现,由于使用的log4j2,slf4j-log4j12-1.6.1.jar是log4j的1.x版本用的,只有删除依赖就可以了。
删除后日志正常
30 三月 2019 10:23:55,282 Slf4jDemo:10 - ----------------------------
2. 隐式依赖冲突
我们知道使用log4j2不会引用log4j的1.x的版本,那么上面的依赖怎么来的呢,这里就是隐式依赖造成的
笔者是使用zookeeper的jar没注意引入的,比如zookeeper的3.4.13的jar
<!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.13</version>
<type>pom</type>
</dependency>
在mvnrepository.com中明确说明依赖log4j的1.x的jar
intellij idea也可以看见
需要exclude掉log4j的1.x的jar
总结
jar冲突其实也还好解决,日志都会有提示的,只是平时没注意