aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-process-monitor/src/main/java/org/sonar/process/monitor/StreamGobbler.java20
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/LogbackHelper.java106
-rw-r--r--server/sonar-search/src/main/java/org/sonar/search/SearchLogging.java4
-rw-r--r--server/sonar-search/src/test/java/org/sonar/search/SearchLoggingTest.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/app/ServerProcessLogging.java9
-rw-r--r--server/sonar-server/src/test/java/org/sonar/ce/log/CeProcessLoggingTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/app/WebServerProcessLoggingTest.java2
-rw-r--r--sonar-application/src/main/java/org/sonar/application/AppLogging.java7
-rw-r--r--sonar-application/src/test/java/org/sonar/application/AppLoggingTest.java17
9 files changed, 137 insertions, 32 deletions
diff --git a/server/sonar-process-monitor/src/main/java/org/sonar/process/monitor/StreamGobbler.java b/server/sonar-process-monitor/src/main/java/org/sonar/process/monitor/StreamGobbler.java
index 6020f255e36..52a43e170d1 100644
--- a/server/sonar-process-monitor/src/main/java/org/sonar/process/monitor/StreamGobbler.java
+++ b/server/sonar-process-monitor/src/main/java/org/sonar/process/monitor/StreamGobbler.java
@@ -19,27 +19,26 @@
*/
package org.sonar.process.monitor;
-import org.apache.commons.io.IOUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.annotation.Nullable;
-
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
+import javax.annotation.Nullable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Reads process output and writes to logs
*/
-class StreamGobbler extends Thread {
+public class StreamGobbler extends Thread {
+
+ public static final String LOGGER_GOBBLER = "gobbler";
private final InputStream is;
private final Logger logger;
StreamGobbler(InputStream is, String processKey) {
- this(is, processKey, LoggerFactory.getLogger("gobbler"));
+ this(is, processKey, LoggerFactory.getLogger(LOGGER_GOBBLER));
}
StreamGobbler(InputStream is, String processKey, Logger logger) {
@@ -50,16 +49,13 @@ class StreamGobbler extends Thread {
@Override
public void run() {
- BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
- try {
+ try (BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
String line;
while ((line = br.readLine()) != null) {
logger.info(line);
}
} catch (Exception ignored) {
// ignored
- } finally {
- IOUtils.closeQuietly(br);
}
}
diff --git a/server/sonar-process/src/main/java/org/sonar/process/LogbackHelper.java b/server/sonar-process/src/main/java/org/sonar/process/LogbackHelper.java
index 8b7c8bf5150..d4496f747c1 100644
--- a/server/sonar-process/src/main/java/org/sonar/process/LogbackHelper.java
+++ b/server/sonar-process/src/main/java/org/sonar/process/LogbackHelper.java
@@ -37,9 +37,12 @@ import ch.qos.logback.core.rolling.RollingFileAppender;
import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy;
import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
import java.io.File;
+import javax.annotation.CheckForNull;
import org.apache.commons.lang.StringUtils;
import org.slf4j.LoggerFactory;
+import static java.util.Objects.requireNonNull;
+
/**
* Helps to configure Logback in a programmatic way, without using XML.
*/
@@ -47,8 +50,9 @@ public class LogbackHelper {
public static final String ROLLING_POLICY_PROPERTY = "sonar.log.rollingPolicy";
public static final String MAX_FILES_PROPERTY = "sonar.log.maxFiles";
+ private static final String PROCESS_NAME_PLACEHOLDER = "XXXX";
private static final String THREAD_ID_PLACEHOLDER = "ZZZZ";
- private static final String LOG_FORMAT = "%d{yyyy.MM.dd HH:mm:ss} %-5level [" + THREAD_ID_PLACEHOLDER + "][%logger{20}] %msg%n";
+ private static final String LOG_FORMAT = "%d{yyyy.MM.dd HH:mm:ss} %-5level " + PROCESS_NAME_PLACEHOLDER + "[" + THREAD_ID_PLACEHOLDER + "][%logger{20}] %msg%n";
public LoggerContext getRootContext() {
org.slf4j.Logger logger;
@@ -76,10 +80,99 @@ public class LogbackHelper {
return propagator;
}
- public void configureRootLogger(LoggerContext ctx, Props props, String threadIdFieldPattern, String fileName) {
- String logFormat = LOG_FORMAT.replace(THREAD_ID_PLACEHOLDER, threadIdFieldPattern);
+ public static final class RootLoggerConfig {
+ private final String processName;
+ private final String threadIdFieldPattern;
+ private final String fileName;
+ private final boolean detachConsole;
+
+ public RootLoggerConfig(Builder builder) {
+ this.processName = builder.processName;
+ this.threadIdFieldPattern = builder.threadIdFieldPattern;
+ this.fileName = builder.fileName;
+ this.detachConsole = builder.detachConsole;
+ }
+
+ public static Builder newRootLoggerConfigBuilder() {
+ return new Builder();
+ }
+
+ public String getProcessName() {
+ return processName;
+ }
+
+ public String getThreadIdFieldPattern() {
+ return threadIdFieldPattern;
+ }
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public boolean isDetachConsole() {
+ return detachConsole;
+ }
+
+ public static final class Builder {
+ @CheckForNull
+ public String processName;
+ private String threadIdFieldPattern = "";
+ @CheckForNull
+ private String fileName;
+ private boolean detachConsole = true;
+
+ private Builder() {
+ // prevents instantiation outside RootLoggerConfig, use static factory method
+ }
+
+ public Builder setProcessName(String processName) {
+ checkProcessName(processName);
+ this.processName = processName;
+ return this;
+ }
+
+ public Builder setThreadIdFieldPattern(String threadIdFieldPattern) {
+ this.threadIdFieldPattern = requireNonNull(threadIdFieldPattern, "threadIdFieldPattern can't be null");
+ return this;
+ }
+
+ public Builder setFileName(String fileName) {
+ checkFileName(fileName);
+ this.fileName = fileName;
+ return this;
+ }
+
+ private static void checkFileName(String fileName) {
+ if (requireNonNull(fileName, "fileName can't be null").isEmpty()) {
+ throw new IllegalArgumentException("fileName can't be empty");
+ }
+ }
+
+ private static void checkProcessName(String fileName) {
+ if (requireNonNull(fileName, "processName can't be null").isEmpty()) {
+ throw new IllegalArgumentException("processName can't be empty");
+ }
+ }
+
+ public Builder setDetachConsole(boolean detachConsole) {
+ this.detachConsole = detachConsole;
+ return this;
+ }
+
+ public RootLoggerConfig build() {
+ checkProcessName(this.processName);
+ checkFileName(this.fileName);
+ return new RootLoggerConfig(this);
+ }
+ }
+ }
+
+ public void configureRootLogger(LoggerContext ctx, Props props, RootLoggerConfig config) {
+ String logFormat = LOG_FORMAT
+ .replace(PROCESS_NAME_PLACEHOLDER, config.getProcessName())
+ .replace(THREAD_ID_PLACEHOLDER, config.getThreadIdFieldPattern());
// configure appender
- LogbackHelper.RollingPolicy rollingPolicy = createRollingPolicy(ctx, props, fileName);
+ LogbackHelper.RollingPolicy rollingPolicy = createRollingPolicy(ctx, props, config.getFileName());
FileAppender<ILoggingEvent> fileAppender = rollingPolicy.createAppender("file");
fileAppender.setContext(ctx);
PatternLayoutEncoder fileEncoder = new PatternLayoutEncoder();
@@ -92,7 +185,10 @@ public class LogbackHelper {
// configure logger
Logger rootLogger = ctx.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
rootLogger.addAppender(fileAppender);
- rootLogger.detachAppender("console");
+// if (config.isDetachConsole()) {
+// rootLogger.detachAppender("console");
+// }
+ rootLogger.addAppender(newConsoleAppender(ctx, "console", logFormat));
}
public ConsoleAppender newConsoleAppender(Context loggerContext, String name, String pattern, Filter... filters) {
diff --git a/server/sonar-search/src/main/java/org/sonar/search/SearchLogging.java b/server/sonar-search/src/main/java/org/sonar/search/SearchLogging.java
index 174733eb097..4667d67f051 100644
--- a/server/sonar-search/src/main/java/org/sonar/search/SearchLogging.java
+++ b/server/sonar-search/src/main/java/org/sonar/search/SearchLogging.java
@@ -23,6 +23,8 @@ import ch.qos.logback.classic.LoggerContext;
import org.sonar.process.LogbackHelper;
import org.sonar.process.Props;
+import static org.sonar.process.LogbackHelper.RootLoggerConfig.newRootLoggerConfigBuilder;
+
public class SearchLogging {
private LogbackHelper helper = new LogbackHelper();
@@ -31,7 +33,7 @@ public class SearchLogging {
LoggerContext ctx = helper.getRootContext();
ctx.reset();
- helper.configureRootLogger(ctx, props, "", "es");
+ helper.configureRootLogger(ctx, props, newRootLoggerConfigBuilder().setProcessName("es").setFileName("es").build());
return ctx;
}
diff --git a/server/sonar-search/src/test/java/org/sonar/search/SearchLoggingTest.java b/server/sonar-search/src/test/java/org/sonar/search/SearchLoggingTest.java
index dde89d32d45..ab229e74a76 100644
--- a/server/sonar-search/src/test/java/org/sonar/search/SearchLoggingTest.java
+++ b/server/sonar-search/src/test/java/org/sonar/search/SearchLoggingTest.java
@@ -79,6 +79,6 @@ public class SearchLoggingTest {
assertThat(fileAppender.getFile()).isEqualTo(new File(logDir, "es.log").getAbsolutePath());
assertThat(fileAppender.getEncoder()).isInstanceOf(PatternLayoutEncoder.class);
PatternLayoutEncoder encoder = (PatternLayoutEncoder) fileAppender.getEncoder();
- assertThat(encoder.getPattern()).isEqualTo("%d{yyyy.MM.dd HH:mm:ss} %-5level [][%logger{20}] %msg%n");
+ assertThat(encoder.getPattern()).isEqualTo("%d{yyyy.MM.dd HH:mm:ss} %-5level es[][%logger{20}] %msg%n");
}
}
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 50feea704f6..72aea06c92a 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
@@ -28,6 +28,8 @@ import org.sonar.process.LogbackHelper;
import org.sonar.process.Props;
import org.sonar.server.platform.ServerLogging;
+import static org.sonar.process.LogbackHelper.RootLoggerConfig.newRootLoggerConfigBuilder;
+
public abstract class ServerProcessLogging {
private static final String LOG_LEVEL_PROPERTY = "sonar.log.level";
private final String processName;
@@ -44,7 +46,12 @@ public abstract class ServerProcessLogging {
ctx.reset();
helper.enableJulChangePropagation(ctx);
- helper.configureRootLogger(ctx, props, threadIdFieldPattern, processName);
+ helper.configureRootLogger(ctx, props,
+ newRootLoggerConfigBuilder()
+ .setProcessName(processName)
+ .setThreadIdFieldPattern(threadIdFieldPattern)
+ .setFileName(processName)
+ .build());
configureLevels(props);
// Configure java.util.logging, used by Tomcat, in order to forward to slf4j
diff --git a/server/sonar-server/src/test/java/org/sonar/ce/log/CeProcessLoggingTest.java b/server/sonar-server/src/test/java/org/sonar/ce/log/CeProcessLoggingTest.java
index fa94f15e1b1..b2e39b3e5d8 100644
--- a/server/sonar-server/src/test/java/org/sonar/ce/log/CeProcessLoggingTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/ce/log/CeProcessLoggingTest.java
@@ -83,7 +83,7 @@ public class CeProcessLoggingTest {
assertThat(fileAppender.getFile()).isEqualTo(new File(logDir, "ce.log").getAbsolutePath());
assertThat(fileAppender.getEncoder()).isInstanceOf(PatternLayoutEncoder.class);
PatternLayoutEncoder encoder = (PatternLayoutEncoder) fileAppender.getEncoder();
- assertThat(encoder.getPattern()).isEqualTo("%d{yyyy.MM.dd HH:mm:ss} %-5level [%X{ceTaskUuid}][%logger{20}] %msg%n");
+ assertThat(encoder.getPattern()).isEqualTo("%d{yyyy.MM.dd HH:mm:ss} %-5level ce[%X{ceTaskUuid}][%logger{20}] %msg%n");
}
@Test
diff --git a/server/sonar-server/src/test/java/org/sonar/server/app/WebServerProcessLoggingTest.java b/server/sonar-server/src/test/java/org/sonar/server/app/WebServerProcessLoggingTest.java
index 9c9e60e6d34..170ea8b6c11 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/app/WebServerProcessLoggingTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/app/WebServerProcessLoggingTest.java
@@ -83,7 +83,7 @@ public class WebServerProcessLoggingTest {
assertThat(fileAppender.getFile()).isEqualTo(new File(logDir, "web.log").getAbsolutePath());
assertThat(fileAppender.getEncoder()).isInstanceOf(PatternLayoutEncoder.class);
PatternLayoutEncoder encoder = (PatternLayoutEncoder) fileAppender.getEncoder();
- assertThat(encoder.getPattern()).isEqualTo("%d{yyyy.MM.dd HH:mm:ss} %-5level [%X{UID}][%logger{20}] %msg%n");
+ assertThat(encoder.getPattern()).isEqualTo("%d{yyyy.MM.dd HH:mm:ss} %-5level web[%X{UID}][%logger{20}] %msg%n");
}
@Test
diff --git a/sonar-application/src/main/java/org/sonar/application/AppLogging.java b/sonar-application/src/main/java/org/sonar/application/AppLogging.java
index 12cad324f57..4395f19e7fa 100644
--- a/sonar-application/src/main/java/org/sonar/application/AppLogging.java
+++ b/sonar-application/src/main/java/org/sonar/application/AppLogging.java
@@ -31,6 +31,8 @@ import org.slf4j.LoggerFactory;
import org.sonar.process.LogbackHelper;
import org.sonar.process.Props;
+import static org.sonar.process.monitor.StreamGobbler.LOGGER_GOBBLER;
+
/**
* Configure logback for the master process
*/
@@ -38,7 +40,6 @@ class AppLogging {
static final String CONSOLE_LOGGER = "console";
static final String CONSOLE_APPENDER = "CONSOLE";
- static final String GOBBLER_LOGGER = "gobbler";
static final String GOBBLER_APPENDER = "GOBBLER";
static final String APP_PATTERN = "%d{yyyy.MM.dd HH:mm:ss} %-5level app[][%logger{20}] %msg%n";
@@ -65,7 +66,7 @@ class AppLogging {
Logger consoleLogger = (Logger) LoggerFactory.getLogger(CONSOLE_LOGGER);
Appender<ILoggingEvent> consoleAppender = consoleLogger.getAppender(CONSOLE_APPENDER);
- Logger gobblerLogger = (Logger) LoggerFactory.getLogger(GOBBLER_LOGGER);
+ Logger gobblerLogger = (Logger) LoggerFactory.getLogger(LOGGER_GOBBLER);
gobblerLogger.addAppender(consoleAppender);
}
@@ -89,7 +90,7 @@ class AppLogging {
fileAppender.start();
// configure logger
- Logger gobblerLogger = ctx.getLogger(GOBBLER_LOGGER);
+ Logger gobblerLogger = ctx.getLogger(LOGGER_GOBBLER);
gobblerLogger.setAdditive(false);
gobblerLogger.addAppender(fileAppender);
}
diff --git a/sonar-application/src/test/java/org/sonar/application/AppLoggingTest.java b/sonar-application/src/test/java/org/sonar/application/AppLoggingTest.java
index 202ccf47b20..4465bcb0664 100644
--- a/sonar-application/src/test/java/org/sonar/application/AppLoggingTest.java
+++ b/sonar-application/src/test/java/org/sonar/application/AppLoggingTest.java
@@ -38,19 +38,22 @@ import org.sonar.process.ProcessProperties;
import org.sonar.process.Props;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.process.monitor.StreamGobbler.LOGGER_GOBBLER;
public class AppLoggingTest {
@Rule
public TemporaryFolder temp = new TemporaryFolder();
- Props props = new Props(new Properties());
- AppLogging underTest = new AppLogging();
+ private File logDir;
+
+ private Props props = new Props(new Properties());
+ private AppLogging underTest = new AppLogging();
@Before
public void setUp() throws Exception {
- File dir = temp.newFolder();
- props.set(ProcessProperties.PATH_LOGS, dir.getAbsolutePath());
+ logDir = temp.newFolder();
+ props.set(ProcessProperties.PATH_LOGS, logDir.getAbsolutePath());
}
@AfterClass
@@ -62,7 +65,7 @@ public class AppLoggingTest {
public void configure_defaults() {
LoggerContext ctx = underTest.configure(props);
- Logger gobbler = ctx.getLogger(AppLogging.GOBBLER_LOGGER);
+ Logger gobbler = ctx.getLogger(LOGGER_GOBBLER);
Appender<ILoggingEvent> appender = gobbler.getAppender(AppLogging.GOBBLER_APPENDER);
assertThat(appender).isInstanceOf(RollingFileAppender.class);
@@ -77,7 +80,7 @@ public class AppLoggingTest {
LoggerContext ctx = underTest.configure(props);
- Logger gobbler = ctx.getLogger(AppLogging.GOBBLER_LOGGER);
+ Logger gobbler = ctx.getLogger(LOGGER_GOBBLER);
Appender<ILoggingEvent> appender = gobbler.getAppender(AppLogging.GOBBLER_APPENDER);
assertThat(appender).isNotInstanceOf(RollingFileAppender.class).isInstanceOf(FileAppender.class);
}
@@ -87,7 +90,7 @@ public class AppLoggingTest {
props.set("sonar.log.console", "true");
LoggerContext ctx = underTest.configure(props);
- Logger gobbler = ctx.getLogger(AppLogging.GOBBLER_LOGGER);
+ Logger gobbler = ctx.getLogger(LOGGER_GOBBLER);
assertThat(gobbler.getAppender(AppLogging.GOBBLER_APPENDER)).isNotNull();
assertThat(gobbler.getAppender(AppLogging.CONSOLE_APPENDER)).isNotNull();
}