aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2016-05-11 10:42:05 +0200
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>2016-05-11 14:02:52 +0200
commit8405142eb1e9ea19f518e4eb49e5f0078d1e4fb9 (patch)
treee9aa9e409be27d3ba30b71ea75c65dd4fa725720
parent25917fa9613242de25c276889a759760e7cc39bf (diff)
downloadsonarqube-8405142eb1e9ea19f518e4eb49e5f0078d1e4fb9.tar.gz
sonarqube-8405142eb1e9ea19f518e4eb49e5f0078d1e4fb9.zip
SONAR-7532 Profiler can now put context before or after time
-rw-r--r--sonar-core/src/main/java/org/sonar/core/util/logs/DefaultProfiler.java56
-rw-r--r--sonar-core/src/main/java/org/sonar/core/util/logs/NullProfiler.java5
-rw-r--r--sonar-core/src/main/java/org/sonar/core/util/logs/Profiler.java6
-rw-r--r--sonar-core/src/test/java/org/sonar/core/util/logs/DefaultProfilerTest.java195
-rw-r--r--sonar-core/src/test/java/org/sonar/core/util/logs/NullProfilerTest.java2
5 files changed, 233 insertions, 31 deletions
diff --git a/sonar-core/src/main/java/org/sonar/core/util/logs/DefaultProfiler.java b/sonar-core/src/main/java/org/sonar/core/util/logs/DefaultProfiler.java
index fff901f8f9f..c758fcff160 100644
--- a/sonar-core/src/main/java/org/sonar/core/util/logs/DefaultProfiler.java
+++ b/sonar-core/src/main/java/org/sonar/core/util/logs/DefaultProfiler.java
@@ -31,6 +31,7 @@ import org.sonar.api.utils.log.LoggerLevel;
class DefaultProfiler extends Profiler {
private static final String CONTEXT_SEPARATOR = " | ";
+ private static final String NO_MESSAGE_SUFFIX = "";
private final LinkedHashMap<String, Object> context = new LinkedHashMap<>();
private final Logger logger;
@@ -38,6 +39,7 @@ class DefaultProfiler extends Profiler {
private long startTime = 0L;
private String startMessage = null;
private Object[] args = null;
+ private boolean logTimeLast = false;
public DefaultProfiler(Logger logger) {
this.logger = logger;
@@ -107,37 +109,37 @@ class DefaultProfiler extends Profiler {
@Override
public long stopTrace(String message) {
- return doStop(LoggerLevel.TRACE, message, null, "");
+ return doStop(LoggerLevel.TRACE, message, null, NO_MESSAGE_SUFFIX);
}
@Override
public long stopTrace(String message, Object... args) {
- return doStop(LoggerLevel.TRACE, message, args, "");
+ return doStop(LoggerLevel.TRACE, message, args, NO_MESSAGE_SUFFIX);
}
@Override
public long stopDebug(String message) {
- return doStop(LoggerLevel.DEBUG, message, null, "");
+ return doStop(LoggerLevel.DEBUG, message, null, NO_MESSAGE_SUFFIX);
}
@Override
public long stopDebug(String message, Object... args) {
- return doStop(LoggerLevel.DEBUG, message, args, "");
+ return doStop(LoggerLevel.DEBUG, message, args, NO_MESSAGE_SUFFIX);
}
@Override
public long stopInfo(String message) {
- return doStop(LoggerLevel.INFO, message, null, "");
+ return doStop(LoggerLevel.INFO, message, null, NO_MESSAGE_SUFFIX);
}
@Override
public long stopInfo(String message, Object... args) {
- return doStop(LoggerLevel.INFO, message, args, "");
+ return doStop(LoggerLevel.INFO, message, args, NO_MESSAGE_SUFFIX);
}
@Override
public long stopError(String message, Object... args) {
- return doStop(LoggerLevel.ERROR, message, args, "");
+ return doStop(LoggerLevel.ERROR, message, args, NO_MESSAGE_SUFFIX);
}
private Profiler doStart(LoggerLevel logLevel, String message, Object... args) {
@@ -185,16 +187,36 @@ class DefaultProfiler extends Profiler {
if (!StringUtils.isEmpty(message)) {
sb.append(message);
sb.append(messageSuffix);
- sb.append(CONTEXT_SEPARATOR);
}
- sb.append("time=").append(duration).append("ms");
- appendContext(sb);
+ if (logTimeLast) {
+ appendContext(sb);
+ appendTime(sb, duration);
+ } else {
+ appendTime(sb, duration);
+ appendContext(sb);
+ }
log(level, sb.toString(), args);
}
reset();
return duration;
}
+ private static void appendTime(StringBuilder sb, long duration) {
+ if (sb.length() > 0) {
+ sb.append(CONTEXT_SEPARATOR);
+ }
+ sb.append("time=").append(duration).append("ms");
+ }
+
+ private void appendContext(StringBuilder sb) {
+ for (Map.Entry<String, Object> entry : context.entrySet()) {
+ if (sb.length() > 0) {
+ sb.append(CONTEXT_SEPARATOR);
+ }
+ sb.append(entry.getKey()).append("=").append(Objects.toString(entry.getValue()));
+ }
+ }
+
void log(LoggerLevel level, String msg, @Nullable Object[] args) {
switch (level) {
case TRACE:
@@ -267,15 +289,6 @@ class DefaultProfiler extends Profiler {
return true;
}
- private void appendContext(StringBuilder sb) {
- for (Map.Entry<String, Object> entry : context.entrySet()) {
- if (sb.length() > 0) {
- sb.append(CONTEXT_SEPARATOR);
- }
- sb.append(entry.getKey()).append("=").append(Objects.toString(entry.getValue()));
- }
- }
-
@Override
public Profiler addContext(String key, @Nullable Object value) {
if (value == null) {
@@ -286,4 +299,9 @@ class DefaultProfiler extends Profiler {
return this;
}
+ @Override
+ public Profiler logTimeLast(boolean flag) {
+ this.logTimeLast = flag;
+ return this;
+ }
}
diff --git a/sonar-core/src/main/java/org/sonar/core/util/logs/NullProfiler.java b/sonar-core/src/main/java/org/sonar/core/util/logs/NullProfiler.java
index 7f3490b530e..7068d25afe9 100644
--- a/sonar-core/src/main/java/org/sonar/core/util/logs/NullProfiler.java
+++ b/sonar-core/src/main/java/org/sonar/core/util/logs/NullProfiler.java
@@ -128,4 +128,9 @@ class NullProfiler extends Profiler {
// nothing to do
return this;
}
+
+ @Override
+ public Profiler logTimeLast(boolean flag) {
+ return this;
+ }
}
diff --git a/sonar-core/src/main/java/org/sonar/core/util/logs/Profiler.java b/sonar-core/src/main/java/org/sonar/core/util/logs/Profiler.java
index 6b39185b56e..859d1fa40f3 100644
--- a/sonar-core/src/main/java/org/sonar/core/util/logs/Profiler.java
+++ b/sonar-core/src/main/java/org/sonar/core/util/logs/Profiler.java
@@ -91,4 +91,10 @@ public abstract class Profiler {
* Context information is removed if value is <code>null</code>.
*/
public abstract Profiler addContext(String key, @Nullable Object value);
+
+ /**
+ * Defines whether time is added to stop messages before or after context (if any).
+ * <p>{@code flag} is {@code false} by default.</p>
+ */
+ public abstract Profiler logTimeLast(boolean flag);
}
diff --git a/sonar-core/src/test/java/org/sonar/core/util/logs/DefaultProfilerTest.java b/sonar-core/src/test/java/org/sonar/core/util/logs/DefaultProfilerTest.java
index 2e230fefc43..796095bc39b 100644
--- a/sonar-core/src/test/java/org/sonar/core/util/logs/DefaultProfilerTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/util/logs/DefaultProfilerTest.java
@@ -19,8 +19,13 @@
*/
package org.sonar.core.util.logs;
+import com.tngtech.java.junit.dataprovider.DataProvider;
+import com.tngtech.java.junit.dataprovider.DataProviderRunner;
+import com.tngtech.java.junit.dataprovider.UseDataProvider;
+import java.util.List;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.sonar.api.utils.log.LogTester;
import org.sonar.api.utils.log.LoggerLevel;
import org.sonar.api.utils.log.Loggers;
@@ -28,6 +33,7 @@ import org.sonar.api.utils.log.Loggers;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
+@RunWith(DataProviderRunner.class)
public class DefaultProfilerTest {
@Rule
@@ -35,6 +41,14 @@ public class DefaultProfilerTest {
Profiler underTest = Profiler.create(Loggers.get("DefaultProfilerTest"));
+ @DataProvider
+ public static Object[][] logTimeLastValues() {
+ return new Object[][] {
+ {true},
+ {false}
+ };
+ }
+
@Test
public void test_levels() throws Exception {
// info by default
@@ -51,7 +65,9 @@ public class DefaultProfilerTest {
}
@Test
- public void stop_reuses_start_message() throws InterruptedException {
+ @UseDataProvider("logTimeLastValues")
+ public void stop_reuses_start_message(boolean logTimeLast) throws InterruptedException {
+ underTest.logTimeLast(logTimeLast);
tester.setLevel(LoggerLevel.TRACE);
// trace
@@ -85,7 +101,9 @@ public class DefaultProfilerTest {
}
@Test
- public void different_start_and_stop_messages() {
+ @UseDataProvider("logTimeLastValues")
+ public void different_start_and_stop_messages(boolean logTimeLast) {
+ underTest.logTimeLast(logTimeLast);
tester.setLevel(LoggerLevel.TRACE);
// start TRACE and stop DEBUG
@@ -113,7 +131,9 @@ public class DefaultProfilerTest {
}
@Test
- public void log_on_at_stop() {
+ @UseDataProvider("logTimeLastValues")
+ public void log_on_at_stop(boolean logTimeLast) {
+ underTest.logTimeLast(logTimeLast);
tester.setLevel(LoggerLevel.TRACE);
// trace
@@ -138,27 +158,178 @@ public class DefaultProfilerTest {
}
@Test
- public void add_context() {
- org.sonar.core.util.logs.Profiler profiler = Profiler.create(Loggers.get("DefaultProfilerTest"));
- profiler.addContext("a_string", "bar");
- profiler.addContext("null_value", null);
- profiler.addContext("an_int", 42);
- profiler.start();
+ public void start_writes_no_log_even_if_there_is_context() {
+ underTest.addContext("a_string", "bar");
+ underTest.addContext("null_value", null);
+ underTest.addContext("an_int", 42);
+ underTest.start();
+
// do not write context as there's no message
assertThat(tester.logs()).isEmpty();
+ }
+
+ @Test
+ public void startInfo_writes_log_with_context_appended_when_there_is_a_message() {
+ addSomeContext(underTest);
+ underTest.startInfo("Foo");
+
+ assertThat(tester.logs(LoggerLevel.INFO)).containsOnly("Foo | a_string=bar | an_int=42 | after_start=true");
+ }
+
+ @Test
+ public void startDebug_writes_log_with_context_appended_when_there_is_a_message() {
+ tester.setLevel(LoggerLevel.DEBUG);
+ addSomeContext(underTest);
+ underTest.startDebug("Foo");
+
+ assertThat(tester.logs(LoggerLevel.DEBUG)).containsOnly("Foo | a_string=bar | an_int=42 | after_start=true");
+ }
+
+ @Test
+ public void startTrace_writes_log_with_context_appended_when_there_is_a_message() {
+ tester.setLevel(LoggerLevel.TRACE);
+ addSomeContext(underTest);
+ underTest.startTrace("Foo");
+
+ assertThat(tester.logs(LoggerLevel.TRACE)).containsOnly("Foo | a_string=bar | an_int=42 | after_start=true");
+ }
+
+ @Test
+ public void stopError_adds_context_after_time_by_default() {
+ addSomeContext(underTest);
+ underTest.start().stopError("Rules registered");
+
+ assertThat(tester.logs()).hasSize(1);
+ assertThat(tester.logs(LoggerLevel.ERROR).get(0))
+ .startsWith("Rules registered | time=")
+ .endsWith("ms | a_string=bar | an_int=42 | after_start=true");
+ }
+
+ @Test
+ public void stopInfo_adds_context_after_time_by_default() {
+ addSomeContext(underTest);
+ underTest.start().stopInfo("Rules registered");
+
+ assertThat(tester.logs()).hasSize(1);
+ assertThat(tester.logs(LoggerLevel.INFO).get(0))
+ .startsWith("Rules registered | time=")
+ .endsWith("ms | a_string=bar | an_int=42 | after_start=true");
+ }
+
+ @Test
+ public void stopTrace_adds_context_after_time_by_default() {
+ tester.setLevel(LoggerLevel.TRACE);
+ addSomeContext(underTest);
+ underTest.start().stopTrace("Rules registered");
- profiler.addContext("after_start", true);
- profiler.stopInfo("Rules registered");
assertThat(tester.logs()).hasSize(1);
- assertThat(tester.logs().get(0))
+ assertThat(tester.logs(LoggerLevel.TRACE).get(0))
.startsWith("Rules registered | time=")
.endsWith("ms | a_string=bar | an_int=42 | after_start=true");
}
@Test
+ public void stopError_adds_context_before_time_if_logTimeLast_is_true() {
+ addSomeContext(underTest);
+ underTest.logTimeLast(true);
+ underTest.start().stopError("Rules registered");
+
+ assertThat(tester.logs()).hasSize(1);
+ assertThat(tester.logs(LoggerLevel.ERROR).get(0))
+ .startsWith("Rules registered | a_string=bar | an_int=42 | after_start=true | time=")
+ .endsWith("ms");
+ }
+
+ @Test
+ public void stopInfo_adds_context_before_time_if_logTimeLast_is_true() {
+ addSomeContext(underTest);
+ underTest.logTimeLast(true);
+ underTest.start().stopInfo("Rules registered");
+
+ assertThat(tester.logs()).hasSize(1);
+ assertThat(tester.logs(LoggerLevel.INFO).get(0))
+ .startsWith("Rules registered | a_string=bar | an_int=42 | after_start=true | time=")
+ .endsWith("ms");
+ }
+
+ @Test
+ public void stopTrace_adds_context_before_time_if_logTimeLast_is_true() {
+ tester.setLevel(LoggerLevel.TRACE);
+ addSomeContext(underTest);
+ underTest.logTimeLast(true);
+ underTest.start().stopTrace("Rules registered");
+
+ assertThat(tester.logs()).hasSize(1);
+ assertThat(tester.logs(LoggerLevel.TRACE).get(0))
+ .startsWith("Rules registered | a_string=bar | an_int=42 | after_start=true | time=")
+ .endsWith("ms");
+ }
+
+ @Test
+ public void stopInfo_clears_context() {
+ addSomeContext(underTest);
+ underTest.logTimeLast(true);
+ underTest.start().stopInfo("Foo");
+ underTest.start().stopInfo("Bar");
+
+ assertThat(tester.logs()).hasSize(2);
+ List<String> logs = tester.logs(LoggerLevel.INFO);
+ assertThat(logs.get(0))
+ .startsWith("Foo | a_string=bar | an_int=42 | after_start=true | time=")
+ .endsWith("ms");
+ assertThat(logs.get(1))
+ .startsWith("Bar | time=")
+ .endsWith("ms");
+ }
+
+ @Test
+ public void stopDebug_clears_context() {
+ tester.setLevel(LoggerLevel.DEBUG);
+ addSomeContext(underTest);
+ underTest.logTimeLast(true);
+ underTest.start().stopDebug("Foo");
+ underTest.start().stopDebug("Bar");
+
+ assertThat(tester.logs()).hasSize(2);
+ List<String> logs = tester.logs(LoggerLevel.DEBUG);
+ assertThat(logs.get(0))
+ .startsWith("Foo | a_string=bar | an_int=42 | after_start=true | time=")
+ .endsWith("ms");
+ assertThat(logs.get(1))
+ .startsWith("Bar | time=")
+ .endsWith("ms");
+ }
+
+ @Test
+ public void stopTrace_clears_context() {
+ tester.setLevel(LoggerLevel.TRACE);
+ addSomeContext(underTest);
+ underTest.logTimeLast(true);
+ underTest.start().stopTrace("Foo");
+ underTest.start().stopTrace("Bar");
+
+ assertThat(tester.logs()).hasSize(2);
+ List<String> logs = tester.logs(LoggerLevel.TRACE);
+ assertThat(logs.get(0))
+ .startsWith("Foo | a_string=bar | an_int=42 | after_start=true | time=")
+ .endsWith("ms");
+ assertThat(logs.get(1))
+ .startsWith("Bar | time=")
+ .endsWith("ms");
+ }
+
+ private static void addSomeContext(Profiler profiler) {
+ profiler.addContext("a_string", "bar");
+ profiler.addContext("null_value", null);
+ profiler.addContext("an_int", 42);
+ profiler.addContext("after_start", true);
+ }
+
+ @Test
public void empty_message() {
underTest.addContext("foo", "bar");
underTest.startInfo("");
+
assertThat(tester.logs()).containsOnly("foo=bar");
underTest.addContext("after_start", true);
diff --git a/sonar-core/src/test/java/org/sonar/core/util/logs/NullProfilerTest.java b/sonar-core/src/test/java/org/sonar/core/util/logs/NullProfilerTest.java
index f2c1985bddd..6bcc79895ff 100644
--- a/sonar-core/src/test/java/org/sonar/core/util/logs/NullProfilerTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/util/logs/NullProfilerTest.java
@@ -37,6 +37,8 @@ public class NullProfilerTest {
assertThat(underTest.isDebugEnabled()).isFalse();
assertThat(underTest.isTraceEnabled()).isFalse();
assertThat(underTest.addContext("foo", "bar")).isSameAs(underTest);
+ assertThat(underTest.logTimeLast(true)).isSameAs(underTest);
+ assertThat(underTest.logTimeLast(false)).isSameAs(underTest);
}
@Test