]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-4756 Introduce a centralized component for profiling logs
authorJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>
Thu, 28 Nov 2013 15:54:58 +0000 (16:54 +0100)
committerJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>
Mon, 2 Dec 2013 14:54:24 +0000 (15:54 +0100)
sonar-core/src/main/java/org/sonar/core/profiling/LoggingWatch.java [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/profiling/NoopWatch.java [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/profiling/Profiling.java [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/profiling/ProfilingLogFactory.java [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/profiling/StopWatch.java [new file with mode: 0644]
sonar-core/src/test/java/org/sonar/core/profiling/ProfilingLogFactoryTest.java [new file with mode: 0644]
sonar-core/src/test/java/org/sonar/core/profiling/ProfilingTest.java [new file with mode: 0644]

diff --git a/sonar-core/src/main/java/org/sonar/core/profiling/LoggingWatch.java b/sonar-core/src/main/java/org/sonar/core/profiling/LoggingWatch.java
new file mode 100644 (file)
index 0000000..2e29aa7
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.core.profiling;
+
+import org.slf4j.Logger;
+
+class LoggingWatch extends StopWatch {
+
+  private Logger logger;
+  private long startTimeInMillis;
+
+  LoggingWatch(Logger logger) {
+    this.logger = logger;
+    this.startTimeInMillis = System.currentTimeMillis();
+  }
+
+  @Override
+  public void stop(String message, Object... args) {
+    long endTimeInMillis = System.currentTimeMillis();
+    logger.info("{}ms {}", Long.valueOf(endTimeInMillis - startTimeInMillis), String.format(message, args));
+  }
+
+}
diff --git a/sonar-core/src/main/java/org/sonar/core/profiling/NoopWatch.java b/sonar-core/src/main/java/org/sonar/core/profiling/NoopWatch.java
new file mode 100644 (file)
index 0000000..fea67f8
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.core.profiling;
+
+
+class NoopWatch extends StopWatch {
+
+  @Override
+  public void stop(String message, Object... args) {
+    // Nothing logged
+  }
+}
diff --git a/sonar-core/src/main/java/org/sonar/core/profiling/Profiling.java b/sonar-core/src/main/java/org/sonar/core/profiling/Profiling.java
new file mode 100644 (file)
index 0000000..6174b83
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.core.profiling;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.ServerExtension;
+import org.sonar.api.config.Settings;
+
+/**
+ * @since 4.1
+ */
+public final class Profiling implements ServerExtension {
+
+  private static final Logger LOGGER = LoggerFactory.getLogger(Profiling.class);
+
+  private Settings settings;
+  private ProfilingLogFactory logFactory;
+
+  public enum Level {
+    NONE, BASIC, FULL;
+  }
+
+  public Profiling(Settings settings) {
+    this(settings, new ProfilingLogFactory());
+  }
+
+  Profiling(Settings settings, ProfilingLogFactory logFactory) {
+    this.settings = settings;
+    this.logFactory = logFactory;
+  }
+
+
+  public StopWatch start(String domain, Level level) {
+    StopWatch watch;
+    if (isProfilingEnabled(level)) {
+      watch = new LoggingWatch(logFactory.getLogger(domain));
+    } else {
+      watch = new NoopWatch();
+    }
+    return watch;
+  }
+
+  private boolean isProfilingEnabled(Level level) {
+    String settingsValue = settings.getString("sonar.log.profilingLevel");
+    Level settingsLevel = Level.NONE;
+    if (settingsValue != null) {
+      try {
+        settingsLevel = Level.valueOf(settingsValue);
+      } catch(IllegalArgumentException invalidSettings) {
+        LOGGER.debug("Bad profiling settings, profiling is disabled", invalidSettings);
+      }
+    }
+    return settingsLevel != Level.NONE && level.ordinal() <= settingsLevel.ordinal();
+  }
+}
diff --git a/sonar-core/src/main/java/org/sonar/core/profiling/ProfilingLogFactory.java b/sonar-core/src/main/java/org/sonar/core/profiling/ProfilingLogFactory.java
new file mode 100644 (file)
index 0000000..e994a42
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.core.profiling;
+
+import org.slf4j.LoggerFactory;
+
+import org.slf4j.Logger;
+
+class ProfilingLogFactory {
+
+  public Logger getLogger(String domain) {
+    return LoggerFactory.getLogger(domain);
+  }
+}
diff --git a/sonar-core/src/main/java/org/sonar/core/profiling/StopWatch.java b/sonar-core/src/main/java/org/sonar/core/profiling/StopWatch.java
new file mode 100644 (file)
index 0000000..a7f8ada
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.core.profiling;
+
+public abstract class StopWatch {
+
+  public abstract void stop(String message, Object... args);
+}
diff --git a/sonar-core/src/test/java/org/sonar/core/profiling/ProfilingLogFactoryTest.java b/sonar-core/src/test/java/org/sonar/core/profiling/ProfilingLogFactoryTest.java
new file mode 100644 (file)
index 0000000..6488421
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.core.profiling;
+
+import org.junit.Test;
+
+public class ProfilingLogFactoryTest {
+
+  @Test
+  public void just_for_coverage() throws Exception {
+    new ProfilingLogFactory().getLogger("domain");
+  }
+}
diff --git a/sonar-core/src/test/java/org/sonar/core/profiling/ProfilingTest.java b/sonar-core/src/test/java/org/sonar/core/profiling/ProfilingTest.java
new file mode 100644 (file)
index 0000000..16ed187
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.core.profiling;
+
+import static org.mockito.Mockito.mock;
+
+import org.slf4j.Logger;
+
+import org.mockito.Mockito;
+import org.sonar.core.profiling.Profiling.Level;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.config.Settings;
+
+public class ProfilingTest {
+
+  private Settings settings;
+  private ProfilingLogFactory logFactory;
+  private Logger logger;
+  private Profiling profiling;
+
+  private static final String BASIC_MESSAGE = "Basic message";
+  private static final String FULL_MESSAGE = "Full message";
+
+  @Before
+  public void prepare() {
+    settings = new Settings();
+    logFactory = mock(ProfilingLogFactory.class);
+    logger = mock(Logger.class);
+    Mockito.when(logFactory.getLogger(Mockito.anyString())).thenReturn(logger);
+    profiling = new Profiling(settings, logFactory);
+  }
+
+  @Test
+  public void should_silence_all_profiling_by_default() throws Exception {
+    doProfiling();
+    Mockito.verifyZeroInteractions(logger);
+  }
+
+  @Test
+  public void should_silence_all_profiling_when_faulty_config() throws Exception {
+    settings.setProperty("sonar.log.profilingLevel", "POLOP");
+    doProfiling();
+    Mockito.verifyZeroInteractions(logger);
+  }
+
+  @Test
+  public void should_silence_all_profiling() throws Exception {
+    settings.setProperty("sonar.log.profilingLevel", "NONE");
+    doProfiling();
+    Mockito.verifyZeroInteractions(logger);
+  }
+
+  @Test
+  public void should_log_basic_level() throws Exception {
+    settings.setProperty("sonar.log.profilingLevel", "BASIC");
+    doProfiling();
+    Mockito.verify(logger).info(Mockito.eq("{}ms {}"), Mockito.anyLong(), Mockito.eq(BASIC_MESSAGE));
+    Mockito.verifyNoMoreInteractions(logger);
+  }
+
+  @Test
+  public void should_log_everything() throws Exception {
+    settings.setProperty("sonar.log.profilingLevel", "FULL");
+    doProfiling();
+    Mockito.verify(logger).info(Mockito.eq("{}ms {}"), Mockito.anyLong(), Mockito.eq(FULL_MESSAGE));
+    Mockito.verify(logger).info(Mockito.eq("{}ms {}"), Mockito.anyLong(), Mockito.eq(BASIC_MESSAGE));
+  }
+
+  private void doProfiling() throws InterruptedException {
+    StopWatch basicWatch = profiling.start("basic", Level.BASIC);
+    StopWatch fullWatch = profiling.start("full", Level.FULL);
+    Thread.sleep(42);
+    fullWatch.stop(FULL_MESSAGE);
+    basicWatch.stop(BASIC_MESSAGE);
+  }
+  
+}