]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7841 Compute Engine logs in sonar.log + step timing are DEBUG
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Thu, 25 Aug 2016 16:29:55 +0000 (18:29 +0200)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Mon, 29 Aug 2016 07:50:41 +0000 (09:50 +0200)
12 files changed:
server/sonar-server/src/main/java/org/sonar/ce/log/CeLogging.java
server/sonar-server/src/main/java/org/sonar/ce/log/CeProcessLogging.java
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/component/VisitorsCrawler.java
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/ExecuteVisitorsStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/task/step/ComputationStepExecutor.java
server/sonar-server/src/main/java/org/sonar/server/computation/taskprocessor/CeWorkerCallableImpl.java
server/sonar-server/src/test/java/org/sonar/ce/log/CeLoggingTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/ChangeLogLevel.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/ReportVisitorsCrawlerTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/ViewsVisitorsCrawlerTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ExecuteVisitorsStepTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/step/ComputationStepExecutorTest.java

index cfab63533d01b90c66e0f0a446337ac0210e0320..9646f851f57eaf5d8831c572d2394f66dd278c5b 100644 (file)
  */
 package org.sonar.ce.log;
 
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.Appender;
-import ch.qos.logback.core.FileAppender;
-import java.util.function.Supplier;
 import org.apache.log4j.MDC;
-import org.sonar.api.utils.log.Logger;
 import org.sonar.ce.queue.CeTask;
-import org.sonar.process.LogbackHelper;
-import org.sonar.process.Props;
 
-/**
- * Manages the logs written by Compute Engine:
- * <ul>
- *   <li>access to existing logs</li>
- *   <li>configure logback when CE worker starts and stops processing a task</li>
- * </ul>
- */
 public class CeLogging {
 
-  private static final String CE_ACTIVITY_APPENDER_NAME = "ce_activity";
-  private static final String CE_ACTIVITY_FILE_NAME_PREFIX = "ce_activity";
-  private static final String CE_ACTIVITY_ENCODER_PATTERN = "%d{yyyy.MM.dd HH:mm:ss} %-5level [%X{ceTaskUuid}][%logger{20}] %msg%n";
-
   static final String MDC_CE_ACTIVITY_FLAG = "ceActivityFlag";
   static final String MDC_CE_TASK_UUID = "ceTaskUuid";
 
@@ -55,41 +35,4 @@ public class CeLogging {
     MDC.remove(MDC_CE_TASK_UUID);
   }
 
-  public void logCeActivity(Logger logger, Runnable logProducer) {
-    MDC.put(MDC_CE_ACTIVITY_FLAG, computeCeActivityFlag(logger));
-    try {
-      logProducer.run();
-    } finally {
-      MDC.remove(MDC_CE_ACTIVITY_FLAG);
-    }
-  }
-
-  public <T> T logCeActivity(Logger logger, Supplier<T> logProducer) {
-    MDC.put(MDC_CE_ACTIVITY_FLAG, computeCeActivityFlag(logger));
-    try {
-      return logProducer.get();
-    } finally {
-      MDC.remove(MDC_CE_ACTIVITY_FLAG);
-    }
-  }
-
-  private static String computeCeActivityFlag(Logger logger) {
-    return logger.isDebugEnabled() || logger.isTraceEnabled() ? "all" : "ce_only";
-  }
-
-  public static Appender<ILoggingEvent> createCeActivityAppenderConfiguration(LogbackHelper helper, LoggerContext ctx, Props processProps) {
-    LogbackHelper.RollingPolicy rollingPolicy = helper.createRollingPolicy(ctx, processProps, CE_ACTIVITY_FILE_NAME_PREFIX);
-    FileAppender<ILoggingEvent> fileAppender = rollingPolicy.createAppender(CE_ACTIVITY_APPENDER_NAME);
-    fileAppender.setContext(ctx);
-
-    PatternLayoutEncoder consoleEncoder = new PatternLayoutEncoder();
-    consoleEncoder.setContext(ctx);
-    consoleEncoder.setPattern(CE_ACTIVITY_ENCODER_PATTERN);
-    consoleEncoder.start();
-    fileAppender.setEncoder(consoleEncoder);
-    fileAppender.addFilter(new CeActivityLogAcceptFilter<>());
-    fileAppender.start();
-
-    return fileAppender;
-  }
 }
index 0f7fe744dde0249ab3bd1c3f3cbe9680b15982db..de414ed39564bb948a3e2e225af49fdc38a119dd 100644 (file)
@@ -43,7 +43,6 @@ public class CeProcessLogging extends ServerProcessLogging {
   protected void configureAppenders(String logFormat, LoggerContext ctx, LogbackHelper helper, Props props) {
     ConsoleAppender<ILoggingEvent> consoleAppender = helper.newConsoleAppender(ctx, "CONSOLE", logFormat, new CeActivityLogConsoleFilter());
     ctx.getLogger(ROOT_LOGGER_NAME).addAppender(consoleAppender);
-    ctx.getLogger(ROOT_LOGGER_NAME).addAppender(CeLogging.createCeActivityAppenderConfiguration(helper, ctx, props));
   }
 
 }
