Use consistent 'ROOT' logger name

Ensure all LoggingSystem implementation provide a consistent ROOT logger
name. Prior to this commit the `/loggers` endpoint could return '' for
root loggers which could then not be set using a POST.

Fixes gh-7372
pull/7373/merge
Phillip Webb 8 years ago
parent 01c381f2a9
commit 1d2f6d25fa

@ -16,6 +16,7 @@
package org.springframework.boot.logging;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
@ -35,6 +36,9 @@ import org.springframework.util.SystemPropertyUtils;
*/
public abstract class AbstractLoggingSystem extends LoggingSystem {
protected static final Comparator<LoggerConfiguration> CONFIGURATION_COMPARATOR = new LoggerConfigurationComparator(
ROOT_LOGGER_NAME);
private final ClassLoader classLoader;
public AbstractLoggingSystem(ClassLoader classLoader) {

@ -25,9 +25,8 @@ import org.springframework.util.Assert;
* Sorts the "root" logger as the first logger and then lexically by name after that.
*
* @author Ben Hale
* @since 1.5.0
*/
public class LoggerConfigurationComparator implements Comparator<LoggerConfiguration> {
class LoggerConfigurationComparator implements Comparator<LoggerConfiguration> {
private final String rootLoggerName;
@ -35,7 +34,7 @@ public class LoggerConfigurationComparator implements Comparator<LoggerConfigura
* Create a new {@link LoggerConfigurationComparator} instance.
* @param rootLoggerName the name of the "root" logger
*/
public LoggerConfigurationComparator(String rootLoggerName) {
LoggerConfigurationComparator(String rootLoggerName) {
Assert.notNull(rootLoggerName, "RootLoggerName must not be null");
this.rootLoggerName = rootLoggerName;
}

@ -350,7 +350,7 @@ public class LoggingApplicationListener implements GenericApplicationListener {
private void setLogLevel(LoggingSystem system, Environment environment, String name,
String level) {
try {
if (name.equalsIgnoreCase("root")) {
if (name.equalsIgnoreCase(LoggingSystem.ROOT_LOGGER_NAME)) {
name = null;
}
level = environment.resolvePlaceholders(level);

@ -47,6 +47,13 @@ public abstract class LoggingSystem {
*/
public static final String NONE = "none";
/**
* The name used to for the root logger. LoggingSystem implementations should ensure
* that this is the name used to represent the root logger, regardless of the
* underlying implementation.
*/
public static final String ROOT_LOGGER_NAME = "ROOT";
private static final Map<String, String> SYSTEMS;
static {
@ -107,7 +114,8 @@ public abstract class LoggingSystem {
/**
* Sets the logging level for a given logger.
* @param loggerName the name of the logger to set
* @param loggerName the name of the logger to set ({@code null} can be used for the
* root logger).
* @param level the log level
*/
public void setLogLevel(String loggerName, LogLevel level) {

@ -31,7 +31,6 @@ import org.springframework.boot.logging.AbstractLoggingSystem;
import org.springframework.boot.logging.LogFile;
import org.springframework.boot.logging.LogLevel;
import org.springframework.boot.logging.LoggerConfiguration;
import org.springframework.boot.logging.LoggerConfigurationComparator;
import org.springframework.boot.logging.LoggingInitializationContext;
import org.springframework.boot.logging.LoggingSystem;
import org.springframework.util.Assert;
@ -49,9 +48,6 @@ import org.springframework.util.StringUtils;
*/
public class JavaLoggingSystem extends AbstractLoggingSystem {
private static final LoggerConfigurationComparator COMPARATOR = new LoggerConfigurationComparator(
"");
private static final LogLevels<Level> LEVELS = new LogLevels<Level>();
static {
@ -122,8 +118,10 @@ public class JavaLoggingSystem extends AbstractLoggingSystem {
@Override
public void setLogLevel(String loggerName, LogLevel level) {
Assert.notNull(level, "Level must not be null");
String name = (StringUtils.hasText(loggerName) ? loggerName : "");
Logger logger = Logger.getLogger(name);
if (loggerName == null || ROOT_LOGGER_NAME.equals(loggerName)) {
loggerName = "";
}
Logger logger = Logger.getLogger(loggerName);
if (logger != null) {
logger.setLevel(LEVELS.convertSystemToNative(level));
}
@ -136,7 +134,7 @@ public class JavaLoggingSystem extends AbstractLoggingSystem {
while (names.hasMoreElements()) {
result.add(getLoggerConfiguration(names.nextElement()));
}
Collections.sort(result, COMPARATOR);
Collections.sort(result, CONFIGURATION_COMPARATOR);
return Collections.unmodifiableList(result);
}
@ -148,7 +146,9 @@ public class JavaLoggingSystem extends AbstractLoggingSystem {
}
LogLevel level = LEVELS.convertNativeToSystem(logger.getLevel());
LogLevel effectiveLevel = LEVELS.convertNativeToSystem(getEffectiveLevel(logger));
return new LoggerConfiguration(logger.getName(), level, effectiveLevel);
String name = (StringUtils.hasLength(logger.getName()) ? logger.getName()
: ROOT_LOGGER_NAME);
return new LoggerConfiguration(name, level, effectiveLevel);
}
private Level getEffectiveLevel(Logger root) {

@ -41,7 +41,6 @@ import org.apache.logging.log4j.message.Message;
import org.springframework.boot.logging.LogFile;
import org.springframework.boot.logging.LogLevel;
import org.springframework.boot.logging.LoggerConfiguration;
import org.springframework.boot.logging.LoggerConfigurationComparator;
import org.springframework.boot.logging.LoggingInitializationContext;
import org.springframework.boot.logging.LoggingSystem;
import org.springframework.boot.logging.Slf4JLoggingSystem;
@ -61,9 +60,6 @@ import org.springframework.util.StringUtils;
*/
public class Log4J2LoggingSystem extends Slf4JLoggingSystem {
private static final LoggerConfigurationComparator COMPARATOR = new LoggerConfigurationComparator(
LogManager.ROOT_LOGGER_NAME);
private static final String FILE_PROTOCOL = "file";
private static final LogLevels<Level> LEVELS = new LogLevels<Level>();
@ -224,7 +220,7 @@ public class Log4J2LoggingSystem extends Slf4JLoggingSystem {
for (LoggerConfig loggerConfig : configuration.getLoggers().values()) {
result.add(convertLoggerConfiguration(loggerConfig));
}
Collections.sort(result, COMPARATOR);
Collections.sort(result, CONFIGURATION_COMPARATOR);
return result;
}
@ -238,7 +234,11 @@ public class Log4J2LoggingSystem extends Slf4JLoggingSystem {
return null;
}
LogLevel level = LEVELS.convertNativeToSystem(loggerConfig.getLevel());
return new LoggerConfiguration(loggerConfig.getName(), level, level);
String name = loggerConfig.getName();
if (!StringUtils.hasLength(name) || LogManager.ROOT_LOGGER_NAME.equals(name)) {
name = ROOT_LOGGER_NAME;
}
return new LoggerConfiguration(name, level, level);
}
@Override
@ -254,7 +254,9 @@ public class Log4J2LoggingSystem extends Slf4JLoggingSystem {
}
private LoggerConfig getLoggerConfig(String name) {
name = (StringUtils.hasText(name) ? name : LogManager.ROOT_LOGGER_NAME);
if (!StringUtils.hasLength(name) || ROOT_LOGGER_NAME.equals(name)) {
name = LogManager.ROOT_LOGGER_NAME;
}
return getLoggerContext().getConfiguration().getLoggers().get(name);
}

@ -41,7 +41,6 @@ import org.slf4j.impl.StaticLoggerBinder;
import org.springframework.boot.logging.LogFile;
import org.springframework.boot.logging.LogLevel;
import org.springframework.boot.logging.LoggerConfiguration;
import org.springframework.boot.logging.LoggerConfigurationComparator;
import org.springframework.boot.logging.LoggingInitializationContext;
import org.springframework.boot.logging.LoggingSystem;
import org.springframework.boot.logging.Slf4JLoggingSystem;
@ -59,9 +58,6 @@ import org.springframework.util.StringUtils;
*/
public class LogbackLoggingSystem extends Slf4JLoggingSystem {
private static final LoggerConfigurationComparator COMPARATOR = new LoggerConfigurationComparator(
Logger.ROOT_LOGGER_NAME);
private static final String CONFIGURATION_FILE_PROPERTY = "logback.configurationFile";
private static final LogLevels<Level> LEVELS = new LogLevels<Level>();
@ -219,7 +215,7 @@ public class LogbackLoggingSystem extends Slf4JLoggingSystem {
for (ch.qos.logback.classic.Logger logger : getLoggerContext().getLoggerList()) {
result.add(getLoggerConfiguration(logger));
}
Collections.sort(result, COMPARATOR);
Collections.sort(result, CONFIGURATION_COMPARATOR);
return result;
}
@ -236,7 +232,11 @@ public class LogbackLoggingSystem extends Slf4JLoggingSystem {
LogLevel level = LEVELS.convertNativeToSystem(logger.getLevel());
LogLevel effectiveLevel = LEVELS
.convertNativeToSystem(logger.getEffectiveLevel());
return new LoggerConfiguration(logger.getName(), level, effectiveLevel);
String name = logger.getName();
if (!StringUtils.hasLength(name) || Logger.ROOT_LOGGER_NAME.equals(name)) {
name = ROOT_LOGGER_NAME;
}
return new LoggerConfiguration(name, level, effectiveLevel);
}
@Override
@ -259,7 +259,9 @@ public class LogbackLoggingSystem extends Slf4JLoggingSystem {
private ch.qos.logback.classic.Logger getLogger(String name) {
LoggerContext factory = getLoggerContext();
name = (StringUtils.isEmpty(name) ? Logger.ROOT_LOGGER_NAME : name);
if (StringUtils.isEmpty(name) || ROOT_LOGGER_NAME.equals(name)) {
name = Logger.ROOT_LOGGER_NAME;
}
return factory.getLogger(name);
}

@ -33,6 +33,7 @@ import org.junit.Test;
import org.springframework.boot.logging.AbstractLoggingSystemTests;
import org.springframework.boot.logging.LogLevel;
import org.springframework.boot.logging.LoggerConfiguration;
import org.springframework.boot.logging.LoggingSystem;
import org.springframework.boot.testutil.InternalOutputCapture;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
@ -175,7 +176,7 @@ public class JavaLoggingSystemTests extends AbstractLoggingSystemTests {
List<LoggerConfiguration> configurations = this.loggingSystem
.getLoggerConfigurations();
assertThat(configurations).isNotEmpty();
assertThat(configurations.get(0).getName()).isEmpty();
assertThat(configurations.get(0).getName()).isEqualTo(LoggingSystem.ROOT_LOGGER_NAME);
}
@Test

@ -40,6 +40,7 @@ import org.junit.Test;
import org.springframework.boot.logging.AbstractLoggingSystemTests;
import org.springframework.boot.logging.LogLevel;
import org.springframework.boot.logging.LoggerConfiguration;
import org.springframework.boot.logging.LoggingSystem;
import org.springframework.boot.testutil.InternalOutputCapture;
import org.springframework.boot.testutil.Matched;
import org.springframework.util.FileCopyUtils;
@ -148,7 +149,8 @@ public class Log4J2LoggingSystemTests extends AbstractLoggingSystemTests {
List<LoggerConfiguration> configurations = this.loggingSystem
.getLoggerConfigurations();
assertThat(configurations).isNotEmpty();
assertThat(configurations.get(0).getName()).isEmpty();
assertThat(configurations.get(0).getName())
.isEqualTo(LoggingSystem.ROOT_LOGGER_NAME);
}
@Test

@ -43,6 +43,7 @@ import org.springframework.boot.logging.LogFile;
import org.springframework.boot.logging.LogLevel;
import org.springframework.boot.logging.LoggerConfiguration;
import org.springframework.boot.logging.LoggingInitializationContext;
import org.springframework.boot.logging.LoggingSystem;
import org.springframework.boot.testutil.InternalOutputCapture;
import org.springframework.boot.testutil.Matched;
import org.springframework.mock.env.MockEnvironment;
@ -190,7 +191,7 @@ public class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
.getLoggerConfigurations();
assertThat(configurations).isNotEmpty();
assertThat(configurations.get(0).getName())
.isEqualTo(org.slf4j.Logger.ROOT_LOGGER_NAME);
.isEqualTo(LoggingSystem.ROOT_LOGGER_NAME);
}
@Test

Loading…
Cancel
Save