From ffbf06564219421bae3580215fff40cfe65adfc5 Mon Sep 17 00:00:00 2001 From: Duarte Meneses Date: Thu, 19 Nov 2015 16:10:18 +0100 Subject: [PATCH] SONAR-7053 Can't activate debug logging between analysis --- .../org/sonar/batch/bootstrapper/Batch.java | 12 ++++++ .../bootstrapper/LoggingConfiguration.java | 41 +++++++++++++++---- .../bootstrapper/LoggingConfigurator.java | 13 +++--- .../LoggingConfigurationTest.java | 31 ++++++++++++++ .../bootstrapper/LoggingConfiguratorTest.java | 17 ++++++++ .../batch/mediumtest/log/LogListenerTest.java | 29 +++++++++++-- 6 files changed, 126 insertions(+), 17 deletions(-) diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java index a640c0e27fb..62bde940a11 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java @@ -107,7 +107,9 @@ public final class Batch { */ public Batch executeTask(Map analysisProperties, Object... components) { checkStarted(); + configureTaskLogging(analysisProperties); bootstrapContainer.executeTask(analysisProperties, components); + configureLogging(); return this; } @@ -116,7 +118,9 @@ public final class Batch { */ public Batch executeTask(Map analysisProperties, IssueListener issueListener) { checkStarted(); + configureTaskLogging(analysisProperties); bootstrapContainer.executeTask(analysisProperties, components, issueListener); + configureLogging(); return this; } @@ -150,6 +154,14 @@ public final class Batch { private void configureLogging() { if (loggingConfig != null) { + loggingConfig.setProperties(bootstrapProperties); + LoggingConfigurator.apply(loggingConfig); + } + } + + private void configureTaskLogging(Map taskProperties) { + if (loggingConfig != null) { + loggingConfig.setProperties(taskProperties, bootstrapProperties); LoggingConfigurator.apply(loggingConfig); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/LoggingConfiguration.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/LoggingConfiguration.java index e648dad4919..66c827c03b3 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/LoggingConfiguration.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/LoggingConfiguration.java @@ -21,8 +21,12 @@ package org.sonar.batch.bootstrapper; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Maps; + import java.util.Map; + +import javax.annotation.CheckForNull; import javax.annotation.Nullable; + import org.apache.commons.lang.StringUtils; /** @@ -60,8 +64,14 @@ public final class LoggingConfiguration { } public LoggingConfiguration setProperties(Map properties) { - setShowSql(properties); - setVerbose(properties); + setShowSql(properties, null); + setVerbose(properties, null); + return this; + } + + public LoggingConfiguration setProperties(Map properties, @Nullable Map fallback) { + setShowSql(properties, fallback); + setVerbose(properties, fallback); return this; } @@ -74,16 +84,29 @@ public final class LoggingConfiguration { return setRootLevel(verbose ? LEVEL_ROOT_VERBOSE : LEVEL_ROOT_DEFAULT); } - public LoggingConfiguration setVerbose(Map properties) { - String logLevel = properties.get("sonar.log.level"); - String deprecatedProfilingLevel = properties.get("sonar.log.profilingLevel"); - boolean verbose = "true".equals(properties.get("sonar.verbose")) || + public LoggingConfiguration setVerbose(Map props, @Nullable Map fallback) { + String logLevel = getFallback("sonar.log.level", props, fallback); + String deprecatedProfilingLevel = getFallback("sonar.log.profilingLevel", props, fallback); + boolean verbose = "true".equals(getFallback("sonar.verbose", props, fallback)) || "DEBUG".equals(logLevel) || "TRACE".equals(logLevel) || "BASIC".equals(deprecatedProfilingLevel) || "FULL".equals(deprecatedProfilingLevel); return setVerbose(verbose); } + @CheckForNull + private static String getFallback(String key, Map properties, @Nullable Map fallback) { + if (properties.containsKey(key)) { + return properties.get(key); + } + + if (fallback != null) { + return fallback.get(key); + } + + return null; + } + public LoggingConfiguration setRootLevel(String level) { return addSubstitutionVariable(PROPERTY_ROOT_LOGGER_LEVEL, level); } @@ -92,9 +115,9 @@ public final class LoggingConfiguration { return addSubstitutionVariable(PROPERTY_SQL_LOGGER_LEVEL, showSql ? "TRACE" : "WARN"); } - public LoggingConfiguration setShowSql(Map properties) { - String logLevel = properties.get("sonar.log.level"); - String deprecatedProfilingLevel = properties.get("sonar.log.profilingLevel"); + public LoggingConfiguration setShowSql(Map properties, @Nullable Map fallback) { + String logLevel = getFallback("sonar.log.level", properties, fallback); + String deprecatedProfilingLevel = getFallback("sonar.log.profilingLevel", properties, fallback); boolean sql = "TRACE".equals(logLevel) || "FULL".equals(deprecatedProfilingLevel); return setShowSql(sql); diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/LoggingConfigurator.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/LoggingConfigurator.java index 1cf808cde33..573b4183eb5 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/LoggingConfigurator.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/LoggingConfigurator.java @@ -29,6 +29,8 @@ import org.slf4j.LoggerFactory; import org.sonar.core.config.Logback; public class LoggingConfigurator { + private static final String CUSTOM_APPENDER_NAME = "custom_stream"; + private LoggingConfigurator() { } @@ -55,17 +57,18 @@ public class LoggingConfigurator { private static void setCustomRootAppender(LoggingConfiguration conf) { Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); - String pattern = StringUtils.defaultIfBlank(conf.getSubstitutionVariables().get(LoggingConfiguration.PROPERTY_FORMAT), LoggingConfiguration.FORMAT_DEFAULT); String level = StringUtils.defaultIfBlank(conf.getSubstitutionVariables().get(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL), LoggingConfiguration.LEVEL_ROOT_DEFAULT); - logger.detachAndStopAllAppenders(); - logger.addAppender(createAppender(pattern, conf.getLogOutput())); + if (logger.getAppender(CUSTOM_APPENDER_NAME) == null) { + logger.detachAndStopAllAppenders(); + logger.addAppender(createAppender(conf.getLogOutput())); + } logger.setLevel(Level.toLevel(level)); } - private static Appender createAppender(String pattern, LogOutput target) { + private static Appender createAppender(LogOutput target) { LogCallbackAppender appender = new LogCallbackAppender(target); - appender.setName("custom_stream"); + appender.setName(CUSTOM_APPENDER_NAME); appender.start(); return appender; diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrapper/LoggingConfigurationTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrapper/LoggingConfigurationTest.java index 0aae6df636c..4f1ce611c92 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrapper/LoggingConfigurationTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrapper/LoggingConfigurationTest.java @@ -40,6 +40,37 @@ public class LoggingConfigurationTest { .getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo("ERROR"); } + @Test + public void testSetVerboseAnalysis() { + Map globalProps = Maps.newHashMap(); + LoggingConfiguration conf = new LoggingConfiguration(null).setProperties(globalProps); + assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_ROOT_DEFAULT); + assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL)).isEqualTo("WARN"); + + Map analysisProperties = Maps.newHashMap(); + analysisProperties.put("sonar.verbose", "true"); + + conf.setProperties(analysisProperties, globalProps); + assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_ROOT_VERBOSE); + assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL)).isEqualTo("WARN"); + } + + @Test + public void testOverrideVerbose() { + Map globalProps = Maps.newHashMap(); + globalProps.put("sonar.verbose", "true"); + LoggingConfiguration conf = new LoggingConfiguration(null).setProperties(globalProps); + assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_ROOT_VERBOSE); + assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL)).isEqualTo("WARN"); + + Map analysisProperties = Maps.newHashMap(); + analysisProperties.put("sonar.verbose", "false"); + + conf.setProperties(analysisProperties, globalProps); + assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_ROOT_DEFAULT); + assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL)).isEqualTo("WARN"); + } + @Test public void shouldNotBeVerboseByDefault() { assertThat(new LoggingConfiguration(null) diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrapper/LoggingConfiguratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrapper/LoggingConfiguratorTest.java index 9e630914193..db1adc7c557 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrapper/LoggingConfiguratorTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrapper/LoggingConfiguratorTest.java @@ -111,6 +111,23 @@ public class LoggingConfiguratorTest { assertThat(out.size()).isEqualTo(0); } + @Test + public void testConfigureMultipleTimes() throws UnsupportedEncodingException { + System.setOut(new PrintStream(out, false, StandardCharsets.UTF_8.name())); + conf.setLogOutput(listener); + LoggingConfigurator.apply(conf); + + Logger logger = LoggerFactory.getLogger(this.getClass()); + logger.debug("debug"); + assertThat(listener.msg).isNull(); + + conf.setVerbose(true); + LoggingConfigurator.apply(conf); + + logger.debug("debug"); + assertThat(listener.msg).isEqualTo("debug"); + } + @Test public void testFormatNoEffect() throws UnsupportedEncodingException { conf.setLogOutput(listener); diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/log/LogListenerTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/log/LogListenerTest.java index 97567ccdfab..1c2f2f3ba94 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/log/LogListenerTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/log/LogListenerTest.java @@ -32,7 +32,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.io.FileUtils; -import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; @@ -54,6 +53,7 @@ public class LogListenerTest { private Pattern simpleTimePattern = Pattern.compile("\\d{2}:\\d{2}:\\d{2}"); private List logOutput; + private StringBuilder logOutputStr; private ByteArrayOutputStream stdOutTarget = new ByteArrayOutputStream(); private ByteArrayOutputStream stdErrTarget = new ByteArrayOutputStream(); private static PrintStream savedStdOut; @@ -91,6 +91,7 @@ public class LogListenerTest { System.setErr(new PrintStream(stdErrTarget)); // logger from the batch might write to it asynchronously logOutput = Collections.synchronizedList(new LinkedList()); + logOutputStr = new StringBuilder(); tester.start(); baseDir = temp.getRoot(); @@ -121,9 +122,28 @@ public class LogListenerTest { assertThat(matcher.find()).isFalse(); } - @After - public void stop() { + @Test + public void testChangeLogForAnalysis() throws IOException, InterruptedException { + File srcDir = new File(baseDir, "src"); + srcDir.mkdir(); + + File xooFile = new File(srcDir, "sample.xoo"); + FileUtils.write(xooFile, "Sample xoo\ncontent"); + + tester.newTask() + .properties(builder + .put("sonar.sources", "src") + .put("sonar.verbose", "true") + .build()) + .start(); + tester.stop(); + for (LogEvent e : logOutput) { + savedStdOut.println("[captured]" + e.level + " " + e.msg); + } + + // only done in DEBUG during analysis + assertThat(logOutputStr.toString()).contains("Post-jobs : "); } @Test @@ -139,6 +159,7 @@ public class LogListenerTest { .put("sonar.sources", "src") .build()) .start(); + tester.stop(); assertNoStdOutput(); assertThat(logOutput).isNotEmpty(); @@ -163,6 +184,7 @@ public class LogListenerTest { .put("sonar.sources", "src") .build()) .start(); + tester.stop(); assertNoStdOutput(); @@ -178,6 +200,7 @@ public class LogListenerTest { @Override public void log(String msg, Level level) { logOutput.add(new LogEvent(msg, level)); + logOutputStr.append(msg).append("\n"); } } -- 2.39.5