springboot 日誌問題記錄
摘要: 問題:新建工程busr,採用pandora boot,引入了需要的包,簡單寫了點程式碼釋出,spring-boot啟動報錯: Caused by: java.lang.IllegalArgumentException: LoggerFactory is not a Logback LoggerContext but Logback is on the classpath.
問題:新建工程busr,採用pandora boot,引入了需要的包,簡單寫了點程式碼釋出,
spring-boot啟動報錯:
Caused by: java.lang.IllegalArgumentException: LoggerFactory is not a Logback LoggerContext but Logback is on the classpath.
Either remove Logback or the competing implementation (class org.apache.logging.slf4j.Log4jLoggerFactory loaded from
jar:file:/opt/*
to prefer-application-packages in WEB-INF/weblogic.xml Object of class [org.apache.logging.slf4j.Log4jLoggerFactory]
must be an instance of class ch.qos.logback.classic.LoggerContext
at org.springframework.util.Assert.isInstanceOf(Assert.java:346)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.getLoggerContext(LogbackLoggingSystem.java:231)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.beforeInitialize(LogbackLoggingSystem.java:97)
at org.springframework.boot.logging.LoggingApplicationListener.onApplicationStartedEvent(LoggingApplicationListener.java:226)
at org.springframework.boot.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:205)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:166)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:138)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:121)
at org.springframework.boot.context.event.EventPublishingRunListener.started(EventPublishingRunListener.java:63)
at org.springframework.boot.SpringApplicationRunListeners.started(SpringApplicationRunListeners.java:48)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:304)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1186)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1175)
看到錯誤 "LoggerFactory is not a Logback LoggerContext but Logback is on the classpath.
Either remove Logback"
大概意思是 可以remove掉logback 解決問題。 當時直接Google了下 Stack Overflow上有篇文章也說
排掉logback的包即可。
釋出啟動 一切貌似正常。 正當高興之餘,突然發現不列印日誌了。很明顯與我剛才的操作有關係,看來剛才解決問題的辦法似乎不正確。靜下來分析問題的根本原因:
看看spring boot 是怎麼載入日誌的:
原始碼中 onApplicationStartedEvent方法,在系統啟動時會被呼叫,LoggingSystem獲取當然的日誌系統
private void onApplicationStartedEvent(ApplicationStartedEvent event) {
this.loggingSystem = LoggingSystem
.get(event.getSpringApplication().getClassLoader());
this.loggingSystem.beforeInitialize();
}
預設的會引入下面3個日誌系統 如果沒有任何配置的化 其預設的是LogbackLoggingSystem
static {
Map systems = new LinkedHashMap();
systems.put("ch.qos.logback.core.Appender",
"org.springframework.boot.logging.logback.LogbackLoggingSystem");
systems.put("org.apache.logging.log4j.core.impl.Log4jContextFactory",
"org.springframework.boot.logging.log4j2.Log4J2LoggingSystem");
systems.put("java.util.logging.LogManager",
"org.springframework.boot.logging.java.JavaLoggingSystem");
SYSTEMS = Collections.unmodifiableMap(systems);
}
逐步跟蹤到第一次系統報錯的地方
private LoggerContext getLoggerContext() {
ILoggerFactory factory = StaticLoggerBinder.getSingleton().getLoggerFactory();
Assert.isInstanceOf(LoggerContext.class, factory,
String.format(
"LoggerFactory is not a Logback LoggerContext but Logback is on "
- "the classpath. Either remove Logback or the competing "
- "implementation (%s loaded from %s). If you are using "
- "WebLogic you will need to add 'org.slf4j' to "
- "prefer-application-packages in WEB-INF/weblogic.xml",
factory.getClass(), getLocation(factory)));
return (LoggerContext) factory;
}
說明返回的factory不是logback的例項, StaticLoggerBinder.getSingleton().getLoggerFactory() 沒有找到logback,
所以這個時候開始懷疑StaticLoggerBinder 是否是因為包衝突,果然 如下圖
http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/a9fbe3063e81267c31ec925c4b5e8c35.png
預設用了slf4j-log4j12 裡面的StaticLoggerBinder 類,而沒有用logback的 所以才會報上面的啟動錯誤。
來至
com.alibaba.trip.tripspider:tripspider-httpclient:jar:1.0.0-SNAPSHOT:compile
排掉即可
org.slf4j
slf4j-log4j12
啟動一切正常,久違的日誌又有了。
思考:遇到問題 google一下找解決辦法或許是最快的,但是有時候往往解決方案因人而異,可能並不完全正確,明白問題出現的根本原因找解決辦法才是最靠譜的。