From 28ae34bded6c22fabbcbabbd3fb49b923cf02dac Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Tue, 6 Oct 2015 19:00:47 +0200 Subject: [PATCH] SONAR-6904 add log level to system info --- .../server/app/ServerProcessLogging.java | 10 +++---- .../sonar/server/platform/ServerLogging.java | 16 +++++++---- .../platform/monitoring/SonarQubeMonitor.java | 18 ++++++++---- .../monitoring/SonarQubeMonitorMBean.java | 2 ++ .../platform/ws/ChangeLogLevelAction.java | 6 ++-- .../server/platform/ServerLoggingTest.java | 15 ++++++++-- .../monitoring/SonarQubeMonitorTest.java | 28 +++++++++++++++---- .../platform/ws/ChangeLogLevelActionTest.java | 6 ++-- .../app/views/system/_monitor.html.erb | 21 ++++++++++++-- .../sonar/api/utils/log/ConsoleLogger.java | 8 ++++-- .../sonar/api/utils/log/LogbackLogger.java | 5 ++++ .../java/org/sonar/api/utils/log/Logger.java | 1 + 12 files changed, 103 insertions(+), 33 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/app/ServerProcessLogging.java b/server/sonar-server/src/main/java/org/sonar/server/app/ServerProcessLogging.java index 5579a02487a..2f591413dcb 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/app/ServerProcessLogging.java +++ b/server/sonar-server/src/main/java/org/sonar/server/app/ServerProcessLogging.java @@ -19,7 +19,6 @@ */ package org.sonar.server.app; -import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.LoggerContext; import ch.qos.logback.classic.spi.ILoggingEvent; @@ -27,6 +26,7 @@ import ch.qos.logback.core.ConsoleAppender; import java.util.logging.LogManager; import org.slf4j.bridge.SLF4JBridgeHandler; import org.sonar.api.utils.MessageException; +import org.sonar.api.utils.log.LoggerLevel; import org.sonar.process.LogbackHelper; import org.sonar.process.Props; import org.sonar.server.computation.log.CeLogDenyFilter; @@ -67,13 +67,13 @@ class ServerProcessLogging { private void configureLevels(Props props) { String levelCode = props.value(LOG_LEVEL_PROPERTY, "INFO"); - Level level; + LoggerLevel level; if ("TRACE".equals(levelCode)) { - level = Level.TRACE; + level = LoggerLevel.TRACE; } else if ("DEBUG".equals(levelCode)) { - level = Level.DEBUG; + level = LoggerLevel.DEBUG; } else if ("INFO".equals(levelCode)) { - level = Level.INFO; + level = LoggerLevel.INFO; } else { throw MessageException.of(String.format("Unsupported log level: %s. Please check property %s", levelCode, LOG_LEVEL_PROPERTY)); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerLogging.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerLogging.java index e79c1024c8e..0fce6d76606 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerLogging.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerLogging.java @@ -22,19 +22,21 @@ package org.sonar.server.platform; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; import java.io.File; import java.util.Set; import org.slf4j.LoggerFactory; import org.sonar.api.config.Settings; import org.sonar.api.server.ServerSide; +import org.sonar.api.utils.log.LoggerLevel; +import org.sonar.api.utils.log.Loggers; import org.sonar.process.LogbackHelper; import org.sonar.process.ProcessProperties; @ServerSide public class ServerLogging { - public static final Set ALLOWED_ROOT_LOG_LEVELS = ImmutableSet.of(Level.TRACE, Level.DEBUG, Level.INFO); + public static final Set ALLOWED_ROOT_LOG_LEVELS = Sets.immutableEnumSet(LoggerLevel.TRACE, LoggerLevel.DEBUG, LoggerLevel.INFO); private final LogbackHelper helper = new LogbackHelper(); private final Settings settings; @@ -43,14 +45,18 @@ public class ServerLogging { this.settings = settings; } - public void changeLevel(Level level) { + public void changeLevel(LoggerLevel level) { configureLevels(helper, level); LoggerFactory.getLogger(ServerLogging.class).info("Level of logs changed to {}", level); } - public static void configureLevels(LogbackHelper helper, Level level) { + public LoggerLevel getRootLoggerLevel() { + return Loggers.get(Logger.ROOT_LOGGER_NAME).getLevel(); + } + + public static void configureLevels(LogbackHelper helper, LoggerLevel level) { Preconditions.checkArgument(ALLOWED_ROOT_LOG_LEVELS.contains(level), "%s log level is not supported (allowed levels are %s)", level, ALLOWED_ROOT_LOG_LEVELS); - helper.configureLogger(Logger.ROOT_LOGGER_NAME, level); + helper.configureLogger(Logger.ROOT_LOGGER_NAME, Level.toLevel(level.name())); helper.configureLogger("rails", Level.WARN); helper.configureLogger("org.apache.ibatis", Level.WARN); helper.configureLogger("java.sql", Level.WARN); diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/SonarQubeMonitor.java b/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/SonarQubeMonitor.java index 0f99dbac195..bfab886ecc2 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/SonarQubeMonitor.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/SonarQubeMonitor.java @@ -20,16 +20,16 @@ package org.sonar.server.platform.monitoring; +import java.io.File; +import java.util.LinkedHashMap; import org.sonar.api.CoreProperties; import org.sonar.api.config.Settings; import org.sonar.api.platform.Server; import org.sonar.api.security.SecurityRealm; import org.sonar.process.ProcessProperties; +import org.sonar.server.platform.ServerLogging; import org.sonar.server.user.SecurityRealmFactory; -import java.io.File; -import java.util.LinkedHashMap; - public class SonarQubeMonitor extends BaseMonitorMBean implements SonarQubeMonitorMBean { static final String BRANDING_FILE_PATH = "web/WEB-INF/classes/com/sonarsource/branding"; @@ -37,12 +37,14 @@ public class SonarQubeMonitor extends BaseMonitorMBean implements SonarQubeMonit private final Settings settings; private final SecurityRealmFactory securityRealmFactory; private final Server server; + private final ServerLogging serverLogging; public SonarQubeMonitor(Settings settings, SecurityRealmFactory securityRealmFactory, - Server server) { + Server server, ServerLogging serverLogging) { this.settings = settings; this.securityRealmFactory = securityRealmFactory; this.server = server; + this.serverLogging = serverLogging; } @Override @@ -55,6 +57,11 @@ public class SonarQubeMonitor extends BaseMonitorMBean implements SonarQubeMonit return server.getVersion(); } + @Override + public String getLogLevel() { + return serverLogging.getRootLoggerLevel().name(); + } + public String getExternalUserAuthentication() { SecurityRealm realm = securityRealmFactory.getRealm(); if (realm == null) { @@ -100,8 +107,9 @@ public class SonarQubeMonitor extends BaseMonitorMBean implements SonarQubeMonit attributes.put("Official Distribution", isOfficialDistribution()); attributes.put("Home Dir", settings.getString(ProcessProperties.PATH_HOME)); attributes.put("Data Dir", settings.getString(ProcessProperties.PATH_DATA)); - attributes.put("Logs Dir", settings.getString(ProcessProperties.PATH_LOGS)); attributes.put("Temp Dir", settings.getString(ProcessProperties.PATH_TEMP)); + attributes.put("Logs Dir", settings.getString(ProcessProperties.PATH_LOGS)); + attributes.put("Logs Level", getLogLevel()); return attributes; } diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/SonarQubeMonitorMBean.java b/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/SonarQubeMonitorMBean.java index 7c010b4403a..bd2a13d1b13 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/SonarQubeMonitorMBean.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/SonarQubeMonitorMBean.java @@ -24,4 +24,6 @@ public interface SonarQubeMonitorMBean { String getServerId(); String getVersion(); + + String getLogLevel(); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/ChangeLogLevelAction.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/ChangeLogLevelAction.java index f024ed1bcd7..00bfc9c768e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/ChangeLogLevelAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/ChangeLogLevelAction.java @@ -19,10 +19,10 @@ */ package org.sonar.server.platform.ws; -import ch.qos.logback.classic.Level; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; +import org.sonar.api.utils.log.LoggerLevel; import org.sonar.api.web.UserRole; import org.sonar.db.Database; import org.sonar.server.platform.ServerLogging; @@ -59,8 +59,8 @@ public class ChangeLogLevelAction implements SystemWsAction { @Override public void handle(Request wsRequest, Response wsResponse) { userSession.checkGlobalPermission(UserRole.ADMIN); - Level level = Level.toLevel(wsRequest.mandatoryParam(PARAM_LEVEL)); - db.enableSqlLogging(level.equals(Level.TRACE)); + LoggerLevel level = LoggerLevel.valueOf(wsRequest.mandatoryParam(PARAM_LEVEL)); + db.enableSqlLogging(level.equals(LoggerLevel.TRACE)); logging.changeLevel(level); wsResponse.noContent(); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/ServerLoggingTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/ServerLoggingTest.java index 08ed7edee54..d23714f3474 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/platform/ServerLoggingTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/platform/ServerLoggingTest.java @@ -29,6 +29,8 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; import org.sonar.api.config.Settings; +import org.sonar.api.utils.log.LogTester; +import org.sonar.api.utils.log.LoggerLevel; import org.sonar.process.LogbackHelper; import org.sonar.process.ProcessProperties; @@ -47,6 +49,9 @@ public class ServerLoggingTest { Settings settings = new Settings(); ServerLogging underTest = new ServerLogging(settings); + @Rule + public LogTester logTester = new LogTester(); + @Test public void getLogsDir() throws IOException { File dir = temp.newFolder(); @@ -55,6 +60,12 @@ public class ServerLoggingTest { assertThat(underTest.getLogsDir()).isEqualTo(dir); } + @Test + public void getRootLoggerLevel() { + logTester.setLevel(LoggerLevel.TRACE); + assertThat(underTest.getRootLoggerLevel()).isEqualTo(LoggerLevel.TRACE); + } + @Test public void getCurrentLogFile() throws IOException { File dir = temp.newFolder(); @@ -68,7 +79,7 @@ public class ServerLoggingTest { @Test public void configureLevels() { LogbackHelper logbackHelper = mock(LogbackHelper.class); - ServerLogging.configureLevels(logbackHelper, Level.TRACE); + ServerLogging.configureLevels(logbackHelper, LoggerLevel.TRACE); verify(logbackHelper).configureLogger(Logger.ROOT_LOGGER_NAME, Level.TRACE); verify(logbackHelper).configureLogger("java.sql", Level.WARN); @@ -80,6 +91,6 @@ public class ServerLoggingTest { expectedException.expectMessage("ERROR log level is not supported (allowed levels are [TRACE, DEBUG, INFO])"); LogbackHelper logbackHelper = mock(LogbackHelper.class); - ServerLogging.configureLevels(logbackHelper, Level.ERROR); + ServerLogging.configureLevels(logbackHelper, LoggerLevel.ERROR); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/monitoring/SonarQubeMonitorTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/monitoring/SonarQubeMonitorTest.java index e411ce656fa..df908e7c4aa 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/platform/monitoring/SonarQubeMonitorTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/platform/monitoring/SonarQubeMonitorTest.java @@ -19,18 +19,20 @@ */ package org.sonar.server.platform.monitoring; +import java.io.File; +import java.util.LinkedHashMap; import org.apache.commons.io.FileUtils; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.config.Settings; import org.sonar.api.platform.Server; import org.sonar.api.utils.DateUtils; +import org.sonar.api.utils.log.LoggerLevel; +import org.sonar.server.platform.ServerLogging; import org.sonar.server.user.SecurityRealmFactory; -import java.io.File; -import java.util.LinkedHashMap; - import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -42,11 +44,17 @@ public class SonarQubeMonitorTest { Settings settings = new Settings(); Server server = mock(Server.class); + ServerLogging serverLogging = mock(ServerLogging.class); + + @Before + public void setUp() throws Exception { + when(serverLogging.getRootLoggerLevel()).thenReturn(LoggerLevel.DEBUG); + } @Test public void getServerId() { when(server.getStartedAt()).thenReturn(DateUtils.parseDate("2015-01-01")); - SonarQubeMonitor monitor = new SonarQubeMonitor(settings, new SecurityRealmFactory(settings), server); + SonarQubeMonitor monitor = new SonarQubeMonitor(settings, new SecurityRealmFactory(settings), server, serverLogging); LinkedHashMap attributes = monitor.attributes(); assertThat(attributes).containsKeys("Server ID", "Version"); @@ -58,7 +66,7 @@ public class SonarQubeMonitorTest { FileUtils.write(new File(rootDir, SonarQubeMonitor.BRANDING_FILE_PATH), "1.2"); when(server.getRootDir()).thenReturn(rootDir); - SonarQubeMonitor monitor = new SonarQubeMonitor(settings, new SecurityRealmFactory(settings), server); + SonarQubeMonitor monitor = new SonarQubeMonitor(settings, new SecurityRealmFactory(settings), server, serverLogging); LinkedHashMap attributes = monitor.attributes(); assertThat(attributes).containsEntry("Official Distribution", Boolean.TRUE); @@ -69,9 +77,17 @@ public class SonarQubeMonitorTest { File rootDir = temp.newFolder(); // branding file is missing when(server.getRootDir()).thenReturn(rootDir); - SonarQubeMonitor monitor = new SonarQubeMonitor(settings, new SecurityRealmFactory(settings), server); + SonarQubeMonitor monitor = new SonarQubeMonitor(settings, new SecurityRealmFactory(settings), server, serverLogging); LinkedHashMap attributes = monitor.attributes(); assertThat(attributes).containsEntry("Official Distribution", Boolean.FALSE); } + + @Test + public void get_log_level() throws Exception { + SonarQubeMonitor monitor = new SonarQubeMonitor(settings, new SecurityRealmFactory(settings), server, serverLogging); + + LinkedHashMap attributes = monitor.attributes(); + assertThat(attributes).containsEntry("Logs Level", "DEBUG"); + } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/ChangeLogLevelActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/ChangeLogLevelActionTest.java index 21f72ce7db6..038f891b7d7 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/ChangeLogLevelActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/ChangeLogLevelActionTest.java @@ -19,10 +19,10 @@ */ package org.sonar.server.platform.ws; -import ch.qos.logback.classic.Level; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.sonar.api.utils.log.LoggerLevel; import org.sonar.api.web.UserRole; import org.sonar.db.Database; import org.sonar.server.exceptions.ForbiddenException; @@ -54,7 +54,7 @@ public class ChangeLogLevelActionTest { .setParam("level", "DEBUG") .setMethod("POST") .execute(); - verify(serverLogging).changeLevel(Level.DEBUG); + verify(serverLogging).changeLevel(LoggerLevel.DEBUG); verify(db).enableSqlLogging(false); } @@ -66,7 +66,7 @@ public class ChangeLogLevelActionTest { .setParam("level", "TRACE") .setMethod("POST") .execute(); - verify(serverLogging).changeLevel(Level.TRACE); + verify(serverLogging).changeLevel(LoggerLevel.TRACE); verify(db).enableSqlLogging(true); } diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/system/_monitor.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/system/_monitor.html.erb index 4d2c377723e..e85aa9cd627 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/system/_monitor.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/system/_monitor.html.erb @@ -23,9 +23,26 @@ <% end %> <% else %> - + "> <%= h attribute_key -%> - <%= h attribute_value -%> + + <% if attribute_key == 'Logs Level' %> + <% + message = '' + css_level = '' + if attribute_value=='TRACE' + css_level = 'alert_ERROR' + message = 'TRACE level has performance impacts, please make sure to get back to INFO level once your investigation is done.' + elsif attribute_value=='DEBUG' + css_level = 'alert_WARN' + message = 'DEBUG level may have performance impacts, please make sure to get back to INFO level once your investigation is done.' + end + %> + <%= h attribute_value -%> + <% else %> + <%= h attribute_value -%> + <% end %> + <% end %> 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 35757ebb256..d58401ed2fc 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 @@ -19,9 +19,8 @@ */ package org.sonar.api.utils.log; -import javax.annotation.Nullable; - import java.io.PrintStream; +import javax.annotation.Nullable; import static org.sonar.api.utils.log.ConsoleFormatter.format; @@ -181,6 +180,11 @@ class ConsoleLogger extends BaseLogger { return false; } + @Override + public LoggerLevel getLevel() { + return Loggers.getFactory().getLevel(); + } + 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/LogbackLogger.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogbackLogger.java index 9a35b5bcf33..8675a94c5e1 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 @@ -168,6 +168,11 @@ class LogbackLogger extends BaseLogger { return true; } + @Override + public LoggerLevel getLevel() { + return LoggerLevel.valueOf(logback.getEffectiveLevel().levelStr); + } + Logger logbackLogger() { return logback; } 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 9c8244bc1bb..4d5c3470f58 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 @@ -234,4 +234,5 @@ public interface Logger { */ boolean setLevel(LoggerLevel level); + LoggerLevel getLevel(); } -- 2.39.5