Register Log42J StatusListener
Update Log42JLoggingSystem to register Boot's StatusListener instead of resetting the fallbackListener during initialization. This fixes an issue when resetting the fallback listener leads to closing standard streams. See gh-44380 Signed-off-by: Dmytro Nosan <dimanosan@gmail.com>
This commit is contained in:
committed by
Andy Wilkinson
parent
575655ca39
commit
22958097e3
@@ -47,6 +47,7 @@ import org.apache.logging.log4j.core.net.ssl.SslConfigurationFactory;
|
||||
import org.apache.logging.log4j.core.util.AuthorizationProvider;
|
||||
import org.apache.logging.log4j.core.util.NameUtil;
|
||||
import org.apache.logging.log4j.jul.Log4jBridgeHandler;
|
||||
import org.apache.logging.log4j.status.StatusConsoleListener;
|
||||
import org.apache.logging.log4j.status.StatusLogger;
|
||||
import org.apache.logging.log4j.util.PropertiesUtil;
|
||||
|
||||
@@ -93,6 +94,9 @@ public class Log4J2LoggingSystem extends AbstractLoggingSystem {
|
||||
static final String ENVIRONMENT_KEY = Conventions.getQualifiedAttributeName(Log4J2LoggingSystem.class,
|
||||
"environment");
|
||||
|
||||
static final String STATUS_LISTENER_KEY = Conventions.getQualifiedAttributeName(Log4J2LoggingSystem.class,
|
||||
"statusListener");
|
||||
|
||||
private static final LogLevels<Level> LEVELS = new LogLevels<>();
|
||||
|
||||
static {
|
||||
@@ -214,10 +218,12 @@ public class Log4J2LoggingSystem extends AbstractLoggingSystem {
|
||||
if (isAlreadyInitialized(loggerContext)) {
|
||||
return;
|
||||
}
|
||||
resetFallbackListenerStream(StatusLogger.getLogger());
|
||||
StatusConsoleListener listener = new StatusConsoleListener(Level.WARN);
|
||||
StatusLogger.getLogger().registerListener(listener);
|
||||
loggerContext.putObject(STATUS_LISTENER_KEY, listener);
|
||||
Environment environment = initializationContext.getEnvironment();
|
||||
if (environment != null) {
|
||||
getLoggerContext().putObject(ENVIRONMENT_KEY, environment);
|
||||
loggerContext.putObject(ENVIRONMENT_KEY, environment);
|
||||
Log4J2LoggingSystem.propertySource.setEnvironment(environment);
|
||||
PropertiesUtil.getProperties().addPropertySource(Log4J2LoggingSystem.propertySource);
|
||||
}
|
||||
@@ -226,21 +232,6 @@ public class Log4J2LoggingSystem extends AbstractLoggingSystem {
|
||||
markAsInitialized(loggerContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the stream used by the fallback listener to the current system out. This
|
||||
* allows the fallback listener to work with any captured output streams in a similar
|
||||
* way to the {@code follow} attribute of the {@code Console} appender.
|
||||
* @param statusLogger the status logger to update
|
||||
*/
|
||||
private void resetFallbackListenerStream(StatusLogger statusLogger) {
|
||||
try {
|
||||
statusLogger.getFallbackListener().setStream(System.out);
|
||||
}
|
||||
catch (NoSuchMethodError ex) {
|
||||
// Ignore for older versions of Log4J
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadDefaults(LoggingInitializationContext initializationContext, LogFile logFile) {
|
||||
String location = getPackagedConfigFile((logFile != null) ? "log4j2-file.xml" : "log4j2.xml");
|
||||
@@ -454,9 +445,14 @@ public class Log4J2LoggingSystem extends AbstractLoggingSystem {
|
||||
super.cleanUp();
|
||||
LoggerContext loggerContext = getLoggerContext();
|
||||
markAsUninitialized(loggerContext);
|
||||
StatusConsoleListener listener = (StatusConsoleListener) getLoggerContext().getObject(STATUS_LISTENER_KEY);
|
||||
if (listener != null) {
|
||||
StatusLogger.getLogger().removeListener(listener);
|
||||
loggerContext.removeObject(STATUS_LISTENER_KEY);
|
||||
}
|
||||
loggerContext.getConfiguration().removeFilter(FILTER);
|
||||
Log4J2LoggingSystem.propertySource.setEnvironment(null);
|
||||
getLoggerContext().removeObject(ENVIRONMENT_KEY);
|
||||
loggerContext.removeObject(ENVIRONMENT_KEY);
|
||||
}
|
||||
|
||||
private LoggerConfig getLogger(String name) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -41,6 +41,8 @@ import org.apache.logging.log4j.core.config.composite.CompositeConfiguration;
|
||||
import org.apache.logging.log4j.core.config.plugins.util.PluginRegistry;
|
||||
import org.apache.logging.log4j.core.util.ShutdownCallbackRegistry;
|
||||
import org.apache.logging.log4j.jul.Log4jBridgeHandler;
|
||||
import org.apache.logging.log4j.status.StatusListener;
|
||||
import org.apache.logging.log4j.status.StatusLogger;
|
||||
import org.apache.logging.log4j.util.PropertiesUtil;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -469,6 +471,42 @@ class Log4J2LoggingSystemTests extends AbstractLoggingSystemTests {
|
||||
assertThat(environment).isSameAs(this.environment);
|
||||
}
|
||||
|
||||
@Test
|
||||
void initializeRegisterStatusListenerAndAttachToLoggerContext() {
|
||||
this.loggingSystem.beforeInitialize();
|
||||
this.loggingSystem.initialize(this.initializationContext, null, null);
|
||||
LoggerContext loggerContext = (LoggerContext) LogManager.getContext(false);
|
||||
StatusListener statusListener = (StatusListener) loggerContext
|
||||
.getObject(Log4J2LoggingSystem.STATUS_LISTENER_KEY);
|
||||
assertThat(statusListener).isNotNull();
|
||||
assertThat(StatusLogger.getLogger().getListeners()).contains(statusListener);
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusListenerIsUpdatedUponReinitialization() {
|
||||
this.loggingSystem.beforeInitialize();
|
||||
this.loggingSystem.initialize(this.initializationContext, null, null);
|
||||
// listener should be registered
|
||||
LoggerContext loggerContext = (LoggerContext) LogManager.getContext(false);
|
||||
StatusListener statusListener = (StatusListener) loggerContext
|
||||
.getObject(Log4J2LoggingSystem.STATUS_LISTENER_KEY);
|
||||
assertThat(statusListener).isNotNull();
|
||||
assertThat(StatusLogger.getLogger().getListeners()).contains(statusListener);
|
||||
|
||||
this.loggingSystem.cleanUp();
|
||||
// listener should be removed from context and StatusLogger
|
||||
assertThat(StatusLogger.getLogger().getListeners()).doesNotContain(statusListener);
|
||||
assertThat(loggerContext.getObject(Log4J2LoggingSystem.STATUS_LISTENER_KEY)).isNull();
|
||||
|
||||
// a new listener should be registered
|
||||
this.loggingSystem.beforeInitialize();
|
||||
this.loggingSystem.initialize(this.initializationContext, null, null);
|
||||
StatusListener statusListener1 = (StatusListener) loggerContext
|
||||
.getObject(Log4J2LoggingSystem.STATUS_LISTENER_KEY);
|
||||
assertThat(statusListener1).isNotNull();
|
||||
assertThat(StatusLogger.getLogger().getListeners()).contains(statusListener1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void initializeAddsSpringEnvironmentPropertySource() {
|
||||
this.environment.setProperty("spring", "boot");
|
||||
|
||||
Reference in New Issue
Block a user