Skip to content

Commit e4d2593

Browse files
committed
Allow skipping unavailable override configurations in Log4j2
Introduced support for the 'optional:' prefix in Log4j2 override file locations, ensuring missing files are ignored without throwing exceptions. See spring-projectsgh-44399 Signed-off-by: Dmytro Nosan <[email protected]>
1 parent f45a3d7 commit e4d2593

File tree

2 files changed

+48
-5
lines changed

2 files changed

+48
-5
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystem.java

+30-5
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
import org.springframework.core.annotation.Order;
6969
import org.springframework.core.env.Environment;
7070
import org.springframework.core.io.Resource;
71+
import org.springframework.core.io.ResourceLoader;
7172
import org.springframework.util.Assert;
7273
import org.springframework.util.ClassUtils;
7374
import org.springframework.util.CollectionUtils;
@@ -85,6 +86,8 @@
8586
*/
8687
public class Log4J2LoggingSystem extends AbstractLoggingSystem {
8788

89+
private static final String OPTIONAL_PREFIX = "optional:";
90+
8891
private static final String LOG4J_BRIDGE_HANDLER = "org.apache.logging.log4j.jul.Log4jBridgeHandler";
8992

9093
private static final String LOG4J_LOG_MANAGER = "org.apache.logging.log4j.jul.LogManager";
@@ -269,9 +272,13 @@ protected void loadConfiguration(String location, LogFile logFile, List<String>
269272
try {
270273
List<Configuration> configurations = new ArrayList<>();
271274
LoggerContext context = getLoggerContext();
272-
configurations.add(load(location, context));
275+
ResourceLoader resourceLoader = ApplicationResourceLoader.get();
276+
configurations.add(load(resourceLoader, location, context));
273277
for (String override : overrides) {
274-
configurations.add(load(override, context));
278+
Configuration overrideConfiguration = loadOptional(resourceLoader, override, context);
279+
if (overrideConfiguration != null) {
280+
configurations.add(overrideConfiguration);
281+
}
275282
}
276283
Configuration configuration = (configurations.size() > 1) ? createComposite(configurations)
277284
: configurations.iterator().next();
@@ -282,8 +289,22 @@ protected void loadConfiguration(String location, LogFile logFile, List<String>
282289
}
283290
}
284291

285-
private Configuration load(String location, LoggerContext context) throws IOException {
286-
Resource resource = ApplicationResourceLoader.get().getResource(location);
292+
private Configuration load(ResourceLoader resourceLoader, String location, LoggerContext context)
293+
throws IOException {
294+
Resource resource = resourceLoader.getResource(location);
295+
return load(resource, context);
296+
}
297+
298+
private Configuration loadOptional(ResourceLoader resourceLoader, String location, LoggerContext context)
299+
throws IOException {
300+
if (location.startsWith(OPTIONAL_PREFIX)) {
301+
Resource resource = resourceLoader.getResource(location.substring(OPTIONAL_PREFIX.length()));
302+
return (resource.exists()) ? load(resource, context) : null;
303+
}
304+
return load(resourceLoader, location, context);
305+
}
306+
307+
private Configuration load(Resource resource, LoggerContext context) throws IOException {
287308
ConfigurationSource source = getConfigurationSource(resource);
288309
return ConfigurationFactory.getInstance().getConfiguration(context, source);
289310
}
@@ -323,9 +344,13 @@ private void reinitializeWithOverrides(List<String> overrides) {
323344
Configuration base = context.getConfiguration();
324345
List<AbstractConfiguration> configurations = new ArrayList<>();
325346
configurations.add((AbstractConfiguration) base);
347+
ResourceLoader resourceLoader = ApplicationResourceLoader.get();
326348
for (String override : overrides) {
327349
try {
328-
configurations.add((AbstractConfiguration) load(override, context));
350+
Configuration overrideConfiguration = loadOptional(resourceLoader, override, context);
351+
if (overrideConfiguration != null) {
352+
configurations.add((AbstractConfiguration) overrideConfiguration);
353+
}
329354
}
330355
catch (IOException ex) {
331356
throw new RuntimeException("Failed to load overriding configuration from '" + override + "'", ex);

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystemTests.java

+18
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import org.apache.logging.log4j.core.config.Reconfigurable;
4444
import org.apache.logging.log4j.core.config.composite.CompositeConfiguration;
4545
import org.apache.logging.log4j.core.config.plugins.util.PluginRegistry;
46+
import org.apache.logging.log4j.core.config.xml.XmlConfiguration;
4647
import org.apache.logging.log4j.core.util.ShutdownCallbackRegistry;
4748
import org.apache.logging.log4j.jul.Log4jBridgeHandler;
4849
import org.apache.logging.log4j.status.StatusListener;
@@ -453,6 +454,23 @@ void shutdownHookIsDisabled() {
453454
.isFalse();
454455
}
455456

457+
@Test
458+
@WithNonDefaultXmlResource
459+
void loadConfigurationOptionalOverrideConfigurationWhenDoesNotExist() {
460+
this.environment.setProperty("logging.log4j2.config.override", "optional:classpath:override.xml");
461+
this.loggingSystem.initialize(this.initializationContext, "classpath:nondefault.xml", null);
462+
assertThat(this.loggingSystem.getConfiguration()).isInstanceOf(XmlConfiguration.class);
463+
}
464+
465+
@Test
466+
@WithNonDefaultXmlResource
467+
@WithOverrideXmlResource
468+
void loadConfigurationOptionalOverrideConfigurationWhenExists() {
469+
this.environment.setProperty("logging.log4j2.config.override", "optional:classpath:override.xml");
470+
this.loggingSystem.initialize(this.initializationContext, "classpath:nondefault.xml", null);
471+
assertThat(this.loggingSystem.getConfiguration()).isInstanceOf(CompositeConfiguration.class);
472+
}
473+
456474
@Test
457475
@WithNonDefaultXmlResource
458476
@WithOverrideXmlResource

0 commit comments

Comments
 (0)