From 0518e8253c82e39e2d7c7d8aa82873edc32d442d Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=A9bastien=20Lesaint?= Date: Tue, 15 Nov 2016 11:17:33 +0100 Subject: [PATCH] SONAR-8335 support properties to configure log level per JVM --- .../java/org/sonar/process/LogbackHelper.java | 40 ++++++++++++------- .../java/org/sonar/search/SearchLogging.java | 3 +- .../org/sonar/ce/log/CeProcessLogging.java | 5 ++- .../server/app/ServerProcessLogging.java | 13 +++--- .../server/app/WebServerProcessLogging.java | 3 +- .../org/sonar/application/AppLogging.java | 3 +- .../org/sonar/application/AppLoggingTest.java | 6 +-- 7 files changed, 45 insertions(+), 28 deletions(-) diff --git a/server/sonar-process/src/main/java/org/sonar/process/LogbackHelper.java b/server/sonar-process/src/main/java/org/sonar/process/LogbackHelper.java index a669c91a9ce..7a86fe5dd4a 100644 --- a/server/sonar-process/src/main/java/org/sonar/process/LogbackHelper.java +++ b/server/sonar-process/src/main/java/org/sonar/process/LogbackHelper.java @@ -53,11 +53,12 @@ import static org.slf4j.Logger.ROOT_LOGGER_NAME; public class LogbackHelper { 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"; private static final String SONAR_LOG_LEVEL_PROPERTY = "sonar.log.level"; + private static final String SONAR_PROCESS_LOG_LEVEL_PROPERTY = "sonar.log.level." + PROCESS_NAME_PLACEHOLDER; private static final String ROLLING_POLICY_PROPERTY = "sonar.log.rollingPolicy"; private static final String MAX_FILES_PROPERTY = "sonar.log.maxFiles"; - private static final String PROCESS_NAME_PLACEHOLDER = "XXXX"; - private static final String THREAD_ID_PLACEHOLDER = "ZZZZ"; private static final String LOG_FORMAT = "%d{yyyy.MM.dd HH:mm:ss} %-5level " + PROCESS_NAME_PLACEHOLDER + "[" + THREAD_ID_PLACEHOLDER + "][%logger{20}] %msg%n"; public static final Set ALLOWED_ROOT_LOG_LEVELS = unmodifiableSet(setOf(Level.TRACE, Level.DEBUG, Level.INFO)); @@ -164,8 +165,8 @@ public class LogbackHelper { public String buildLogPattern(LogbackHelper.RootLoggerConfig config) { return LOG_FORMAT - .replace(PROCESS_NAME_PLACEHOLDER, config.getProcessName()) - .replace(THREAD_ID_PLACEHOLDER, config.getThreadIdFieldPattern()); + .replace(PROCESS_NAME_PLACEHOLDER, config.getProcessName()) + .replace(THREAD_ID_PLACEHOLDER, config.getThreadIdFieldPattern()); } /** @@ -190,12 +191,12 @@ public class LogbackHelper { /** * Make logback configuration for a process to push all its logs to a log file. *

- *

+ * *

* * @see #buildLogPattern(RootLoggerConfig) @@ -254,17 +255,26 @@ public class LogbackHelper { * * @throws IllegalArgumentException if the value of {@link #SONAR_LOG_LEVEL_PROPERTY} is not one of {@link #ALLOWED_ROOT_LOG_LEVELS} */ - public Level configureRootLogLevel(Props props) { - return configureRootLogLevel(props, SONAR_LOG_LEVEL_PROPERTY); + public Level configureRootLogLevel(Props props, ProcessId processId) { + return configureRootLogLevel(props, + SONAR_LOG_LEVEL_PROPERTY, + SONAR_PROCESS_LOG_LEVEL_PROPERTY.replace(PROCESS_NAME_PLACEHOLDER, processId.getKey())); } /** - * Configure the log level of the root logger reading the value of specified property. + * Configure the log level of the root logger reading the value of specified properties. The lowest level will be + * applied. * * @throws IllegalArgumentException if the value of the specified property is not one of {@link #ALLOWED_ROOT_LOG_LEVELS} */ - public Level configureRootLogLevel(Props props, String propertyKey) { - Level newLevel = Level.toLevel(props.value(propertyKey, Level.INFO.toString()), Level.INFO); + public Level configureRootLogLevel(Props props, String... propertyKeys) { + Level newLevel = Level.INFO; + for (String propertyKey : propertyKeys) { + Level level = Level.toLevel(props.value(propertyKey, Level.INFO.toString()), Level.INFO); + if (!level.isGreaterOrEqual(newLevel)) { + newLevel = level; + } + } return configureRootLogLevel(newLevel); } diff --git a/server/sonar-search/src/main/java/org/sonar/search/SearchLogging.java b/server/sonar-search/src/main/java/org/sonar/search/SearchLogging.java index 62c710e929a..5a35bd69c65 100644 --- a/server/sonar-search/src/main/java/org/sonar/search/SearchLogging.java +++ b/server/sonar-search/src/main/java/org/sonar/search/SearchLogging.java @@ -38,7 +38,8 @@ public class SearchLogging { String logPattern = helper.buildLogPattern(config); helper.configureGlobalFileLog(props, config, logPattern); helper.configureForSubprocessGobbler(props, logPattern); - helper.configureRootLogLevel(props); + // SQ's global log level must not change ES's log level + helper.configureRootLogLevel(props, "sonar.log.es.level"); return ctx; } diff --git a/server/sonar-server/src/main/java/org/sonar/ce/log/CeProcessLogging.java b/server/sonar-server/src/main/java/org/sonar/ce/log/CeProcessLogging.java index 201878865df..e756cd1c251 100644 --- a/server/sonar-server/src/main/java/org/sonar/ce/log/CeProcessLogging.java +++ b/server/sonar-server/src/main/java/org/sonar/ce/log/CeProcessLogging.java @@ -19,16 +19,19 @@ */ package org.sonar.ce.log; +import org.sonar.process.ProcessId; import org.sonar.process.Props; import org.sonar.server.app.ServerProcessLogging; +import static org.sonar.ce.log.CeLogging.MDC_CE_TASK_UUID; + /** * Configure logback for the Compute Engine process. Logs are written to file "ce.log" in SQ's log directory. */ public class CeProcessLogging extends ServerProcessLogging { public CeProcessLogging() { - super("ce", "%X{ceTaskUuid}"); + super(ProcessId.COMPUTE_ENGINE, "%X{" + MDC_CE_TASK_UUID + "}"); } @Override diff --git a/server/sonar-server/src/main/java/org/sonar/server/app/ServerProcessLogging.java b/server/sonar-server/src/main/java/org/sonar/server/app/ServerProcessLogging.java index ec9f4e565d4..933f6800314 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/app/ServerProcessLogging.java +++ b/server/sonar-server/src/main/java/org/sonar/server/app/ServerProcessLogging.java @@ -21,18 +21,19 @@ package org.sonar.server.app; import ch.qos.logback.classic.LoggerContext; import org.sonar.process.LogbackHelper; +import org.sonar.process.ProcessId; import org.sonar.process.Props; import org.sonar.server.platform.ServerLogging; import static org.sonar.process.LogbackHelper.RootLoggerConfig.newRootLoggerConfigBuilder; public abstract class ServerProcessLogging { - private final String processName; + private final ProcessId processId; private final String threadIdFieldPattern; private final LogbackHelper helper = new LogbackHelper(); - protected ServerProcessLogging(String processName, String threadIdFieldPattern) { - this.processName = processName; + protected ServerProcessLogging(ProcessId processId, String threadIdFieldPattern) { + this.processId = processId; this.threadIdFieldPattern = threadIdFieldPattern; } @@ -52,16 +53,16 @@ public abstract class ServerProcessLogging { private void configureRootLogger(Props props) { LogbackHelper.RootLoggerConfig config = newRootLoggerConfigBuilder() - .setProcessName(processName) + .setProcessName(processId.getKey()) .setThreadIdFieldPattern(threadIdFieldPattern) - .setFileNamePrefix(processName) + .setFileNamePrefix(processId.getKey()) .build(); String logPattern = helper.buildLogPattern(config); helper.configureGlobalFileLog(props, config, logPattern); helper.configureForSubprocessGobbler(props, logPattern); - helper.configureRootLogLevel(props); + helper.configureRootLogLevel(props, processId); ServerLogging.configureHardcodedLevels(helper); } 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 f10f249db8d..f4f0753f214 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 @@ -21,6 +21,7 @@ package org.sonar.server.app; import java.util.logging.LogManager; import org.slf4j.bridge.SLF4JBridgeHandler; +import org.sonar.process.ProcessId; import org.sonar.process.Props; /** @@ -29,7 +30,7 @@ import org.sonar.process.Props; public class WebServerProcessLogging extends ServerProcessLogging { public WebServerProcessLogging() { - super("web", "%X{UID}"); + super(ProcessId.WEB_SERVER, "%X{UID}"); } @Override diff --git a/sonar-application/src/main/java/org/sonar/application/AppLogging.java b/sonar-application/src/main/java/org/sonar/application/AppLogging.java index 7ec122f95ce..6a5586b9381 100644 --- a/sonar-application/src/main/java/org/sonar/application/AppLogging.java +++ b/sonar-application/src/main/java/org/sonar/application/AppLogging.java @@ -25,6 +25,7 @@ import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.ConsoleAppender; import ch.qos.logback.core.FileAppender; import org.sonar.process.LogbackHelper; +import org.sonar.process.ProcessId; import org.sonar.process.Props; import static org.slf4j.Logger.ROOT_LOGGER_NAME; @@ -126,7 +127,7 @@ class AppLogging { } else { configureWithWrapperWritingToFile(ctx); } - helper.configureRootLogLevel(props, "sonar.app.log.level"); + helper.configureRootLogLevel(props, ProcessId.APP); return ctx; } diff --git a/sonar-application/src/test/java/org/sonar/application/AppLoggingTest.java b/sonar-application/src/test/java/org/sonar/application/AppLoggingTest.java index 0fccc6e11c7..d53a868482b 100644 --- a/sonar-application/src/test/java/org/sonar/application/AppLoggingTest.java +++ b/sonar-application/src/test/java/org/sonar/application/AppLoggingTest.java @@ -178,7 +178,7 @@ public class AppLoggingTest { @Test public void root_logger_level_can_be_changed_with_a_property() { - props.set("sonar.app.log.level", "TRACE"); + props.set("sonar.log.level.app", "TRACE"); LoggerContext ctx = underTest.configure(props); Logger rootLogger = ctx.getLogger(ROOT_LOGGER_NAME); @@ -187,7 +187,7 @@ public class AppLoggingTest { @Test public void property_changing_root_logger_level_is_case_insensitive() { - props.set("sonar.app.log.level", "trace"); + props.set("sonar.log.level.app", "trace"); LoggerContext ctx = underTest.configure(props); Logger rootLogger = ctx.getLogger(ROOT_LOGGER_NAME); @@ -196,7 +196,7 @@ public class AppLoggingTest { @Test public void default_to_INFO_if_property_changing_root_logger_level_has_invalid_value() { - props.set("sonar.app.log.level", "DodoDouh!"); + props.set("sonar.log.level.app", "DodoDouh!"); LoggerContext ctx = underTest.configure(props); Logger rootLogger = ctx.getLogger(ROOT_LOGGER_NAME); -- 2.39.5