diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/how-to/pages/logging.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/how-to/pages/logging.adoc index ab3ac41942..980b34b913 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/how-to/pages/logging.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/how-to/pages/logging.adoc @@ -202,4 +202,8 @@ Log4j 2 has support for combining multiple configuration files into a single com To use this support in Spring Boot, configure configprop:logging.log4j2.config.override[] with the locations of one or more secondary configuration files. The secondary configuration files will be merged with the primary configuration, whether the primary's source is Spring Boot's defaults, a standard location such as `log4j.xml`, or the location configured by the configprop:logging.config[] property. -NOTE: Log4j2 override configuration file locations can be prefixed with `optional:`, for example, `optional:classpath:log4j2-override.xml`, to indicate that the location is optional and should only be loaded if the resource exists. +[NOTE] +==== +Log4j2 override configuration file locations can be prefixed with `optional:`. +For example, `optional:classpath:log4j2-override.xml` indicates that `log4j2-override.xml` should only be loaded if the resource exists. +==== diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystem.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystem.java index fbd33e7962..aad205422c 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystem.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystem.java @@ -274,41 +274,21 @@ public class Log4J2LoggingSystem extends AbstractLoggingSystem { List configurations = new ArrayList<>(); LoggerContext context = getLoggerContext(); ResourceLoader resourceLoader = ApplicationResourceLoader.get(); - configurations.add(loadConfiguration(resourceLoader, location, context)); + configurations.add(load(resourceLoader.getResource(location), context)); for (String override : overrides) { - Configuration overrideConfiguration = loadOptionalConfiguration(resourceLoader, override, context); + Configuration overrideConfiguration = loadOverride(resourceLoader, override, context); if (overrideConfiguration != null) { configurations.add(overrideConfiguration); } } - context.start(createCompositeConfigurationIfNecessary(configurations)); + context.start(mergeConfigurations(configurations)); } catch (Exception ex) { throw new IllegalStateException("Could not initialize Log4J2 logging from " + location, ex); } } - private Configuration loadOptionalConfiguration(ResourceLoader resourceLoader, String location, - LoggerContext context) throws IOException { - if (location.startsWith(OPTIONAL_PREFIX)) { - Resource resource = resourceLoader.getResource(location.substring(OPTIONAL_PREFIX.length())); - try { - return (resource.exists()) ? loadConfiguration(resource, context) : null; - } - catch (FileNotFoundException ex) { - return null; - } - } - return loadConfiguration(resourceLoader, location, context); - } - - private Configuration loadConfiguration(ResourceLoader resourceLoader, String location, LoggerContext context) - throws IOException { - Resource resource = resourceLoader.getResource(location); - return loadConfiguration(resource, context); - } - - private Configuration loadConfiguration(Resource resource, LoggerContext context) throws IOException { + private Configuration load(Resource resource, LoggerContext context) throws IOException { ConfigurationFactory factory = ConfigurationFactory.getInstance(); if (resource.isFile()) { try (InputStream inputStream = resource.getInputStream()) { @@ -328,7 +308,21 @@ public class Log4J2LoggingSystem extends AbstractLoggingSystem { } } - private Configuration createCompositeConfigurationIfNecessary(List configurations) { + private Configuration loadOverride(ResourceLoader resourceLoader, String location, LoggerContext context) + throws IOException { + if (location.startsWith(OPTIONAL_PREFIX)) { + Resource resource = resourceLoader.getResource(location.substring(OPTIONAL_PREFIX.length())); + try { + return (resource.exists()) ? load(resource, context) : null; + } + catch (FileNotFoundException ex) { + return null; + } + } + return load(resourceLoader.getResource(location), context); + } + + private Configuration mergeConfigurations(List configurations) { if (configurations.size() == 1) { return configurations.iterator().next(); } @@ -354,7 +348,7 @@ public class Log4J2LoggingSystem extends AbstractLoggingSystem { ResourceLoader resourceLoader = ApplicationResourceLoader.get(); for (String override : overrides) { try { - Configuration overrideConfiguration = loadOptionalConfiguration(resourceLoader, override, context); + Configuration overrideConfiguration = loadOverride(resourceLoader, override, context); if (overrideConfiguration != null) { configurations.add(overrideConfiguration); } @@ -363,7 +357,7 @@ public class Log4J2LoggingSystem extends AbstractLoggingSystem { throw new RuntimeException("Failed to load overriding configuration from '" + override + "'", ex); } } - context.reconfigure(createCompositeConfigurationIfNecessary(configurations)); + context.reconfigure(mergeConfigurations(configurations)); } @Override diff --git a/spring-boot-project/spring-boot/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 9066d1a154..ca6e639151 100644 --- a/spring-boot-project/spring-boot/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-project/spring-boot/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -126,7 +126,7 @@ { "name": "logging.log4j2.config.override", "type": "java.util.List", - "description": "Overriding configuration files used to create a composite configuration." + "description": "Overriding configuration files used to create a composite configuration. Can be prefixed with 'optional:' to only load the override if it exists." }, { "name": "logging.logback.rollingpolicy.clean-history-on-start",