]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7053 Can't activate debug logging between analysis
authorDuarte Meneses <duarte.meneses@sonarsource.com>
Thu, 19 Nov 2015 15:10:18 +0000 (16:10 +0100)
committerDuarte Meneses <duarte.meneses@sonarsource.com>
Fri, 20 Nov 2015 13:27:53 +0000 (14:27 +0100)
sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java
sonar-batch/src/main/java/org/sonar/batch/bootstrapper/LoggingConfiguration.java
sonar-batch/src/main/java/org/sonar/batch/bootstrapper/LoggingConfigurator.java
sonar-batch/src/test/java/org/sonar/batch/bootstrapper/LoggingConfigurationTest.java
sonar-batch/src/test/java/org/sonar/batch/bootstrapper/LoggingConfiguratorTest.java
sonar-batch/src/test/java/org/sonar/batch/mediumtest/log/LogListenerTest.java

index a640c0e27fb0abce6141551e412c6bf7adf61f1e..62bde940a11ffa42a5c77968523bdfbba6f9f621 100644 (file)
@@ -107,7 +107,9 @@ public final class Batch {
    */
   public Batch executeTask(Map<String, String> 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<String, String> 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<String, String> taskProperties) {
+    if (loggingConfig != null) {
+      loggingConfig.setProperties(taskProperties, bootstrapProperties);
       LoggingConfigurator.apply(loggingConfig);
     }
   }
index e648dad4919bf83a9c9138ed1288b4bf6a254ee4..66c827c03b3917859f98f64ec84c2f40702b3599 100644 (file)
@@ -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<String, String> properties) {
-    setShowSql(properties);
-    setVerbose(properties);
+    setShowSql(properties, null);
+    setVerbose(properties, null);
+    return this;
+  }
+
+  public LoggingConfiguration setProperties(Map<String, String> properties, @Nullable Map<String, String> 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<String, String> 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<String, String> props, @Nullable Map<String, String> 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<String, String> properties, @Nullable Map<String, String> 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<String, String> properties) {
-    String logLevel = properties.get("sonar.log.level");
-    String deprecatedProfilingLevel = properties.get("sonar.log.profilingLevel");
+  public LoggingConfiguration setShowSql(Map<String, String> properties, @Nullable Map<String, String> 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);
index 1cf808cde33f42f9eec474c54b91af3da4000700..573b4183eb5ac88c1a7bdd3c2750d962afaf157a 100644 (file)
@@ -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<ILoggingEvent> createAppender(String pattern, LogOutput target) {
+  private static Appender<ILoggingEvent> createAppender(LogOutput target) {
     LogCallbackAppender appender = new LogCallbackAppender(target);
-    appender.setName("custom_stream");
+    appender.setName(CUSTOM_APPENDER_NAME);
     appender.start();
 
     return appender;
index 0aae6df636c0756dbeeb40a1d90e1f8f63df8bbd..4f1ce611c923e6ba324a6c6e598f4a33e6e108fc 100644 (file)
@@ -40,6 +40,37 @@ public class LoggingConfigurationTest {
       .getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo("ERROR");
   }
 
+  @Test
+  public void testSetVerboseAnalysis() {
+    Map<String, String> 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<String, String> 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<String, String> 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<String, String> 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)
index 9e63091419340dc8fc21aafd5a0034c6e4784a29..db1adc7c55716c354ecfdefcef4c27bce1dfed4f 100644 (file)
@@ -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);
index 97567ccdfab8c1caf28308fd75cc2148bcb82214..1c2f2f3ba94281be7eeb42074837697114ae423c 100644 (file)
@@ -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<LogEvent> 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<LogEvent>());
+    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");
     }
   }