From 619a2b2bdf11bb3d4eb61ae3610ca38f23c2370a Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=A9bastien=20Lesaint?= Date: Mon, 3 Apr 2017 16:24:05 +0200 Subject: [PATCH] SONAR-7485 enable back Tomcat logs if trace if globally enabled --- .../sonar/process/logging/LogLevelConfig.java | 19 ++++++++ .../sonar/process/logging/LogbackHelper.java | 16 +++++-- .../process/logging/LogbackHelperTest.java | 43 +++++++++++++++++-- .../server/app/WebServerProcessLogging.java | 10 ++--- .../app/WebServerProcessLoggingTest.java | 42 ++++++++++++++++++ 5 files changed, 119 insertions(+), 11 deletions(-) diff --git a/server/sonar-process/src/main/java/org/sonar/process/logging/LogLevelConfig.java b/server/sonar-process/src/main/java/org/sonar/process/logging/LogLevelConfig.java index c7a414f371d..8e4c813b24f 100644 --- a/server/sonar-process/src/main/java/org/sonar/process/logging/LogLevelConfig.java +++ b/server/sonar-process/src/main/java/org/sonar/process/logging/LogLevelConfig.java @@ -23,8 +23,10 @@ import ch.qos.logback.classic.Level; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; import org.sonar.process.ProcessId; @@ -39,10 +41,12 @@ public final class LogLevelConfig { private final Map> configuredByProperties; private final Map configuredByHardcodedLevel; + private final Set offUnlessTrace; private LogLevelConfig(Builder builder) { this.configuredByProperties = Collections.unmodifiableMap(builder.configuredByProperties); this.configuredByHardcodedLevel = Collections.unmodifiableMap(builder.configuredByHardcodedLevel); + this.offUnlessTrace = Collections.unmodifiableSet(builder.offUnlessTrace); } Map> getConfiguredByProperties() { @@ -53,6 +57,10 @@ public final class LogLevelConfig { return configuredByHardcodedLevel; } + public Set getOffUnlessTrace() { + return offUnlessTrace; + } + public static Builder newBuilder() { return new Builder(); } @@ -60,6 +68,7 @@ public final class LogLevelConfig { public static final class Builder { private final Map> configuredByProperties = new HashMap<>(); private final Map configuredByHardcodedLevel = new HashMap<>(); + private final Set offUnlessTrace = new HashSet<>(); private Builder() { // use static factory method @@ -113,6 +122,9 @@ public final class LogLevelConfig { if (configuredByHardcodedLevel.containsKey(loggerName)) { throw new IllegalStateException("Configuration hardcoded level already registered for " + loggerName); } + if (offUnlessTrace.contains(loggerName)) { + throw new IllegalStateException("Configuration off unless TRACE already registered for " + loggerName); + } } private static void checkProcessId(ProcessId processId) { @@ -126,6 +138,13 @@ public final class LogLevelConfig { } } + public Builder offUnlessTrace(String loggerName) { + checkLoggerName(loggerName); + ensureUniqueConfiguration(loggerName); + offUnlessTrace.add(loggerName); + return this; + } + public LogLevelConfig build() { return new LogLevelConfig(this); } diff --git a/server/sonar-process/src/main/java/org/sonar/process/logging/LogbackHelper.java b/server/sonar-process/src/main/java/org/sonar/process/logging/LogbackHelper.java index b45d9451e94..16c5a9cbcff 100644 --- a/server/sonar-process/src/main/java/org/sonar/process/logging/LogbackHelper.java +++ b/server/sonar-process/src/main/java/org/sonar/process/logging/LogbackHelper.java @@ -54,6 +54,7 @@ import static org.slf4j.Logger.ROOT_LOGGER_NAME; */ public class LogbackHelper { + private static final String SONAR_LOG_LEVEL_PROPERTY = "sonar.log.level"; private static final String ALL_LOGS_TO_CONSOLE_PROPERTY = "sonar.log.console"; private static final String PROCESS_NAME_PLACEHOLDER = "XXXX"; private static final String THREAD_ID_PLACEHOLDER = "ZZZZ"; @@ -99,8 +100,11 @@ public class LogbackHelper { */ public LoggerContext apply(LogLevelConfig logLevelConfig, Props props) { LoggerContext rootContext = getRootContext(); - logLevelConfig.getConfiguredByProperties().entrySet().forEach(entry -> applyLevelByProperty(props, rootContext.getLogger(entry.getKey()), entry.getValue())); - logLevelConfig.getConfiguredByHardcodedLevel().entrySet().forEach(entry -> applyHardcodedLevel(rootContext, entry.getKey(), entry.getValue())); + logLevelConfig.getConfiguredByProperties().forEach((key, value) -> applyLevelByProperty(props, rootContext.getLogger(key), value)); + logLevelConfig.getConfiguredByHardcodedLevel().forEach((key, value) -> applyHardcodedLevel(rootContext, key, value)); + Level propertyValueAsLevel = getPropertyValueAsLevel(props, SONAR_LOG_LEVEL_PROPERTY); + boolean traceGloballyEnabled = propertyValueAsLevel == Level.TRACE; + logLevelConfig.getOffUnlessTrace().forEach(logger -> applyHardUnlessTrace(rootContext, logger, traceGloballyEnabled)); return rootContext; } @@ -133,11 +137,17 @@ public class LogbackHelper { rootContext.getLogger(loggerName).setLevel(newLevel); } + private static void applyHardUnlessTrace(LoggerContext rootContext, String logger, boolean traceGloballyEnabled) { + if (!traceGloballyEnabled) { + rootContext.getLogger(logger).setLevel(Level.OFF); + } + } + public void changeRoot(LogLevelConfig logLevelConfig, Level newLevel) { ensureSupportedLevel(newLevel); LoggerContext rootContext = getRootContext(); rootContext.getLogger(ROOT_LOGGER_NAME).setLevel(newLevel); - logLevelConfig.getConfiguredByProperties().entrySet().forEach(entry -> rootContext.getLogger(entry.getKey()).setLevel(newLevel)); + logLevelConfig.getConfiguredByProperties().forEach((key, value) -> rootContext.getLogger(key).setLevel(newLevel)); } private static void ensureSupportedLevel(Level newLevel) { diff --git a/server/sonar-process/src/test/java/org/sonar/process/logging/LogbackHelperTest.java b/server/sonar-process/src/test/java/org/sonar/process/logging/LogbackHelperTest.java index 9b6a50d8e0d..0317f8f12f4 100644 --- a/server/sonar-process/src/test/java/org/sonar/process/logging/LogbackHelperTest.java +++ b/server/sonar-process/src/test/java/org/sonar/process/logging/LogbackHelperTest.java @@ -35,7 +35,7 @@ import com.tngtech.java.junit.dataprovider.DataProviderRunner; import com.tngtech.java.junit.dataprovider.UseDataProvider; import java.io.File; import java.util.Properties; -import org.junit.AfterClass; +import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -68,8 +68,8 @@ public class LogbackHelperTest { props.set(ProcessProperties.PATH_LOGS, dir.getAbsolutePath()); } - @AfterClass - public static void resetLogback() throws Exception { + @After + public void resetLogback() throws Exception { new LogbackHelper().resetFromXml("/org/sonar/process/logging/LogbackHelperTest/logback-test.xml"); } @@ -319,6 +319,43 @@ public class LogbackHelperTest { assertThat(context.getLogger("pif").getLevel()).isEqualTo(Level.TRACE); } + @Test + public void apply_set_level_to_OFF_if_sonar_global_level_is_not_set() { + LoggerContext context = underTest.apply(LogLevelConfig.newBuilder().offUnlessTrace("fii").build(), new Props(new Properties())); + + assertThat(context.getLogger("fii").getLevel()).isEqualTo(Level.OFF); + } + + @Test + public void apply_set_level_to_OFF_if_sonar_global_level_is_INFO() { + setLevelToOff(Level.INFO); + } + + @Test + public void apply_set_level_to_OFF_if_sonar_global_level_is_DEBUG() { + setLevelToOff(Level.DEBUG); + } + + @Test + public void apply_does_not_set_level_if_sonar_global_level_is_TRACE() { + Properties properties = new Properties(); + properties.setProperty("sonar.log.level", Level.TRACE.toString()); + assertThat(underTest.getRootContext().getLogger("fii").getLevel()).isNull(); + + LoggerContext context = underTest.apply(LogLevelConfig.newBuilder().offUnlessTrace("fii").build(), new Props(properties)); + + assertThat(context.getLogger("fii").getLevel()).isNull(); + } + + private void setLevelToOff(Level globalLogLevel) { + Properties properties = new Properties(); + properties.setProperty("sonar.log.level", globalLogLevel.toString()); + + LoggerContext context = underTest.apply(LogLevelConfig.newBuilder().offUnlessTrace("fii").build(), new Props(properties)); + + assertThat(context.getLogger("fii").getLevel()).isEqualTo(Level.OFF); + } + @DataProvider public static Object[][] logbackLevels() { return new Object[][] { diff --git a/server/sonar-server/src/main/java/org/sonar/server/app/WebServerProcessLogging.java b/server/sonar-server/src/main/java/org/sonar/server/app/WebServerProcessLogging.java index 20ec182c276..98c79054720 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/app/WebServerProcessLogging.java +++ b/server/sonar-server/src/main/java/org/sonar/server/app/WebServerProcessLogging.java @@ -19,13 +19,12 @@ */ package org.sonar.server.app; -import ch.qos.logback.classic.Level; import java.util.logging.LogManager; import org.slf4j.bridge.SLF4JBridgeHandler; -import org.sonar.process.logging.LogLevelConfig; import org.sonar.process.ProcessId; - import org.sonar.process.logging.LogDomain; +import org.sonar.process.logging.LogLevelConfig; + import static org.sonar.server.platform.web.requestid.RequestIdMDCStorage.HTTP_REQUEST_ID_MDC_KEY; /** @@ -44,8 +43,9 @@ public class WebServerProcessLogging extends ServerProcessLogging { logLevelConfigBuilder.levelByDomain("auth.event", ProcessId.WEB_SERVER, LogDomain.AUTH_EVENT); JMX_RMI_LOGGER_NAMES.forEach(loggerName -> logLevelConfigBuilder.levelByDomain(loggerName, ProcessId.WEB_SERVER, LogDomain.JMX)); - logLevelConfigBuilder.immutableLevel("org.apache.catalina.core.ContainerBase", Level.OFF); - logLevelConfigBuilder.immutableLevel("org.apache.catalina.core.StandardContext", Level.OFF); + logLevelConfigBuilder.offUnlessTrace("org.apache.catalina.core.ContainerBase"); + logLevelConfigBuilder.offUnlessTrace("org.apache.catalina.core.StandardContext"); + logLevelConfigBuilder.offUnlessTrace("org.apache.catalina.core.StandardService"); } @Override diff --git a/server/sonar-server/src/test/java/org/sonar/server/app/WebServerProcessLoggingTest.java b/server/sonar-server/src/test/java/org/sonar/server/app/WebServerProcessLoggingTest.java index 487ebb3b71d..722978a3cab 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/app/WebServerProcessLoggingTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/app/WebServerProcessLoggingTest.java @@ -426,6 +426,42 @@ public class WebServerProcessLoggingTest { verifyImmutableLogLevels(context); } + @Test + public void configure_turns_off_some_Tomcat_loggers_if_global_log_level_is_not_set() { + LoggerContext context = underTest.configure(props); + + verifyTomcatLoggersLogLevelsOff(context); + } + + @Test + public void configure_turns_off_some_Tomcat_loggers_if_global_log_level_is_INFO() { + props.set("sonar.log.level", "INFO"); + + LoggerContext context = underTest.configure(props); + + verifyTomcatLoggersLogLevelsOff(context); + } + + @Test + public void configure_turns_off_some_Tomcat_loggers_if_global_log_level_is_DEBUG() { + props.set("sonar.log.level", "DEBUG"); + + LoggerContext context = underTest.configure(props); + + verifyTomcatLoggersLogLevelsOff(context); + } + + @Test + public void configure_turns_off_some_Tomcat_loggers_if_global_log_level_is_TRACE() { + props.set("sonar.log.level", "TRACE"); + + LoggerContext context = underTest.configure(props); + + assertThat(context.getLogger("org.apache.catalina.core.ContainerBase").getLevel()).isNull(); + assertThat(context.getLogger("org.apache.catalina.core.StandardContext").getLevel()).isNull(); + assertThat(context.getLogger("org.apache.catalina.core.StandardService").getLevel()).isNull(); + } + private void verifyRootLogLevel(LoggerContext ctx, Level expected) { Logger rootLogger = ctx.getLogger(ROOT_LOGGER_NAME); assertThat(rootLogger.getLevel()).isEqualTo(expected); @@ -466,4 +502,10 @@ public class WebServerProcessLoggingTest { assertThat(ctx.getLogger("org.apache.tomcat").getLevel()).isEqualTo(Level.INFO); } + private void verifyTomcatLoggersLogLevelsOff(LoggerContext context) { + assertThat(context.getLogger("org.apache.catalina.core.ContainerBase").getLevel()).isEqualTo(Level.OFF); + assertThat(context.getLogger("org.apache.catalina.core.StandardContext").getLevel()).isEqualTo(Level.OFF); + assertThat(context.getLogger("org.apache.catalina.core.StandardService").getLevel()).isEqualTo(Level.OFF); + } + } -- 2.39.5