aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-plugin-api
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@sonarsource.com>2015-02-17 14:53:25 +0100
committerSimon Brandhof <simon.brandhof@sonarsource.com>2015-02-19 12:02:11 +0100
commit6adb553ddc2711cb88632be9bd96b4e91c51082e (patch)
treeac6c1d4fb0ed1d465b1764f01bec593e487a7094 /sonar-plugin-api
parent97fad28fd91b49710bd39217ad7f3929e0c2661e (diff)
downloadsonarqube-6adb553ddc2711cb88632be9bd96b4e91c51082e.tar.gz
sonarqube-6adb553ddc2711cb88632be9bd96b4e91c51082e.zip
SONAR-5700 ability to change level of loggers of 3rd-party libraries
Diffstat (limited to 'sonar-plugin-api')
-rw-r--r--sonar-plugin-api/pom.xml5
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ConsoleLogger.java7
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ConsoleLoggers.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogTester.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogbackLogger.java70
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogbackLoggers.java3
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/log/Logger.java64
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LoggerLevel.java24
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/utils/log/ConsoleLoggerTest.java5
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LogbackLoggerTest.java18
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/utils/log/NullInterceptorTest.java2
11 files changed, 170 insertions, 32 deletions
diff --git a/sonar-plugin-api/pom.xml b/sonar-plugin-api/pom.xml
index fef2a0bed26..3bb3de8f2e1 100644
--- a/sonar-plugin-api/pom.xml
+++ b/sonar-plugin-api/pom.xml
@@ -156,6 +156,11 @@
<optional>true</optional>
</dependency>
<dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-core</artifactId>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<optional>true</optional>
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ConsoleLogger.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ConsoleLogger.java
index 93af4ef8785..1dee60c11d6 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ConsoleLogger.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ConsoleLogger.java
@@ -35,7 +35,7 @@ class ConsoleLogger extends BaseLogger {
private final PrintStream stream;
- ConsoleLogger(String unusedName) {
+ ConsoleLogger() {
this.stream = System.out;
}
@@ -142,6 +142,11 @@ class ConsoleLogger extends BaseLogger {
thrown.printStackTrace();
}
+ @Override
+ public boolean setLevel(LoggerLevel level) {
+ return false;
+ }
+
private void log(String level, String msg) {
this.stream.println(String.format("%s %s", level, msg));
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ConsoleLoggers.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ConsoleLoggers.java
index a6a2f2524a0..726321e2956 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ConsoleLoggers.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ConsoleLoggers.java
@@ -25,7 +25,7 @@ class ConsoleLoggers extends Loggers {
@Override
protected Logger newInstance(String name) {
- return new ConsoleLogger(name);
+ return new ConsoleLogger();
}
@Override
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogTester.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogTester.java
index 9ee625e0c62..98ddc36cbf5 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogTester.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogTester.java
@@ -29,7 +29,7 @@ import java.util.List;
* This JUnit rule allows to configure and access logs in tests. By default
* debug logs are enabled.
* <p/>
- * Warning - not compatible with parallel execution of tests.
+ * Warning - not compatible with parallel execution of tests in the same JVM fork.
* <p/>
* Example:
* <pre>
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogbackLogger.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogbackLogger.java
index 7313a2fc2a5..7b42e877ac5 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogbackLogger.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogbackLogger.java
@@ -19,106 +19,132 @@
*/
package org.sonar.api.utils.log;
+import ch.qos.logback.classic.*;
+import ch.qos.logback.classic.Logger;
+
import javax.annotation.Nullable;
/**
- * Note that logback is accessed through SLF4J
+ * Logback is used in production.
*/
class LogbackLogger extends BaseLogger {
- private final transient org.slf4j.Logger slf4j;
+ private final transient ch.qos.logback.classic.Logger logback;
- LogbackLogger(org.slf4j.Logger slf4j) {
- this.slf4j = slf4j;
+ LogbackLogger(ch.qos.logback.classic.Logger logback) {
+ this.logback = logback;
}
@Override
public boolean isDebugEnabled() {
- return slf4j.isDebugEnabled();
+ return logback.isDebugEnabled();
}
@Override
protected void doDebug(String msg) {
- slf4j.debug(msg);
+ logback.debug(msg);
}
@Override
protected void doDebug(String msg, @Nullable Object arg) {
- slf4j.debug(msg, arg);
+ logback.debug(msg, arg);
}
@Override
protected void doDebug(String msg, @Nullable Object arg1, @Nullable Object arg2) {
- slf4j.debug(msg, arg1, arg2);
+ logback.debug(msg, arg1, arg2);
}
@Override
protected void doDebug(String msg, Object... args) {
- slf4j.debug(msg, args);
+ logback.debug(msg, args);
}
@Override
protected void doInfo(String msg) {
- slf4j.info(msg);
+ logback.info(msg);
}
@Override
protected void doInfo(String msg, @Nullable Object arg) {
- slf4j.info(msg, arg);
+ logback.info(msg, arg);
}
@Override
protected void doInfo(String msg, @Nullable Object arg1, @Nullable Object arg2) {
- slf4j.info(msg, arg1, arg2);
+ logback.info(msg, arg1, arg2);
}
@Override
protected void doInfo(String msg, Object... args) {
- slf4j.info(msg, args);
+ logback.info(msg, args);
}
@Override
protected void doWarn(String msg) {
- slf4j.warn(msg);
+ logback.warn(msg);
}
@Override
protected void doWarn(String msg, @Nullable Object arg) {
- slf4j.warn(msg, arg);
+ logback.warn(msg, arg);
}
@Override
protected void doWarn(String msg, @Nullable Object arg1, @Nullable Object arg2) {
- slf4j.warn(msg, arg1, arg2);
+ logback.warn(msg, arg1, arg2);
}
@Override
protected void doWarn(String msg, Object... args) {
- slf4j.warn(msg, args);
+ logback.warn(msg, args);
}
@Override
protected void doError(String msg) {
- slf4j.error(msg);
+ logback.error(msg);
}
@Override
protected void doError(String msg, @Nullable Object arg) {
- slf4j.error(msg, arg);
+ logback.error(msg, arg);
}
@Override
protected void doError(String msg, @Nullable Object arg1, @Nullable Object arg2) {
- slf4j.error(msg, arg1, arg2);
+ logback.error(msg, arg1, arg2);
}
@Override
protected void doError(String msg, Object... args) {
- slf4j.error(msg, args);
+ logback.error(msg, args);
}
@Override
protected void doError(String msg, Throwable thrown) {
- slf4j.error(msg, thrown);
+ logback.error(msg, thrown);
+ }
+
+ @Override
+ public boolean setLevel(LoggerLevel level) {
+ switch (level) {
+ case DEBUG:
+ logback.setLevel(Level.DEBUG);
+ break;
+ case INFO:
+ logback.setLevel(Level.INFO);
+ break;
+ case WARN:
+ logback.setLevel(Level.WARN);
+ break;
+ case ERROR:
+ logback.setLevel(Level.ERROR);
+ break;
+ }
+ return true;
+ }
+
+ Logger logbackLogger() {
+ return logback;
}
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogbackLoggers.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogbackLoggers.java
index e4490a79e3a..7d8ce45f94e 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogbackLoggers.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogbackLoggers.java
@@ -30,7 +30,8 @@ class LogbackLoggers extends Loggers {
@Override
protected Logger newInstance(String name) {
- return new LogbackLogger(LoggerFactory.getLogger(name));
+ // logback is accessed through SLF4J
+ return new LogbackLogger((ch.qos.logback.classic.Logger)LoggerFactory.getLogger(name));
}
@Override
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/Logger.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/Logger.java
index 834dc235661..d729a4b7f08 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/Logger.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/Logger.java
@@ -23,7 +23,7 @@ import javax.annotation.Nullable;
/**
* SonarQube plugins are not coupled with external logging libraries like SLF4J or Logback.
- *
+ * <p/>
* Example:
* <pre>
* public class MyClass {
@@ -35,7 +35,14 @@ import javax.annotation.Nullable;
* }
* }
* </pre>
+ * <p/>
+ * Message arguments are defined with <code>{}</code>, but not with {@link java.util.Formatter} syntax.
*
+ * <p/>
+ * INFO, WARN and ERROR levels are always enabled. They can't be disabled by users.
+ * DEBUG level can be enabled with properties <code>sonar.log.debug</code> (on server, see sonar.properties)
+ * and <code>sonar.verbose</code> (on batch)
+ * <p/>
* See {@link org.sonar.api.utils.log.LogTester} for testing facilities.
* @since 5.1
*/
@@ -44,15 +51,24 @@ public interface Logger {
boolean isDebugEnabled();
/**
- * Logs a DEBUG level message. Debug messages must
- * be valuable for production environments and are not for development debugging.
+ * Logs a DEBUG message. Debug messages must
+ * be valuable for diagnosing production problems. They must not be used for development debugging.
*/
void debug(String msg);
+ /**
+ * @see #debug(String)
+ */
void debug(String pattern, @Nullable Object arg);
+ /**
+ * @see #debug(String)
+ */
void debug(String msg, @Nullable Object arg1, @Nullable Object arg2);
+ /**
+ * @see #debug(String)
+ */
void debug(String msg, Object... args);
/**
@@ -60,10 +76,19 @@ public interface Logger {
*/
void info(String msg);
+ /**
+ * @see #info(String)
+ */
void info(String msg, @Nullable Object arg);
+ /**
+ * @see #info(String)
+ */
void info(String msg, @Nullable Object arg1, @Nullable Object arg2);
+ /**
+ * @see #info(String)
+ */
void info(String msg, Object... args);
/**
@@ -71,10 +96,19 @@ public interface Logger {
*/
void warn(String msg);
+ /**
+ * @see #warn(String)
+ */
void warn(String msg, @Nullable Object arg);
+ /**
+ * @see #warn(String)
+ */
void warn(String msg, @Nullable Object arg1, @Nullable Object arg2);
+ /**
+ * @see #warn(String)
+ */
void warn(String msg, Object... args);
/**
@@ -82,14 +116,36 @@ public interface Logger {
*/
void error(String msg);
+ /**
+ * @see #error(String)
+ */
void error(String msg, @Nullable Object arg);
+ /**
+ * @see #error(String)
+ */
void error(String msg, @Nullable Object arg1, @Nullable Object arg2);
+ /**
+ * @see #error(String)
+ */
void error(String msg, Object... args);
/**
- * Logs an ERROR level message.
+ * @see #error(String)
*/
void error(String msg, Throwable thrown);
+
+ /**
+ * Attempt to change logger level. Return true if it succeeded, false if
+ * the underlying logging facility does not allow to change level at
+ * runtime.
+ * <p/>
+ * This method must not be used to enable debug logs in tests. Use
+ * {@link org.sonar.api.utils.log.LogTester#enableDebug(boolean)}.
+ * <p/>
+ * The standard use-case is to customize logging of embedded 3rd-party
+ * libraries.
+ */
+ boolean setLevel(LoggerLevel level);
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LoggerLevel.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LoggerLevel.java
new file mode 100644
index 00000000000..5ff6fd27f54
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LoggerLevel.java
@@ -0,0 +1,24 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 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.api.utils.log;
+
+public enum LoggerLevel {
+ DEBUG, INFO, WARN, ERROR
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/ConsoleLoggerTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/ConsoleLoggerTest.java
index 68d4d02bac3..3f59d8d87e5 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/ConsoleLoggerTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/ConsoleLoggerTest.java
@@ -79,4 +79,9 @@ public class ConsoleLoggerTest {
sut.error("message", new IllegalArgumentException());
verify(stream, times(5)).println(startsWith("ERROR "));
}
+
+ @Test
+ public void level_change_not_implemented_yet() throws Exception {
+ assertThat(sut.setLevel(LoggerLevel.DEBUG)).isFalse();
+ }
}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LogbackLoggerTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LogbackLoggerTest.java
index 2c8c3680eb7..7bb3ff87068 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LogbackLoggerTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LogbackLoggerTest.java
@@ -19,6 +19,7 @@
*/
package org.sonar.api.utils.log;
+import ch.qos.logback.classic.Level;
import org.junit.Rule;
import org.junit.Test;
import org.slf4j.LoggerFactory;
@@ -27,7 +28,7 @@ import static org.assertj.core.api.Assertions.assertThat;
public class LogbackLoggerTest {
- LogbackLogger sut = new LogbackLogger(LoggerFactory.getLogger(getClass()));
+ LogbackLogger sut = new LogbackLogger((ch.qos.logback.classic.Logger)LoggerFactory.getLogger(getClass()));
@Rule
public LogTester tester = new LogTester();
@@ -64,6 +65,21 @@ public class LogbackLoggerTest {
sut.error("message {} {}", "foo", "bar");
sut.error("message {} {} {}", "foo", "bar", "baz");
sut.error("message", new IllegalArgumentException(""));
+ }
+
+ @Test
+ public void change_level() throws Exception {
+ assertThat(sut.setLevel(LoggerLevel.ERROR)).isTrue();
+ assertThat(sut.logbackLogger().getLevel()).isEqualTo(Level.ERROR);
+ assertThat(sut.setLevel(LoggerLevel.WARN)).isTrue();
+ assertThat(sut.logbackLogger().getLevel()).isEqualTo(Level.WARN);
+
+ assertThat(sut.setLevel(LoggerLevel.INFO)).isTrue();
+ assertThat(sut.logbackLogger().getLevel()).isEqualTo(Level.INFO);
+
+ assertThat(sut.setLevel(LoggerLevel.DEBUG)).isTrue();
+ assertThat(sut.logbackLogger().getLevel()).isEqualTo(Level.DEBUG);
+ assertThat(sut.isDebugEnabled()).isTrue();
}
}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/NullInterceptorTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/NullInterceptorTest.java
index d25d04d1dcd..ca4d14e4890 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/NullInterceptorTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/NullInterceptorTest.java
@@ -26,7 +26,7 @@ import static org.mockito.Mockito.mock;
public class NullInterceptorTest {
@Test
- public void do_nothing() throws Exception {
+ public void do_not_throws_exception() throws Exception {
// verify that... it does nothing
NullInterceptor.NULL_INSTANCE.log("foo");
NullInterceptor.NULL_INSTANCE.log("foo {}", 42);