背景
项目之前是通过命令行参数-Dlogging.config指定日志配置文件的路径的,后面应用docker化时,需要将这个配置文件打到应用包中,因此翻了下spring boot源码,看都支持哪些路径。
spring boot初始化入口
如之前文章的分析,spring boot是通过LoggingApplicationListener监听到ApplicationEnvironmentPreparedEvent后开始初始化日志系统的。从源码可以看到,spring boot有三种方式去获取日志配置,优先级如下:
- 由配置项logging.config指定
- 约定的默认路径(“classpath:xx.xml”)
- 默认配置(由spring boot编码实现)
由配置项logging.config指定
日志初始化的入口函数为org.springframework.boot.context.logging.LoggingApplicationListener#initializeSystem
public static final String CONFIG_PROPERTY = "logging.config";
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 {
system.initialize(initializationContext, logConfig, logFile);
}
catch (Exception ex) {
......
}
}
org.springframework.boot.logging.AbstractLoggingSystem#initialize
@Override
public void initialize(LoggingInitializationContext initializationContext, String configLocation, LogFile logFile) {
# 可以看到优先使用logging.config配置项指定的配置路径
if (StringUtils.hasLength(configLocation)) {
initializeWithSpecificConfig(initializationContext, configLocation, logFile);
return;
}
initializeWithConventions(initializationContext, logFile);
}
约定的默认路径
org.springframework.boot.logging.AbstractLoggingSystem#initializeWithConventions
private void initializeWithConventions(LoggingInitializationContext initializationContext, LogFile logFile) {
# 优先获取自定义的日志配置文件
String config = getSelfInitializationConfig();
if (config != null && logFile == null) {
reinitialize(initializationContext);
return;
}
# 没有自定义的这使用spring自己的日志配置文件
if (config == null) {
config = getSpringInitializationConfig();
}
if (config != null) {
loadConfiguration(initializationContext, config, logFile);
return;
}
# 上述两者都不存在的情况下,则使用编码的方式,配置日志的默认配置
loadDefaults(initializationContext, logFile);
}
不管是自定义的默认路径的日志配置文件还是spring自己的,都是在类路径上搜索(“classpath:xx.xml”),唯一的区别只是,两者的名字不一样而已。 自定义的会搜索"logback-test.groovy", “logback-test.xml”, “logback.groovy”, “logback.xml”; spring自带的则会搜索"logback-test-spring.groovy", “logback-test-spring.xml”, “logback-spring.groovy”, “logback-spring.xml”;
protected String getSelfInitializationConfig() {
return findConfig(getStandardConfigLocations());
}
protected String[] getStandardConfigLocations() {
return new String[] { "logback-test.groovy", "logback-test.xml", "logback.groovy", "logback.xml" };
}
protected String getSpringInitializationConfig() {
return findConfig(getSpringConfigLocations());
}
protected String[] getSpringConfigLocations() {
String[] locations = getStandardConfigLocations();
# spring自己的配置文件就是在默认的自定义文件名上加“-spring”后缀
for (int i = 0; i < locations.length; i++) {
String extension = StringUtils.getFilenameExtension(locations[i]);
locations[i] = locations[i].substring(0, locations[i].length() - extension.length() - 1) + "-spring."
+ extension;
}
return locations;
}
private String findConfig(String[] locations) {
for (String location : locations) {
ClassPathResource resource = new ClassPathResource(location, this.classLoader);
if (resource.exists()) {
return "classpath:" + location;
}
}
return null;
}
默认配置(由spring boot编码实现)
org.springframework.boot.logging.logback.LogbackLoggingSystem#loadDefaults
protected void loadDefaults(LoggingInitializationContext initializationContext, LogFile logFile) {
LoggerContext context = getLoggerContext();
stopAndReset(context);
boolean debug = Boolean.getBoolean("logback.debug");
if (debug) {
StatusListenerConfigHelper.addOnConsoleListenerInstance(context, new OnConsoleStatusListener());
}
LogbackConfigurator configurator = debug ? new DebugLogbackConfigurator(context)
: new LogbackConfigurator(context);
Environment environment = initializationContext.getEnvironment();
context.putProperty(LoggingSystemProperties.LOG_LEVEL_PATTERN,
environment.resolvePlaceholders("${logging.pattern.level:${LOG_LEVEL_PATTERN:%5p}}"));
context.putProperty(LoggingSystemProperties.LOG_DATEFORMAT_PATTERN, environment.resolvePlaceholders(
"${logging.pattern.dateformat:${LOG_DATEFORMAT_PATTERN:yyyy-MM-dd HH:mm:ss.SSS}}"));
context.putProperty(LoggingSystemProperties.ROLLING_FILE_NAME_PATTERN, environment
.resolvePlaceholders("${logging.pattern.rolling-file-name:${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz}"));
new DefaultLogbackConfiguration(initializationContext, logFile).apply(configurator);
context.setPackagingDataEnabled(true);
}
|