index e94f107eeee62177f48f68e0bdcc64ae3fdf6d71..4512783a6857b5ecf3029a65ebd067837a110d4d 100644 (file)
@@ -23,6 +23,7 @@ import com.google.common.base.Function;
 import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Maps;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import javax.annotation.Nonnull;
@@ -39,21 +40,30 @@ import static java.util.Objects.requireNonNull;
  */
 public class VisitorsCrawler implements ComponentCrawler {
 
+  private final boolean computeDuration;
   private final Map<ComponentVisitor, VisitorDuration> visitorCumulativeDurations;
   private final List<VisitorWrapper> preOrderVisitorWrappers;
   private final List<VisitorWrapper> postOrderVisitorWrappers;
 
   public VisitorsCrawler(Iterable<ComponentVisitor> visitors) {
+    this(visitors, false);
+  }
+
+  public VisitorsCrawler(Iterable<ComponentVisitor> visitors, boolean computeDuration) {
     List<VisitorWrapper> visitorWrappers = from(visitors).transform(ToVisitorWrapper.INSTANCE).toList();
     this.preOrderVisitorWrappers = from(visitorWrappers).filter(MathPreOrderVisitor.INSTANCE).toList();
     this.postOrderVisitorWrappers = from(visitorWrappers).filter(MatchPostOrderVisitor.INSTANCE).toList();
-    this.visitorCumulativeDurations = from(visitors).toMap(VisitorWrapperToInitialDuration.INSTANCE);
+    this.computeDuration = computeDuration;
+    this.visitorCumulativeDurations = computeDuration ? from(visitors).toMap(VisitorWrapperToInitialDuration.INSTANCE) : Collections.emptyMap();
   }
 
   public Map<ComponentVisitor, Long> getCumulativeDurations() {
-    return ImmutableMap.copyOf(
-      Maps.transformValues(this.visitorCumulativeDurations, VisitorDurationToDuration.INSTANCE)
+    if (computeDuration) {
+      return ImmutableMap.copyOf(
+          Maps.transformValues(this.visitorCumulativeDurations, VisitorDurationToDuration.INSTANCE)
       );
+    }
+    return Collections.emptyMap();
   }
 
   @Override
@@ -135,7 +145,9 @@ public class VisitorsCrawler implements ComponentCrawler {
   }
 
   private void incrementDuration(VisitorWrapper visitorWrapper, long duration) {
-    visitorCumulativeDurations.get(visitorWrapper.getWrappedVisitor()).increment(duration);
+    if (computeDuration) {
+      visitorCumulativeDurations.get(visitorWrapper.getWrappedVisitor()).increment(duration);
+    }
   }
 
   private enum ToVisitorWrapper implements Function<ComponentVisitor, VisitorWrapper> {
index 2ad1f0a8935e4bcb6d27fc65b4ad5a2ff6118074..27a37a8acbef8d838312a104aea38771a004bb49 100644 (file)
@@ -23,7 +23,6 @@ import java.util.List;
 import java.util.Map;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
-import org.sonar.ce.log.CeLogging;
 import org.sonar.server.computation.task.projectanalysis.component.ComponentVisitor;
 import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolder;
 import org.sonar.server.computation.task.projectanalysis.component.VisitorsCrawler;
@@ -35,12 +34,10 @@ public class ExecuteVisitorsStep implements ComputationStep {
 
   private final TreeRootHolder treeRootHolder;
   private final List<ComponentVisitor> visitors;
-  private final CeLogging ceLogging;
 
-  public ExecuteVisitorsStep(TreeRootHolder treeRootHolder, List<ComponentVisitor> visitors, CeLogging ceLogging) {
+  public ExecuteVisitorsStep(TreeRootHolder treeRootHolder, List<ComponentVisitor> visitors) {
     this.treeRootHolder = treeRootHolder;
     this.visitors = visitors;
-    this.ceLogging = ceLogging;
   }
 
   @Override
@@ -50,16 +47,18 @@ public class ExecuteVisitorsStep implements ComputationStep {
 
   @Override
   public void execute() {
-    VisitorsCrawler visitorsCrawler = new VisitorsCrawler(visitors);
+    VisitorsCrawler visitorsCrawler = new VisitorsCrawler(visitors, LOGGER.isDebugEnabled());
     visitorsCrawler.visit(treeRootHolder.getRoot());
-    ceLogging.logCeActivity(LOGGER, () -> logVisitorExecutionDurations(visitors, visitorsCrawler));
+    logVisitorExecutionDurations(visitors, visitorsCrawler);
   }
 
   private static void logVisitorExecutionDurations(List<ComponentVisitor> visitors, VisitorsCrawler visitorsCrawler) {
-    LOGGER.info("  Execution time for each component visitor:");
-    Map<ComponentVisitor, Long> cumulativeDurations = visitorsCrawler.getCumulativeDurations();
-    for (ComponentVisitor visitor : visitors) {
-      LOGGER.info("  - {} | time={}ms", visitor.getClass().getSimpleName(), cumulativeDurations.get(visitor));
+    if (LOGGER.isDebugEnabled()) {
+      LOGGER.debug("  Execution time for each component visitor:");
+      Map<ComponentVisitor, Long> cumulativeDurations = visitorsCrawler.getCumulativeDurations();
+      for (ComponentVisitor visitor : visitors) {
+        LOGGER.debug("  - {} | time={}ms", visitor.getClass().getSimpleName(), cumulativeDurations.get(visitor));
+      }
     }
   }
 }
index 9bbbe34c40be88c5da8187c06f317bab0a4fdad1..854dc1013fe4e735286bcc0b3311b1ada76e3691 100644 (file)
@@ -23,14 +23,12 @@ import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
-import org.sonar.ce.log.CeLogging;
 import org.sonar.core.util.logs.Profiler;
 
 public final class ComputationStepExecutor {
   private static final Logger LOGGER = Loggers.get(ComputationStepExecutor.class);
 
   private final ComputationSteps steps;
-  private final CeLogging ceLogging;
   @CheckForNull
   private final Listener listener;
 
@@ -38,13 +36,12 @@ public final class ComputationStepExecutor {
    * Used when no {@link ComputationStepExecutor.Listener} is available in pico
    * container.
    */
-  public ComputationStepExecutor(ComputationSteps steps, CeLogging ceLogging) {
-    this(steps, ceLogging, null);
+  public ComputationStepExecutor(ComputationSteps steps) {
+    this(steps, null);
   }
 
-  public ComputationStepExecutor(ComputationSteps steps, CeLogging ceLogging, @Nullable Listener listener) {
+  public ComputationStepExecutor(ComputationSteps steps, @Nullable Listener listener) {
     this.steps = steps;
-    this.ceLogging = ceLogging;
     this.listener = listener;
   }
 
@@ -65,7 +62,7 @@ public final class ComputationStepExecutor {
     for (ComputationStep step : steps.instances()) {
       stepProfiler.start();
       step.execute();
-      ceLogging.logCeActivity(LOGGER, () -> stepProfiler.stopInfo(step.getDescription()));
+      stepProfiler.stopDebug(step.getDescription());
     }
   }
 
index 0b80433e5ac41a4df909794a7c9da6ab654da7da..2c749a6edbedbe8042c48647a524516d4e7279fa 100644 (file)
@@ -97,18 +97,18 @@ public class CeWorkerCallableImpl implements CeWorkerCallable {
     }
   }
 
-  private Profiler startActivityProfiler(CeTask task) {
+  private static Profiler startActivityProfiler(CeTask task) {
     Profiler profiler = Profiler.create(LOG);
     addContext(profiler, task);
-    return ceLogging.logCeActivity(LOG, () -> profiler.startInfo("Execute task"));
+    return profiler.startInfo("Execute task");
   }
 
-  private void stopActivityProfiler(Profiler profiler, CeTask task, CeActivityDto.Status status) {
+  private static void stopActivityProfiler(Profiler profiler, CeTask task, CeActivityDto.Status status) {
     addContext(profiler, task);
     if (status == CeActivityDto.Status.FAILED) {
-      ceLogging.logCeActivity(LOG, () -> profiler.stopError("Executed task"));
+      profiler.stopError("Executed task");
     } else {
-      ceLogging.logCeActivity(LOG, () -> profiler.stopInfo("Executed task"));
+      profiler.stopInfo("Executed task");
     }
   }
 
index 0f5d24fb0abcbfe0f7602ae751e547875f81dc58..c251892a2840a3628e7eb6917176afb0a9bebf4b 100644 (file)
  */
 package org.sonar.ce.log;
 
-import ch.qos.logback.classic.Level;
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.Appender;
-import ch.qos.logback.core.FileAppender;
-import ch.qos.logback.core.filter.Filter;
 import ch.qos.logback.core.joran.spi.JoranException;
-import java.io.File;
-import java.util.List;
-import java.util.Properties;
-import java.util.concurrent.atomic.AtomicBoolean;
 import org.junit.After;
-import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-import org.junit.rules.TemporaryFolder;
 import org.mockito.Mockito;
 import org.slf4j.MDC;
-import org.sonar.api.utils.log.Logger;
 import org.sonar.ce.queue.CeTask;
 import org.sonar.process.LogbackHelper;
-import org.sonar.process.ProcessProperties;
-import org.sonar.process.Props;
 
-import static ch.qos.logback.classic.Level.DEBUG;
-import static ch.qos.logback.classic.Level.ERROR;
-import static ch.qos.logback.classic.Level.INFO;
-import static ch.qos.logback.classic.Level.TRACE;
-import static ch.qos.logback.classic.Level.WARN;
-import static junit.framework.TestCase.fail;
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
-import static org.sonar.ce.log.CeLogging.MDC_CE_ACTIVITY_FLAG;
 import static org.sonar.ce.log.CeLogging.MDC_CE_TASK_UUID;
 
 public class CeLoggingTest {
 
   @Rule
   public ExpectedException expectedException = ExpectedException.none();
-  @Rule
-  public TemporaryFolder temp = new TemporaryFolder();
 
   private LogbackHelper helper = new LogbackHelper();
-  private File logDir;
-
   private CeLogging underTest = new CeLogging();
 
-  @Before
-  public void setUp() throws Exception {
-    this.logDir = temp.newFolder();
-  }
-
   @After
   public void resetLogback() throws JoranException {
     helper.resetFromXml("/logback-test.xml");
@@ -108,168 +75,4 @@ public class CeLoggingTest {
     assertThat(MDC.get(MDC_CE_TASK_UUID)).isNull();
   }
 
-  @Test
-  public void createCeConfigurationConfiguration_fails_if_log_directory_is_not_set_in_Props() {
-    LogbackHelper helper = new LogbackHelper();
-    LoggerContext ctx = new LoggerContext();
-    Props processProps = new Props(new Properties());
-
-    expectedException.expect(IllegalArgumentException.class);
-    expectedException.expectMessage("Property sonar.path.logs is not set");
-
-    CeLogging.createCeActivityAppenderConfiguration(helper, ctx, processProps);
-  }
-
-  @Test
-  public void createCeConfigurationConfiguration() {
-    Properties props = new Properties();
-    props.setProperty(ProcessProperties.PATH_LOGS, logDir.getAbsolutePath());
-    Appender<ILoggingEvent> appender = CeLogging.createCeActivityAppenderConfiguration(new LogbackHelper(), new LoggerContext(), new Props(props));
-
-    // filter on CE logs
-    List<Filter<ILoggingEvent>> filters = appender.getCopyOfAttachedFiltersList();
-    assertThat(filters).hasSize(1);
-    assertThat(filters.get(0)).isInstanceOf(CeActivityLogAcceptFilter.class);
-
-    assertThat(appender).isInstanceOf(FileAppender.class);
-    assertThat(appender.getName()).isEqualTo("ce_activity");
-    FileAppender fileAppender = (FileAppender) appender;
-    assertThat(fileAppender.getEncoder())
-      .isInstanceOf(PatternLayoutEncoder.class);
-    assertThat(fileAppender.getFile()).isEqualTo(new File(logDir, "ce_activity.log").getAbsolutePath());
-  }
-
-  @Test
-  public void logCeActivity_of_Runnable_set_flag_in_MDC_to_ce_only_when_log_level_is_ERROR_and_calls_Runnable_and_remove_flag_even_if_Runnable_throws_exception() {
-    callLogCeActivityOfRunnableAndVerify("ce_only", ERROR);
-    callLogCeActivityOfFailingRunnableAndVerify("ce_only", ERROR);
-  }
-
-  @Test
-  public void logCeActivity_of_Runnable_set_flag_in_MDC_to_ce_only_when_log_level_is_WARN_and_calls_Runnable_and_remove_flag_even_if_Runnable_throws_exception() {
-    callLogCeActivityOfRunnableAndVerify("ce_only", WARN);
-    callLogCeActivityOfFailingRunnableAndVerify("ce_only", WARN);
-  }
-
-  @Test
-  public void logCeActivity_of_Runnable_set_flag_in_MDC_to_ce_only_when_log_level_is_INFO_and_calls_Runnable_and_remove_flag_even_if_Runnable_throws_exception() {
-    callLogCeActivityOfRunnableAndVerify("ce_only", INFO);
-  }
-
-  @Test
-  public void logCeActivity_of_Runnable_set_flag_in_MDC_to_all_when_log_level_is_DEBUG_and_calls_Runnable_and_remove_flag_even_if_Runnable_throws_exception() {
-    callLogCeActivityOfRunnableAndVerify("all", DEBUG);
-    callLogCeActivityOfFailingRunnableAndVerify("all", DEBUG);
-  }
-
-  @Test
-  public void logCeActivity_of_Runnable_set_flag_in_MDC_to_all_when_log_level_is_TRACE_and_calls_Runnable_and_remove_flag_even_if_Runnable_throws_exception() {
-    callLogCeActivityOfRunnableAndVerify("all", TRACE);
-    callLogCeActivityOfFailingRunnableAndVerify("all", TRACE);
-  }
-
-  private void callLogCeActivityOfRunnableAndVerify(String expectedMdcValue, Level logLevel) {
-    AtomicBoolean called = new AtomicBoolean(false);
-    underTest.logCeActivity(
-      createLogger(logLevel),
-      () -> {
-        assertThat(MDC.get(MDC_CE_ACTIVITY_FLAG)).isEqualTo(expectedMdcValue);
-        called.compareAndSet(false, true);
-      });
-    assertThat(MDC.get(MDC_CE_ACTIVITY_FLAG)).isNull();
-    assertThat(called.get()).isTrue();
-  }
-
-  private void callLogCeActivityOfFailingRunnableAndVerify(String expectedMdcValue, Level logLevel) {
-    RuntimeException exception = new RuntimeException("Simulates a failing Runnable");
-
-    AtomicBoolean called = new AtomicBoolean(false);
-    try {
-      underTest.logCeActivity(
-        createLogger(logLevel),
-        () -> {
-          assertThat(MDC.get(MDC_CE_ACTIVITY_FLAG)).isEqualTo(expectedMdcValue);
-          called.compareAndSet(false, true);
-          throw exception;
-        });
-      fail("exception should have been raised");
-    } catch (Exception e) {
-      assertThat(e).isSameAs(exception);
-    } finally {
-      assertThat(MDC.get(MDC_CE_ACTIVITY_FLAG)).isNull();
-      assertThat(called.get()).isTrue();
-    }
-  }
-
-  private static Logger createLogger(Level info) {
-    Logger logger = mock(Logger.class);
-    when(logger.isDebugEnabled()).thenReturn(DEBUG.isGreaterOrEqual(info));
-    when(logger.isTraceEnabled()).thenReturn(TRACE.isGreaterOrEqual(info));
-    return logger;
-  }
-
-  @Test
-  public void logCeActivity_of_Supplier_set_flag_in_MDC_to_ce_only_when_log_level_is_ERROR_and_calls_Supplier_and_remove_flag_even_if_Supplier_throws_exception() {
-    callLogCeActivityOfSupplierAndVerify(ERROR, "ce_only");
-    callLogCeActivityOfFailingSupplierAndVerify(ERROR, "ce_only");
-  }
-
-  @Test
-  public void logCeActivity_of_Supplier_set_flag_in_MDC_to_ce_only_when_log_level_is_WARN_and_calls_Supplier_and_remove_flag_even_if_Supplier_throws_exception() {
-    callLogCeActivityOfSupplierAndVerify(WARN, "ce_only");
-    callLogCeActivityOfFailingSupplierAndVerify(WARN, "ce_only");
-  }
-
-  @Test
-  public void logCeActivity_of_Supplier_set_flag_in_MDC_to_ce_only_when_log_level_is_INFO_and_calls_Supplier_and_remove_flag_even_if_Supplier_throws_exception() {
-    callLogCeActivityOfSupplierAndVerify(INFO, "ce_only");
-    callLogCeActivityOfFailingSupplierAndVerify(INFO, "ce_only");
-  }
-
-  @Test
-  public void logCeActivity_of_Supplier_set_flag_in_MDC_to_all_when_log_level_is_DEBUG_and_calls_Supplier_and_remove_flag_even_if_Supplier_throws_exception() {
-    callLogCeActivityOfSupplierAndVerify(DEBUG, "all");
-    callLogCeActivityOfFailingSupplierAndVerify(DEBUG, "all");
-  }
-
-  @Test
-  public void logCeActivity_of_Supplier_set_flag_in_MDC_to_all_when_log_level_is_TRACE_and_calls_Supplier_and_remove_flag_even_if_Supplier_throws_exception() {
-    callLogCeActivityOfSupplierAndVerify(TRACE, "all");
-    callLogCeActivityOfFailingSupplierAndVerify(TRACE, "all");
-  }
-
-  private void callLogCeActivityOfSupplierAndVerify(Level logLevel, String expectedFlag) {
-    AtomicBoolean called = new AtomicBoolean(false);
-    underTest.logCeActivity(
-      createLogger(logLevel),
-      () -> {
-        assertThat(MDC.get(MDC_CE_ACTIVITY_FLAG)).isEqualTo(expectedFlag);
-        called.compareAndSet(false, true);
-        return 1;
-      });
-    assertThat(MDC.get(MDC_CE_ACTIVITY_FLAG)).isNull();
-    assertThat(called.get()).isTrue();
-  }
-
-  private void callLogCeActivityOfFailingSupplierAndVerify(Level logLevel, String expectedFlag) {
-    RuntimeException exception = new RuntimeException("Simulates a failing Supplier");
-
-    AtomicBoolean called = new AtomicBoolean(false);
-    try {
-      underTest.logCeActivity(
-        createLogger(logLevel),
-        () -> {
-          assertThat(MDC.get(MDC_CE_ACTIVITY_FLAG)).isEqualTo(expectedFlag);
-          called.compareAndSet(false, true);
-          throw exception;
-        });
-      fail("exception should have been raised");
-    } catch (Exception e) {
-      assertThat(e).isSameAs(exception);
-    } finally {
-      assertThat(MDC.get(MDC_CE_ACTIVITY_FLAG)).isNull();
-      assertThat(called.get()).isTrue();
-    }
-  }
-
 }
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/ChangeLogLevel.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/ChangeLogLevel.java
new file mode 100644 (file)
index 0000000..ba2ac86
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.task;
+
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.LoggerLevel;
+import org.sonar.api.utils.log.Loggers;
+
+public final class ChangeLogLevel implements AutoCloseable {
+  private final Logger logger;
+  private final LoggerLevel previous;
+
+  public ChangeLogLevel(Class<?> clazz, LoggerLevel newLevel) {
+    this.logger = Loggers.get(clazz);
+    this.previous = logger.getLevel();
+    logger.setLevel(newLevel);
+  }
+
+  @Override
+  public void close() {
+    logger.setLevel(previous);
+  }
+}
index f5e4f5519c66006b0afe0e5e40d427fe95a93850..e7e42e8b05c6a1a591d470c3a184798e8790fbe3 100644 (file)
@@ -25,6 +25,7 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.mockito.InOrder;
 
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.inOrder;
@@ -86,7 +87,7 @@ public class ReportVisitorsCrawlerTest {
   @Test
   public void execute_pre_visitor_before_post_visitor() throws Exception {
     InOrder inOrder = inOrder(spyPreOrderTypeAwareVisitor, spyPostOrderTypeAwareVisitor);
-    VisitorsCrawler underTest = new VisitorsCrawler(Arrays.<ComponentVisitor>asList(spyPreOrderTypeAwareVisitor, spyPostOrderTypeAwareVisitor));
+    VisitorsCrawler underTest = new VisitorsCrawler(Arrays.asList(spyPreOrderTypeAwareVisitor, spyPostOrderTypeAwareVisitor));
     underTest.visit(COMPONENT_TREE);
 
     inOrder.verify(spyPreOrderTypeAwareVisitor).visitProject(COMPONENT_TREE);
@@ -102,6 +103,22 @@ public class ReportVisitorsCrawlerTest {
     inOrder.verify(spyPostOrderTypeAwareVisitor).visitProject(COMPONENT_TREE);
   }
 
+  @Test
+  public void getCumulativeDurations_returns_an_empty_map_when_computation_is_disabled_in_constructor() {
+    VisitorsCrawler underTest = new VisitorsCrawler(Arrays.asList(spyPreOrderTypeAwareVisitor, spyPostOrderTypeAwareVisitor), false);
+    underTest.visit(COMPONENT_TREE);
+
+    assertThat(underTest.getCumulativeDurations()).isEmpty();
+  }
+
+  @Test
+  public void getCumulativeDurations_returns_an_non_empty_map_when_computation_is_enabled_in_constructor() {
+    VisitorsCrawler underTest = new VisitorsCrawler(Arrays.asList(spyPreOrderTypeAwareVisitor, spyPostOrderTypeAwareVisitor), true);
+    underTest.visit(COMPONENT_TREE);
+
+    assertThat(underTest.getCumulativeDurations()).hasSize(2);
+  }
+
   @Test
   public void fail_with_IAE_when_visitor_is_not_path_aware_or_type_aware() throws Exception {
     thrown.expect(IllegalArgumentException.class);
index 0e20adaac1b87910b42a4c7d2f802f46b17bfa81..cebe643cab079d5b16e88147ea1d3107c2816d38 100644 (file)
@@ -25,6 +25,7 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.mockito.InOrder;
 
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.inOrder;
@@ -53,7 +54,7 @@ public class ViewsVisitorsCrawlerTest {
   @Test
   public void execute_each_visitor_on_each_level() throws Exception {
     InOrder inOrder = inOrder(spyPostOrderTypeAwareVisitor, spyPathAwareVisitor);
-    VisitorsCrawler underTest = new VisitorsCrawler(Arrays.asList(spyPostOrderTypeAwareVisitor, spyPathAwareVisitor));
+    VisitorsCrawler underTest = new VisitorsCrawler(Arrays.asList(spyPostOrderTypeAwareVisitor, spyPathAwareVisitor), false);
     underTest.visit(COMPONENT_TREE);
 
     inOrder.verify(spyPostOrderTypeAwareVisitor).visitAny(PROJECT_VIEW_5);
@@ -85,7 +86,7 @@ public class ViewsVisitorsCrawlerTest {
   @Test
   public void execute_pre_visitor_before_post_visitor() throws Exception {
     InOrder inOrder = inOrder(spyPreOrderTypeAwareVisitor, spyPostOrderTypeAwareVisitor);
-    VisitorsCrawler underTest = new VisitorsCrawler(Arrays.<ComponentVisitor>asList(spyPreOrderTypeAwareVisitor, spyPostOrderTypeAwareVisitor));
+    VisitorsCrawler underTest = new VisitorsCrawler(Arrays.<ComponentVisitor>asList(spyPreOrderTypeAwareVisitor, spyPostOrderTypeAwareVisitor), false);
     underTest.visit(COMPONENT_TREE);
 
     inOrder.verify(spyPreOrderTypeAwareVisitor).visitView(COMPONENT_TREE);
@@ -120,6 +121,22 @@ public class ViewsVisitorsCrawlerTest {
     new VisitorsCrawler(Arrays.asList(componentVisitor));
   }
 
+  @Test
+  public void getCumulativeDurations_returns_an_empty_map_when_computation_is_disabled_in_constructor() {
+    VisitorsCrawler underTest = new VisitorsCrawler(Arrays.asList(spyPreOrderTypeAwareVisitor, spyPostOrderTypeAwareVisitor), false);
+    underTest.visit(COMPONENT_TREE);
+
+    assertThat(underTest.getCumulativeDurations()).isEmpty();
+  }
+
+  @Test
+  public void getCumulativeDurations_returns_an_non_empty_map_when_computation_is_enabled_in_constructor() {
+    VisitorsCrawler underTest = new VisitorsCrawler(Arrays.asList(spyPreOrderTypeAwareVisitor, spyPostOrderTypeAwareVisitor), true);
+    underTest.visit(COMPONENT_TREE);
+
+    assertThat(underTest.getCumulativeDurations()).hasSize(2);
+  }
+
   private static Component component(final Component.Type type, final int ref, final Component... children) {
     return ViewsComponent.builder(type, ref).addChildren(children).build();
   }
index e48f66b3db1ad0f965081a0e0b4b49f1d87353b3..cb83b9af5c9cf3dc9cac7b41e9ed9d34af0d5a93 100644 (file)
@@ -24,9 +24,8 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.utils.log.LogTester;
-import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.LoggerLevel;
-import org.sonar.ce.log.CeLogging;
+import org.sonar.server.computation.task.ChangeLogLevel;
 import org.sonar.server.computation.task.projectanalysis.component.Component;
 import org.sonar.server.computation.task.projectanalysis.component.ComponentVisitor;
 import org.sonar.server.computation.task.projectanalysis.component.CrawlerDepthLimit;
@@ -41,9 +40,6 @@ import org.sonar.server.computation.task.projectanalysis.metric.MetricRepository
 import static java.util.Arrays.asList;
 import static java.util.Collections.singletonList;
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
 import static org.sonar.api.measures.CoreMetrics.NCLOC;
 import static org.sonar.api.measures.CoreMetrics.NCLOC_KEY;
 import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.DIRECTORY;
@@ -74,8 +70,6 @@ public class ExecuteVisitorsStepTest {
   @Rule
   public LogTester logTester = new LogTester();
 
-  private CeLogging ceLogging = spy(new CeLogging());
-
   @Before
   public void setUp() throws Exception {
     treeRootHolder.setRoot(
@@ -94,7 +88,7 @@ public class ExecuteVisitorsStepTest {
 
   @Test
   public void execute_with_type_aware_visitor() throws Exception {
-    ExecuteVisitorsStep underStep = new ExecuteVisitorsStep(treeRootHolder, singletonList(new TestTypeAwareVisitor()), ceLogging);
+    ExecuteVisitorsStep underStep = new ExecuteVisitorsStep(treeRootHolder, singletonList(new TestTypeAwareVisitor()));
 
     measureRepository.addRawMeasure(FILE_1_REF, NCLOC_KEY, newMeasureBuilder().create(1));
     measureRepository.addRawMeasure(FILE_2_REF, NCLOC_KEY, newMeasureBuilder().create(2));
@@ -113,7 +107,7 @@ public class ExecuteVisitorsStepTest {
 
   @Test
   public void execute_with_path_aware_visitor() throws Exception {
-    ExecuteVisitorsStep underStep = new ExecuteVisitorsStep(treeRootHolder, singletonList(new TestPathAwareVisitor()), ceLogging);
+    ExecuteVisitorsStep underStep = new ExecuteVisitorsStep(treeRootHolder, singletonList(new TestPathAwareVisitor()));
 
     measureRepository.addRawMeasure(FILE_1_REF, NCLOC_KEY, newMeasureBuilder().create(1));
     measureRepository.addRawMeasure(FILE_2_REF, NCLOC_KEY, newMeasureBuilder().create(1));
@@ -129,20 +123,24 @@ public class ExecuteVisitorsStepTest {
 
   @Test
   public void execute_logs_at_info_level_all_execution_duration_of_all_visitors() {
-    ExecuteVisitorsStep underStep = new ExecuteVisitorsStep(
-      treeRootHolder,
-      asList(new VisitorA(), new VisitorB(), new VisitorC()),
-      ceLogging);
-
-    underStep.execute();
+    try (ChangeLogLevel executor = new ChangeLogLevel(ExecuteVisitorsStep.class, LoggerLevel.DEBUG);
+      ChangeLogLevel step1 = new ChangeLogLevel(VisitorA.class, LoggerLevel.DEBUG);
+      ChangeLogLevel step2 = new ChangeLogLevel(VisitorB.class, LoggerLevel.DEBUG);
+      ChangeLogLevel step3 = new ChangeLogLevel(VisitorB.class, LoggerLevel.DEBUG)) {
+      ExecuteVisitorsStep underStep = new ExecuteVisitorsStep(
+        treeRootHolder,
+        asList(new VisitorA(), new VisitorB(), new VisitorC()));
+
+      underStep.execute();
+
+      List<String> logs = logTester.logs(LoggerLevel.DEBUG);
+      assertThat(logs).hasSize(4);
+      assertThat(logs.get(0)).isEqualTo("  Execution time for each component visitor:");
+      assertThat(logs.get(1)).startsWith("  - VisitorA | time=");
+      assertThat(logs.get(2)).startsWith("  - VisitorB | time=");
+      assertThat(logs.get(3)).startsWith("  - VisitorC | time=");
 
-    verify(ceLogging).logCeActivity(any(Logger.class), any(Runnable.class));
-    List<String> logs = logTester.logs(LoggerLevel.INFO);
-    assertThat(logs).hasSize(4);
-    assertThat(logs.get(0)).isEqualTo("  Execution time for each component visitor:");
-    assertThat(logs.get(1)).startsWith("  - VisitorA | time=");
-    assertThat(logs.get(2)).startsWith("  - VisitorB | time=");
-    assertThat(logs.get(3)).startsWith("  - VisitorC | time=");
+    }
   }
 
   private static class VisitorA extends TypeAwareVisitorAdapter {
index 1435f1ec54e2d0ed0004d06ae3918aa711e9e11e..197cdb50ba4f4c4ea5b32134f1c65c91d4b09519 100644 (file)
@@ -27,7 +27,7 @@ import org.junit.rules.ExpectedException;
 import org.mockito.InOrder;
 import org.sonar.api.utils.log.LogTester;
 import org.sonar.api.utils.log.LoggerLevel;
-import org.sonar.ce.log.CeLogging;
+import org.sonar.server.computation.task.ChangeLogLevel;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.fail;
@@ -49,11 +49,9 @@ public class ComputationStepExecutorTest {
   private final ComputationStep computationStep2 = mockComputationStep("step2");
   private final ComputationStep computationStep3 = mockComputationStep("step3");
 
-  private CeLogging ceLogging = new CeLogging();
-
   @Test
   public void execute_call_execute_on_each_ComputationStep_in_order_returned_by_instances_method() {
-    new ComputationStepExecutor(mockComputationSteps(computationStep1, computationStep2, computationStep3), ceLogging)
+    new ComputationStepExecutor(mockComputationSteps(computationStep1, computationStep2, computationStep3))
       .execute();
 
     InOrder inOrder = inOrder(computationStep1, computationStep2, computationStep3);
@@ -75,7 +73,7 @@ public class ComputationStepExecutorTest {
       .when(computationStep)
       .execute();
 
-    ComputationStepExecutor computationStepExecutor = new ComputationStepExecutor(mockComputationSteps(computationStep), ceLogging);
+    ComputationStepExecutor computationStepExecutor = new ComputationStepExecutor(mockComputationSteps(computationStep));
 
     expectedException.expect(RuntimeException.class);
     expectedException.expectMessage(message);
@@ -84,19 +82,41 @@ public class ComputationStepExecutorTest {
   }
 
   @Test
-  public void execute_logs_end_timing_for_each_ComputationStep_called() {
-    new ComputationStepExecutor(mockComputationSteps(computationStep1, computationStep2), ceLogging)
-      .execute();
+  public void execute_does_not_log_end_timing_for_each_ComputationStep_called_when_level_is_INFO() {
+    List<String> infoLogs = execute_logs_end_timing_for_each_ComputationStep_called_when_(LoggerLevel.INFO);
+    assertThat(infoLogs).isEmpty();
+  }
 
-    List<String> infoLogs = logTester.logs(LoggerLevel.INFO);
+  @Test
+  public void execute_logs_end_timing_for_each_ComputationStep_called_when_level_is_DEBUG() {
+    List<String> infoLogs = execute_logs_end_timing_for_each_ComputationStep_called_when_(LoggerLevel.DEBUG);
     assertThat(infoLogs).hasSize(2);
     assertThat(infoLogs.get(0)).contains("step1 | time=");
     assertThat(infoLogs.get(1)).contains("step2 | time=");
   }
 
+  @Test
+  public void execute_logs_end_timing_for_each_ComputationStep_called_when_level_is_TRACE() {
+    List<String> infoLogs = execute_logs_end_timing_for_each_ComputationStep_called_when_(LoggerLevel.TRACE);
+    assertThat(infoLogs).hasSize(2);
+    assertThat(infoLogs.get(0)).contains("step1 | time=");
+    assertThat(infoLogs.get(1)).contains("step2 | time=");
+  }
+
+  private List<String> execute_logs_end_timing_for_each_ComputationStep_called_when_(LoggerLevel level) {
+    try (ChangeLogLevel executor = new ChangeLogLevel(ComputationStepExecutor.class, level);
+         ChangeLogLevel step1 = new ChangeLogLevel(computationStep1.getClass(), level);
+         ChangeLogLevel step2 = new ChangeLogLevel(computationStep2.getClass(), level)) {
+      new ComputationStepExecutor(mockComputationSteps(computationStep1, computationStep2))
+        .execute();
+
+      return logTester.logs(LoggerLevel.DEBUG);
+    }
+  }
+
   @Test
   public void execute_calls_listener_finished_method_with_all_step_runs() {
-    new ComputationStepExecutor(mockComputationSteps(computationStep1, computationStep2), ceLogging, listener)
+    new ComputationStepExecutor(mockComputationSteps(computationStep1, computationStep2), listener)
       .execute();
 
     verify(listener).finished(true);
@@ -111,7 +131,7 @@ public class ComputationStepExecutorTest {
       .execute();
 
     try {
-      new ComputationStepExecutor(mockComputationSteps(computationStep1, computationStep2), ceLogging, listener)
+      new ComputationStepExecutor(mockComputationSteps(computationStep1, computationStep2), listener)
         .execute();
       fail("exception toBeThrown should have been raised");
     } catch (RuntimeException e) {