解决 WAR 部署方式下日志配置不生效的问题
1. 问题描述
应用使用spring boot进行开发,日志系统使用backlog,系统配置文件backlog-config.xml,通过jar包部署时日志输出正常,通过war包部署应用到tomcat时,发现输出日志与期望不符。
配置文件application.yaml
# 更改配置文件名称
logging:
config: classpath:logging-config.xml
2. 问题分析
Spring Boot初始化日志系统的逻辑是,从环境变量environment中获取logging.config属性值(即配置文件信息),然后根据配置文件更新LoggerContext。
org.springframework.boot.context.logging.LoggingApplicationListener#initializeSystem
private void initializeSystem(ConfigurableEnvironment environment,
LoggingSystem system, LogFile logFile) {
LoggingInitializationContext initializationContext = new LoggingInitializationContext(
environment);
String logConfig = environment.getProperty(CONFIG_PROPERTY);
if (ignoreLogConfig(logConfig)) {
system.initialize(initializationContext, null, logFile);
}
else {
try {
ResourceUtils.getURL(logConfig).openStream().close();
system.initialize(initializationContext, logConfig, logFile);
}
catch (Exception ex) {
// NOTE: We can't use the logger here to report the problem
System.err.println("Logging system failed to initialize "
+ "using configuration from '" + logConfig + "'");
ex.printStackTrace(System.err);
throw new IllegalStateException(ex);
}
}
}
此处的关键是logConfig的值,通过jar部署时,logConfig的值为classpath:logging-config.xml,所以日志输出正常;而通过war包方式部署时,logConfig的值为-Djava.util.logging.config.file=“C:\Users\me.IntelliJIdea2018.2\system\tomcat\Unnamed_Spring-Boot-In-Action\conf\logging.properties”,所以日志输出格式自然与预期不否咯!
那么问题来了,logging.config和java.util.logging.config.file这两个KEY差别可有点大,怎么会扯到一起了呢?原因是spring boot通过系统环境变量获取属性值时有个转换处理,经过处理后logging.config的actualName是LOGGING_CONFIG;而LOGGING_CONFIG对应的值正是-Djava.util.logging.config.file=“C:\Users\me.IntelliJIdea2018.2\system\tomcat\Unnamed_Spring-Boot-In-Action\conf\logging.properties”。
org.springframework.core.env.SystemEnvironmentPropertySource#getProperty


3. 解决方案
我们的配置logging.config就这么被中途截胡啦!我们可以通过两种方式解决该问题。
3.1 提升logging.config的优先级
之前java.util.logging.config.file之所以优先于logging.config被加载是因为其属于system environment,而logging.config属于application.yaml配置文件级别。
根据Spring boot加载配置的优先级顺序,将logging.config的配置提升到命令行参数systemProperties级别,配置可顺利加载。
关于配置加载的优先级可参考 2. 通过属性文件外置配置

-Dlogging.config=classpath:logging-config.xml
3.2 使用默认的配置文件名称
虽然logging.config的配置被截胡,但是如果属性值如果以-D开头则会被忽略掉,也就是说日志系统会查看是否存在默认名称的配置文件,如log4j2的log4j2.properties或log4j2.xml或backlog的logback.xml等。
所以只需要将配置文件的名字改成默认名称就可以啦!
org.springframework.boot.context.logging.LoggingApplicationListener#ignoreLogConfig
附录
1. Overview of property sources

本文围绕Spring Boot应用展开,使用backlog日志系统,jar包部署时日志输出正常,war包部署到tomcat时不符预期。经分析是logging.config配置被截胡,给出两种解决方案:提升logging.config优先级到命令行参数级别;使用默认的配置文件名称。
2万+

被折叠的 条评论
为什么被折叠?



