Avoid changing root logger level when setting level of unconfigured logger

Previously getLoggerConfig(loggerName) was used to retrieve the
LoggerConfig object on which the level was to be set. As described in the
method’s javadoc it will “remove tokens from the package name as
necessary or return the root LoggerConfig if no other matches were found”.
This is problematic as, if there’s no configuration for the logger whose
level is being configured, the level will be applied to a logger from an
outer package or to the root logger.

This commit updates Log4J2LoggingSystem to use the configuration’s map of
LoggerConfigs, rather than calling getLoggerConfig. In the event of the
level being set on an unconfigured logger, this will produce a null
LoggerConfig. When a null LoggerConfig is encountered, a new one is
created with the appropriate level. If the config already exists, its
level is set as it was before.

The code that was accessing the root logger using a magic null value
(which was then coerced into the root logger’s name (an empty string))
has also been updated to make it clearer that they are purposefully
dealing with the root logger.

Closes gh-3550
pull/3630/head
Andy Wilkinson 9 years ago
parent 9b6538d5bd
commit a43cd18ac9

@ -121,12 +121,12 @@ public class Log4J2LoggingSystem extends Slf4JLoggingSystem {
@Override @Override
public void beforeInitialize() { public void beforeInitialize() {
super.beforeInitialize(); super.beforeInitialize();
getLoggerConfig(null).addFilter(FILTER); getRootLoggerConfig().addFilter(FILTER);
} }
@Override @Override
public void initialize(String configLocation, LogFile logFile) { public void initialize(String configLocation, LogFile logFile) {
getLoggerConfig(null).removeFilter(FILTER); getRootLoggerConfig().removeFilter(FILTER);
super.initialize(configLocation, logFile); super.initialize(configLocation, logFile);
} }
@ -164,15 +164,25 @@ public class Log4J2LoggingSystem extends Slf4JLoggingSystem {
} }
@Override @Override
public void setLogLevel(String loggerName, LogLevel level) { public void setLogLevel(String loggerName, LogLevel logLevel) {
getLoggerConfig(loggerName).setLevel(LEVELS.get(level)); Level level = LEVELS.get(logLevel);
LoggerConfig loggerConfig = getLoggerConfig(loggerName);
if (loggerConfig == null) {
loggerConfig = new LoggerConfig(loggerName, level, true);
getLoggerContext().getConfiguration().addLogger(loggerName, loggerConfig);
}
else {
loggerConfig.setLevel(level);
}
getLoggerContext().updateLoggers(); getLoggerContext().updateLoggers();
} }
private LoggerConfig getRootLoggerConfig() {
return getLoggerContext().getConfiguration().getLoggerConfig("");
}
private LoggerConfig getLoggerConfig(String loggerName) { private LoggerConfig getLoggerConfig(String loggerName) {
LoggerConfig loggerConfig = getLoggerContext().getConfiguration() return getLoggerContext().getConfiguration().getLoggers().get(loggerName);
.getLoggerConfig(loggerName == null ? "" : loggerName);
return loggerConfig;
} }
private LoggerContext getLoggerContext() { private LoggerContext getLoggerContext() {

@ -34,9 +34,11 @@ import org.springframework.util.StringUtils;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.Matchers.arrayContaining; import static org.hamcrest.Matchers.arrayContaining;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
@ -115,6 +117,17 @@ public class Log4J2LoggingSystemTests extends AbstractLoggingSystemTests {
equalTo(1)); equalTo(1));
} }
@Test
public void setLevelOfUnconfiguredLoggerDoesNotAffectRootConfiguration()
throws Exception {
this.loggingSystem.beforeInitialize();
this.loggingSystem.initialize(null, null);
LogManager.getRootLogger().debug("Hello");
this.loggingSystem.setLogLevel("foo.bar.baz", LogLevel.DEBUG);
LogManager.getRootLogger().debug("Hello");
assertThat(this.output.toString(), not(containsString("Hello")));
}
@Test @Test
@Ignore("Fails on Bamboo") @Ignore("Fails on Bamboo")
public void loggingThatUsesJulIsCaptured() { public void loggingThatUsesJulIsCaptured() {

Loading…
Cancel
Save