springboot多環境日志配置,啟動時logback-test.xml文件沖突導致啟動失敗:openFile(null,true) call failed. java.io.FileNotFoundException


  如題,在項目中用到了4個環境的日志配置文件,啟動時在application.properties中指定環境,讓springboot自動加載logback對應的配置文件:

 

 

  每個環境的日志目錄都不一樣,比如sit和test環境分別是:

 

 

 

 

  如果spring.profiles.active配置的是test,那么一切正常,非test環境,則啟動失敗。比如我現在配置spring.profiles.active=sit來啟動聯調環境,報錯日志如下:

2020-01-10 14:32:33.579 |-ERROR [main] org.springframework.boot.SpringApplication [822] -| Application run failed
java.lang.IllegalStateException: Logback configuration error detected: 
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[ERROR] - Failed to create parent directories for [/home/wlf/logs/prize/error-20200110.log]
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[ERROR] - openFile(null,true) call failed. java.io.FileNotFoundException: /home/wlf/logs/prize/error-20200110.log (No such file or directory)
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[CDR] - Failed to create parent directories for [/home/wlf/REPORT/send/prize20020000601809988202001101432.txt]
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[CDR] - openFile(null,true) call failed. java.io.FileNotFoundException: /home/wlf/REPORT/send/prize20020000601809988202001101432.txt (No such file or directory)         at org.springframework.boot.logging.logback.LogbackLoggingSystem.loadConfiguration(LogbackLoggingSystem.java:167)
        at org.springframework.boot.logging.logback.LogbackLoggingSystem.reinitialize(LogbackLoggingSystem.java:220)
        at org.springframework.boot.logging.AbstractLoggingSystem.initializeWithConventions(AbstractLoggingSystem.java:73)
        at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:60)
        at org.springframework.boot.logging.logback.LogbackLoggingSystem.initialize(LogbackLoggingSystem.java:118)
        at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:289)
        at org.springframework.boot.context.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:264)
        at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:226)
        at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:203)
        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:127)
        at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:76)
        at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:53)
        at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:341)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:305)
        at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:140)
        at org.springframework.cloud.bootstrap.BootstrapApplicationListener.bootstrapServiceContext(BootstrapApplicationListener.java:191)
        at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:105)
        at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:71)
        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:127)
        at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:76)
        at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:53)
        at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:341)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:305)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1214)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1203)
        at com.wlf.order.prize.PrizeApplication.main(PrizeApplication.java:12)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:51)
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:52)
Exception in thread "main" java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:51)
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:52)
Caused by: java.lang.IllegalStateException: Logback configuration error detected: 
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[ERROR] - Failed to create parent directories for [/home/wlf/logs/prize/error-20200110.log]
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[ERROR] - openFile(null,true) call failed. java.io.FileNotFoundException: /home/wlf/logs/prize/error-20200110.log (No such file or directory)
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[CDR] - Failed to create parent directories for [/home/wlf/REPORT/send/prize20020000601809988202001101432.txt]
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[CDR] - openFile(null,true) call failed. java.io.FileNotFoundException: /home/wlf/REPORT/send/prize20020000601809988202001101432.txt (No such file or directory)
        at org.springframework.boot.logging.logback.LogbackLoggingSystem.loadConfiguration(LogbackLoggingSystem.java:167)
        at org.springframework.boot.logging.logback.LogbackLoggingSystem.reinitialize(LogbackLoggingSystem.java:220)
        at org.springframework.boot.logging.AbstractLoggingSystem.initializeWithConventions(AbstractLoggingSystem.java:73)
        at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:60)
        at org.springframework.boot.logging.logback.LogbackLoggingSystem.initialize(LogbackLoggingSystem.java:118)
        at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:289)
        at org.springframework.boot.context.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:264)
        at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:226)
        at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:203)
        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:127)
        at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:76)
        at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:53)
        at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:341)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:305)
        at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:140)
        at org.springframework.cloud.bootstrap.BootstrapApplicationListener.bootstrapServiceContext(BootstrapApplicationListener.java:191)
        at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:105)
        at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:71)
        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:127)
        at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:76)
        at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:53)
        at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:341)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:305)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1214)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1203)
        at com.wlf.order.prize.PrizeApplication.main(PrizeApplication.java:12)
        ... 8 more

 

  我們從日志中看到,我啟動的是sit,可spring boot竟然跑去讀取logback-test.xml里面的信息了,我的sit環境在prize用戶下,當然找不到test環境下wlf用戶下的文件了。

  詭異的是為何spring boot會去讀取logback-test.xml而不是logback-sit.xml呢?原因其實就在源碼里。在LogbackLoggingSystem的118行initialize初始化方法中,spring boot開始加載logback:

 

 

  繼續點進去,來到抽象父類的世界:

 

 

  繼續在抽象父類里暢游,我們發現spring boot先去找自身特定的logback配置文件,找到了就執行reinitialize方法(見上面日志標黃處):

 

 

  既然日志打印了,說明代碼已經取到了config對象。我們關心的是spring boot取到的是哪些指定的logback配置?怎么取的?其實一切盡在getSelfInitializationConfig方法中:

 

 

 

  上面已經回答剛才那兩個問題:

   1、logback配置文件怎么取的——很明顯,它拿指定的logback文件去classpath中(比如我們的src/resources)查找匹配,如果匹配上了就加載。

  2、核心問題來了:取哪些指定的logback配置文件——我們需要先結束抽象父類的游覽旅程了,回到LogbackLoggingSystem去:

 

   一目了然,我們的4個日志配置文件里,剛好有一個logback-test.xml跟logback默認的配置重復了,而且能被匹配出來,spring boot當然優先讀取默認的logback-test.xml,管你的環境變量是prod還是sit還是dev。

  既然知道了問題所在,解決方案也自然就出來了:別給測試環境的日志配置起名叫logback-test了,隨便改個名吧。記得改名后重先跑maven要先clean一把,否則原來logback-test.xml還會在你的jar包里,問題依然存在。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM