diff options
author | Simon Brandhof <simon.brandhof@sonarsource.com> | 2015-02-17 14:53:25 +0100 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@sonarsource.com> | 2015-02-19 12:02:11 +0100 |
commit | 6adb553ddc2711cb88632be9bd96b4e91c51082e (patch) | |
tree | ac6c1d4fb0ed1d465b1764f01bec593e487a7094 /sonar-plugin-api | |
parent | 97fad28fd91b49710bd39217ad7f3929e0c2661e (diff) | |
download | sonarqube-6adb553ddc2711cb88632be9bd96b4e91c51082e.tar.gz sonarqube-6adb553ddc2711cb88632be9bd96b4e91c51082e.zip |
SONAR-5700 ability to change level of loggers of 3rd-party libraries
Diffstat (limited to 'sonar-plugin-api')
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); |