zoukankan      html  css  js  c++  java
  • 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包里,问题依然存在。

  • 相关阅读:
    python保护变量(_),私有变量(__),私有方法,
    避免在循环体中创建对象
    HashMap的初始容量(initialCapacity)和装载因子(loadFactor)
    深入理解Java的接口和抽象类
    关于◎SuppressWarnings("unchecked")
    缓存技术PK:选择Memcached还是Redis?
    Maven详解之聚合与继承
    浅谈redis和memcached的区别
    《玩转Spring》第二章 BeanPostProcessor扩展
    使用Spring实现读写分离( MySQL实现主从复制)
  • 原文地址:https://www.cnblogs.com/wuxun1997/p/12187098.html
Copyright © 2011-2022 走看看