基於Springboot使用logback的註意事項

Springboot logback的註意事項

項目使用SpringBoot搭建的,開發環境沒有發現問題,日志輸出位置也正常。

項目的日志沒有使用默認配置文件名方式,而是一個環境一套配置文件,所以日志也是通過application.properties配置中間接指定的;

比如開發環境:

application.properties文件配置為:spring.profiles.active=dev

application-dev.properties文件的日志配置:logging.config=classpath:logback-dev.xml

但是在生產環境的時候發現啟動項目會輸出多個日志文件???

通過查看SpringBoot源碼org.springframework.boot.context.logging.LoggingApplicationListener日志處理模塊,在org.springframework.boot.logging.logback.LogbackLoggingSystem對象中找到加載默認配置文件的代碼:

@Override
protected String[] getStandardConfigLocations() {
 return new String[] { "logback-test.groovy", "logback-test.xml", "logback.groovy", "logback.xml" };
}

生產配置為:

application.properties文件配置為:spring.profiles.active=prod

application-prod.properties文件的日志配置:logging.config=classpath:logback-prod.xml

看似沒有問題,其實我的配置文件中還包含一套測試環境的配置文件,剛好其中的日志配置文件名是logback-test.xml與默認加載的配置文件名正好相同。

找到原因後將生產環境中的logback-test.xml刪除掉日志輸出就正常瞭。

結論:

如果項目中有多套環境是日志文件的名千萬不要和默認配置文件名相同。

最後看瞭一下log4j的加載的源碼,貼出來看看,多套環境時避免使用:

private String[] getCurrentlySupportedConfigLocations() {
 List<String> supportedConfigLocations = new ArrayList<>();
 supportedConfigLocations.add("log4j2.properties");
 if (isClassAvailable("com.fasterxml.jackson.dataformat.yaml.YAMLParser")) {
  Collections.addAll(supportedConfigLocations, "log4j2.yaml", "log4j2.yml");
 }
 if (isClassAvailable("com.fasterxml.jackson.databind.ObjectMapper")) {
  Collections.addAll(supportedConfigLocations, "log4j2.json", "log4j2.jsn");
 }
 supportedConfigLocations.add("log4j2.xml");
 return StringUtils.toStringArray(supportedConfigLocations);
}

springboot使用logback會遇到的坑

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 file:/C:/Users/fyk/.m2/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.7/log4j-slf4j-impl-2.7.jar). If you are using WebLogic you will need to add 'org.slf4j' to prefer-application-packages in WEB-INF/weblogic.xml: org.apache.logging.slf4j.Log4jLoggerFactory
 at org.springframework.util.Assert.instanceCheckFailed(Assert.java:389)
 at org.springframework.util.Assert.isInstanceOf(Assert.java:327)
 at org.springframework.boot.logging.logback.LogbackLoggingSystem.getLoggerContext(LogbackLoggingSystem.java:274)
 at org.springframework.boot.logging.logback.LogbackLoggingSystem.beforeInitialize(LogbackLoggingSystem.java:98)
 at org.springframework.boot.logging.LoggingApplicationListener.onApplicationStartingEvent(LoggingApplicationListener.java:230)
 at org.springframework.boot.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:209)
 at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
 at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
 at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
 at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:122)
 at org.springframework.boot.context.event.EventPublishingRunListener.starting(EventPublishingRunListener.java:69)
 at org.springframework.boot.SpringApplicationRunListeners.starting(SpringApplicationRunListeners.java:48)
 at org.springframework.boot.SpringApplication.run(SpringApplication.java:292)
 at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118)
 at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107)
 at com.light.SpringbootApplication.main(SpringbootApplication.java:32)
 ... 5 more

在spring boot中導入logback jar包會與spring-boot-starter-web沖突,應該是springboot中已經包含瞭這個包,

   <dependency>
   <groupId>ch.qos.logback</groupId>
   <artifactId>logback-classic</artifactId>
   <version>1.2.3</version>
  </dependency>

去掉這個導入就好瞭。

以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。

推薦閱讀: