springboot多环境日志配置,启动时logback-test.xml文件冲突导致启动失败:openfile(null,true)callfailed.java.io.filenotfoun

不想下火车的人      2022-05-17     430

关键词:

  如题,在项目中用到了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包里,问题依然存在。

springboot中实现logback多环境日志配置

参考:https://www.cnblogs.com/EasonJim/p/7801549.htmlhttps://docs.spring.io/spring-boot/docs/1.5.7.RELEASE/reference/htmlsingle/#boot-features-custom-log-configuration在根据文档配置后,出现了以下错误Loggingsystemfailedt 查看详情

java中多环境logback配置与elk日志发送

Java中多环境Logback配置与ELK日志发送 一、项目基于SpringBoot实现,引入SpringBoot相关库后,本文还要讲上传到ELK的Logstash,所以需要在pom.xml中加入:<!--https://mvnrepository.com/artifact/net.logstash.logback/logstash-logback-encoder-->< 查看详情

springboot的多环境配置

语法结构:application-profile.properties/ymlprofile:代表某个配置环境的标识示例:  application-dev.properties/yml  开发环境  application-test.properties/yml  测试环境  application.prod.properties/yml  生产环境Windows环境下启动  java-ja... 查看详情

springboot-多环境配置

...手动更改运行环境配置,会显得非常繁琐与低效。因此,SpringBoot提供了一套机制可以很容易地让我们进行多环境配置。假设现在我们需要往返于两个运行环境:开发环境dev和测试环境test。SpringBoot提供了一套多环境配置机制,称... 查看详情

springboot多环境部署,在启动时动态设置相应的配置文件

项目中,往往在测试环境和正式环境拥有不同的配置,例如数据库连接,第三方库的appkey等。这时候,我们就要在不同的环境启用不同的配置下面新建三个文件,分别表示开发环境,生产环境和测试环境的配置文件在 applicati... 查看详情

吊炸天,springboot的多环境配置一下搞明白了!

1、使用springboot的profile命名规则profile用于多环境的激活和配置,用来切换生产,测试,本地等多套不通环境的配置。如果每次去更改配置就非常麻烦,profile就是用来切换多环境配置的。在SpringBoot框架中,使... 查看详情

吊炸天,springboot的多环境配置一下搞明白了!

1、使用springboot的profile命名规则profile用于多环境的激活和配置,用来切换生产,测试,本地等多套不通环境的配置。如果每次去更改配置就非常麻烦,profile就是用来切换多环境配置的。在SpringBoot框架中,使... 查看详情

springboot(代码片段)

文章目录学习目标一、SpringBoot简介1.入门案例问题导入1.1入门案例开发步骤1.2基于SpringBoot官网创建项目1.3SpringBoot项目快速启动2.SpringBoot概述问题导入2.1起步依赖2.2辅助功能二、基础配置1.配置文件格式问题导入1.0初始环境1.1修... 查看详情

springboot2:运维实用篇(黑马程序员p54~p66)

...件书写格式6、多环境开发(properties版)7、Maven与SpringBoot多环境配置8、日志9、日志痛点解决10、日志输出格式控制11、文件记录日志 查看详情

springboot2:运维实用篇(黑马程序员p54~p66)

...件书写格式6、多环境开发(properties版)7、Maven与SpringBoot多环境配置8、日志9、日志痛点解决10、日志输出格式控制11、文件记录日志 查看详情

吊炸天,springboot的多环境配置一下搞明白了!

1、使用springboot的profile命名规则profile用于多环境的激活和配置,用来切换生产,测试,本地等多套不通环境的配置。如果每次去更改配置就非常麻烦,profile就是用来切换多环境配置的。在SpringBoot框架中,使... 查看详情

idea配置多环境启动,dev、test、prod

...术A应用场景:实际开发过程中,通常包含研发测试正式环境,为了对各环境在实际使用中隔离,maven配置支持对各环境区分启动使用例子一、pom添加以下内容在pom文件<project>标签下添加如下内容application-dev.yml增加如下配置,a... 查看详情

springboot2:运维实用篇(黑马程序员p54~p66)

...件书写格式6、多环境开发(properties版)7、Maven与SpringBoot多环境配置8、日志9、日志痛点解决10、日志输出格式 查看详情

springboot配置多环境log4j2

1.分别创建dev,test,product环境的log4j2配置文件2.application.properties文件中设置日志文件引用logging.config=classpath:log4j2_dev.xml3.注意采用多配置文件的时候,默认的配置文件log4j2.xml不能存在,否则两个配置文件都会生效,建议改名或者删... 查看详情

springboot日志配置文件不生效

SpringBoot日志配置文件不生效是因为配置文件重复!!!SpringBoot项目中默认有一份日志配置文件,项目启动时先读取到了默认日志配置文件,没有读取resource目录中的配置文件,需要自定义日志信息的话需要在Springboot配置文件中... 查看详情

node-线上环境的配置

线上环境考虑PM2进程守护,系统崩溃自动重启启动多进程,充分利用CPU和内存自带日志功能安装:常用命令:启动重启删除查看日志进程守护PM2配置日志位置打印新建pm2.config.json多进程多进程共享redis来解决无法... 查看详情

springboot2启动时加载properties文件

...环境来讲,项目发布需要打成镜像,再进行部署。如果把springboot项目连同配置文件(变量)一起打入JAR包并不是一个很好的选择,我们的做法是JAR不包含配置文件,待启动镜像和JAR时将配置文件动态赋值给JAR包。对于Spring 查看详情

idea修改springboot启动时的环境

问题起因:开发中不想修改主配置文件application.yml中的active属性,每次提交代码还得把它由dev改成prod,提交代码时需要刻意不提交它,能不能不修改它呢?当然是可以的,修改启动参数即可 问题处理:https://www.cnblogs.com/WPF0414/p/11531944.... 查看详情