aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-process
diff options
context:
space:
mode:
authorJacek <jacek.poreda@sonarsource.com>2021-08-09 17:35:50 +0200
committersonartech <sonartech@sonarsource.com>2021-08-11 20:08:08 +0000
commitc3c730f06025f4a83b9a69cc84668c9876594955 (patch)
tree1d21ef19abc8d72928eb2b9f0f43678cb1695347 /server/sonar-process
parentbb03cec435d188cc7fd5576eced84eaa2c634212 (diff)
downloadsonarqube-c3c730f06025f4a83b9a69cc84668c9876594955.tar.gz
sonarqube-c3c730f06025f4a83b9a69cc84668c9876594955.zip
SONAR-11094 Add nodename to logs for DCE only
Diffstat (limited to 'server/sonar-process')
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/logging/AbstractLogHelper.java16
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/logging/Log4JPropertiesBuilder.java9
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/logging/LogbackHelper.java4
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/logging/LogbackJsonLayout.java7
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/logging/RootLoggerConfig.java14
-rw-r--r--server/sonar-process/src/test/java/org/sonar/process/logging/Log4JPropertiesBuilderTest.java29
-rw-r--r--server/sonar-process/src/test/java/org/sonar/process/logging/LogbackHelperTest.java10
-rw-r--r--server/sonar-process/src/test/java/org/sonar/process/logging/LogbackJsonLayoutTest.java22
8 files changed, 98 insertions, 13 deletions
diff --git a/server/sonar-process/src/main/java/org/sonar/process/logging/AbstractLogHelper.java b/server/sonar-process/src/main/java/org/sonar/process/logging/AbstractLogHelper.java
index f08417eb852..bb3b795796f 100644
--- a/server/sonar-process/src/main/java/org/sonar/process/logging/AbstractLogHelper.java
+++ b/server/sonar-process/src/main/java/org/sonar/process/logging/AbstractLogHelper.java
@@ -29,10 +29,8 @@ import static java.lang.String.format;
public abstract class AbstractLogHelper {
static final Level[] ALLOWED_ROOT_LOG_LEVELS = new Level[] {Level.TRACE, Level.DEBUG, Level.INFO};
- private static final String PROCESS_NAME_PLACEHOLDER = "XXXX";
- private static final String THREAD_ID_PLACEHOLDER = "ZZZZ";
- private static final String LOGGER_NAME_PLACEHOLDER = "YYYY";
- private static final String LOG_FORMAT = "%d{yyyy.MM.dd HH:mm:ss} %-5level " + PROCESS_NAME_PLACEHOLDER + "[" + THREAD_ID_PLACEHOLDER + "][YYYY] %msg%n";
+ private static final String PREFIX_LOG_FORMAT = "%d{yyyy.MM.dd HH:mm:ss} %-5level ";
+ private static final String SUFFIX_LOG_FORMAT = " %msg%n";
private final String loggerNamePattern;
protected AbstractLogHelper(String loggerNamePattern) {
@@ -42,10 +40,12 @@ public abstract class AbstractLogHelper {
public abstract String getRootLoggerName();
public String buildLogPattern(RootLoggerConfig config) {
- return LOG_FORMAT
- .replace(PROCESS_NAME_PLACEHOLDER, config.getProcessId().getKey())
- .replace(THREAD_ID_PLACEHOLDER, config.getThreadIdFieldPattern())
- .replace(LOGGER_NAME_PLACEHOLDER, loggerNamePattern);
+ return PREFIX_LOG_FORMAT
+ + (config.getNodeNameField().isBlank() ? "" : (config.getNodeNameField() + " "))
+ + config.getProcessId().getKey()
+ + "[" + config.getThreadIdFieldPattern() + "]"
+ + "[" + loggerNamePattern + "]"
+ + SUFFIX_LOG_FORMAT;
}
/**
diff --git a/server/sonar-process/src/main/java/org/sonar/process/logging/Log4JPropertiesBuilder.java b/server/sonar-process/src/main/java/org/sonar/process/logging/Log4JPropertiesBuilder.java
index c450d940d62..8bd5b836c9c 100644
--- a/server/sonar-process/src/main/java/org/sonar/process/logging/Log4JPropertiesBuilder.java
+++ b/server/sonar-process/src/main/java/org/sonar/process/logging/Log4JPropertiesBuilder.java
@@ -238,7 +238,14 @@ public class Log4JPropertiesBuilder extends AbstractLogHelper {
* json pattern based on https://github.com/elastic/elasticsearch/blob/7.13/server/src/main/java/org/elasticsearch/common/logging/ESJsonLayout.java
*/
private String getJsonPattern() {
- return "{"
+ String json = "{";
+ if (!"".equals(config.getNodeNameField())) {
+ json = json
+ + jsonKey("nodename")
+ + inQuotes(config.getNodeNameField())
+ + ",";
+ }
+ return json
+ jsonKey("process")
+ inQuotes(config.getProcessId().getKey())
+ ","
diff --git a/server/sonar-process/src/main/java/org/sonar/process/logging/LogbackHelper.java b/server/sonar-process/src/main/java/org/sonar/process/logging/LogbackHelper.java
index e95fb20eda0..f9738bb12bd 100644
--- a/server/sonar-process/src/main/java/org/sonar/process/logging/LogbackHelper.java
+++ b/server/sonar-process/src/main/java/org/sonar/process/logging/LogbackHelper.java
@@ -52,10 +52,10 @@ import org.sonar.process.Props;
import static java.lang.String.format;
import static org.slf4j.Logger.ROOT_LOGGER_NAME;
import static org.sonar.process.ProcessProperties.Property.LOG_CONSOLE;
+import static org.sonar.process.ProcessProperties.Property.LOG_JSON_OUTPUT;
import static org.sonar.process.ProcessProperties.Property.LOG_LEVEL;
import static org.sonar.process.ProcessProperties.Property.LOG_MAX_FILES;
import static org.sonar.process.ProcessProperties.Property.LOG_ROLLING_POLICY;
-import static org.sonar.process.ProcessProperties.Property.LOG_JSON_OUTPUT;
import static org.sonar.process.ProcessProperties.Property.PATH_LOGS;
/**
@@ -232,7 +232,7 @@ public class LogbackHelper extends AbstractLogHelper {
public Encoder<ILoggingEvent> createEncoder(Props props, RootLoggerConfig config, LoggerContext context) {
if (props.valueAsBoolean(LOG_JSON_OUTPUT.getKey(), Boolean.parseBoolean(LOG_JSON_OUTPUT.getDefaultValue()))) {
LayoutWrappingEncoder encoder = new LayoutWrappingEncoder<>();
- encoder.setLayout(new LogbackJsonLayout(config.getProcessId().getKey()));
+ encoder.setLayout(new LogbackJsonLayout(config.getProcessId().getKey(), config.getNodeNameField()));
encoder.setContext(context);
encoder.start();
return encoder;
diff --git a/server/sonar-process/src/main/java/org/sonar/process/logging/LogbackJsonLayout.java b/server/sonar-process/src/main/java/org/sonar/process/logging/LogbackJsonLayout.java
index d0ed49a5f1d..d25ce3a5b44 100644
--- a/server/sonar-process/src/main/java/org/sonar/process/logging/LogbackJsonLayout.java
+++ b/server/sonar-process/src/main/java/org/sonar/process/logging/LogbackJsonLayout.java
@@ -51,9 +51,11 @@ public class LogbackJsonLayout extends LayoutBase<ILoggingEvent> {
private static final Pattern NEWLINE_REGEXP = Pattern.compile("\n");
private final String processKey;
+ private final String nodeName;
- public LogbackJsonLayout(String processKey) {
+ public LogbackJsonLayout(String processKey, String nodeName) {
this.processKey = requireNonNull(processKey);
+ this.nodeName = nodeName;
}
String getProcessKey() {
@@ -65,6 +67,9 @@ public class LogbackJsonLayout extends LayoutBase<ILoggingEvent> {
StringWriter output = new StringWriter();
try (JsonWriter json = new JsonWriter(output)) {
json.beginObject();
+ if (!"".equals(nodeName)) {
+ json.name("nodename").value(nodeName);
+ }
json.name("process").value(processKey);
for (Map.Entry<String, String> entry : event.getMDCPropertyMap().entrySet()) {
if (entry.getValue() != null) {
diff --git a/server/sonar-process/src/main/java/org/sonar/process/logging/RootLoggerConfig.java b/server/sonar-process/src/main/java/org/sonar/process/logging/RootLoggerConfig.java
index 00ceba2dd6c..02b74d06b71 100644
--- a/server/sonar-process/src/main/java/org/sonar/process/logging/RootLoggerConfig.java
+++ b/server/sonar-process/src/main/java/org/sonar/process/logging/RootLoggerConfig.java
@@ -19,7 +19,9 @@
*/
package org.sonar.process.logging;
+import java.util.Optional;
import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
import org.sonar.process.ProcessId;
import static java.util.Objects.requireNonNull;
@@ -27,16 +29,22 @@ import static java.util.Objects.requireNonNull;
public final class RootLoggerConfig {
private final ProcessId processId;
private final String threadIdFieldPattern;
+ private final String nodeNameField;
private RootLoggerConfig(Builder builder) {
this.processId = requireNonNull(builder.processId);
this.threadIdFieldPattern = builder.threadIdFieldPattern;
+ this.nodeNameField = Optional.ofNullable(builder.nodeNameField).orElse("");
}
public static Builder newRootLoggerConfigBuilder() {
return new Builder();
}
+ public String getNodeNameField() {
+ return nodeNameField;
+ }
+
public ProcessId getProcessId() {
return processId;
}
@@ -49,11 +57,17 @@ public final class RootLoggerConfig {
@CheckForNull
private ProcessId processId;
private String threadIdFieldPattern = "";
+ private String nodeNameField;
private Builder() {
// prevents instantiation outside RootLoggerConfig, use static factory method
}
+ public Builder setNodeNameField(@Nullable String nodeNameField) {
+ this.nodeNameField = nodeNameField;
+ return this;
+ }
+
public Builder setProcessId(ProcessId processId) {
this.processId = processId;
return this;
diff --git a/server/sonar-process/src/test/java/org/sonar/process/logging/Log4JPropertiesBuilderTest.java b/server/sonar-process/src/test/java/org/sonar/process/logging/Log4JPropertiesBuilderTest.java
index 975eba70c3f..bd0ceae2e9d 100644
--- a/server/sonar-process/src/test/java/org/sonar/process/logging/Log4JPropertiesBuilderTest.java
+++ b/server/sonar-process/src/test/java/org/sonar/process/logging/Log4JPropertiesBuilderTest.java
@@ -354,6 +354,35 @@ public class Log4JPropertiesBuilderTest {
}
@Test
+ public void enable_json_output_should_include_hostname_if_set() throws IOException {
+ File logDir = temporaryFolder.newFolder();
+ RootLoggerConfig esRootLoggerConfigWithHostname = newRootLoggerConfigBuilder()
+ .setProcessId(ProcessId.ELASTICSEARCH)
+ .setNodeNameField("my-node")
+ .build();
+ String expectedPattern = "{\"nodename\": \"my-node\",\"process\": \"es\",\"timestamp\": \"%d{yyyy-MM-dd'T'HH:mm:ss.SSSZZ}\","
+ + "\"severity\": \"%p\",\"logger\": \"%c{1.}\",\"message\": \"%notEmpty{%enc{%marker}{JSON} }%enc{%.-10000m}{JSON}\"%exceptionAsJson }" + System.lineSeparator();
+
+ Log4JPropertiesBuilder underTest = newLog4JPropertiesBuilder(ROLLING_POLICY_PROPERTY, "none")
+ .enableAllLogsToConsole(true)
+ .rootLoggerConfig(esRootLoggerConfigWithHostname)
+ .jsonOutput(true)
+ .logDir(logDir);
+ verifyProperties(underTest.build(),
+ "appender.stdout.type", "Console",
+ "appender.stdout.name", "stdout",
+ "appender.stdout.layout.type", "PatternLayout",
+ "appender.stdout.layout.pattern", expectedPattern,
+ "rootLogger.appenderRef.stdout.ref", "stdout",
+ "appender.file_es.layout.type", "PatternLayout",
+ "appender.file_es.layout.pattern", expectedPattern,
+ "appender.file_es.fileName", new File(logDir, "es.log").getAbsolutePath(),
+ "appender.file_es.name", "file_es",
+ "rootLogger.appenderRef.file_es.ref", "file_es",
+ "appender.file_es.type", "File");
+ }
+
+ @Test
public void apply_fails_with_IAE_if_LogLevelConfig_does_not_have_rootLoggerName_of_Log4J() throws IOException {
LogLevelConfig logLevelConfig = LogLevelConfig.newBuilder(randomAlphanumeric(2)).build();
File logDir = temporaryFolder.newFolder();
diff --git a/server/sonar-process/src/test/java/org/sonar/process/logging/LogbackHelperTest.java b/server/sonar-process/src/test/java/org/sonar/process/logging/LogbackHelperTest.java
index 7806aaa0a78..022587fcd73 100644
--- a/server/sonar-process/src/test/java/org/sonar/process/logging/LogbackHelperTest.java
+++ b/server/sonar-process/src/test/java/org/sonar/process/logging/LogbackHelperTest.java
@@ -100,6 +100,16 @@ public class LogbackHelperTest {
}
@Test
+ public void buildLogPattern_adds_nodename() {
+ String pattern = underTest.buildLogPattern(newRootLoggerConfigBuilder()
+ .setProcessId(ProcessId.ELASTICSEARCH)
+ .setNodeNameField("my-nodename")
+ .build());
+
+ assertThat(pattern).isEqualTo("%d{yyyy.MM.dd HH:mm:ss} %-5level my-nodename es[][%logger{20}] %msg%n");
+ }
+
+ @Test
public void buildLogPattern_puts_threadIdFieldPattern_from_RootLoggerConfig_non_null() {
String threadIdFieldPattern = RandomStringUtils.randomAlphabetic(5);
String pattern = underTest.buildLogPattern(
diff --git a/server/sonar-process/src/test/java/org/sonar/process/logging/LogbackJsonLayoutTest.java b/server/sonar-process/src/test/java/org/sonar/process/logging/LogbackJsonLayoutTest.java
index 6a207d6a746..4c05a92684f 100644
--- a/server/sonar-process/src/test/java/org/sonar/process/logging/LogbackJsonLayoutTest.java
+++ b/server/sonar-process/src/test/java/org/sonar/process/logging/LogbackJsonLayoutTest.java
@@ -33,7 +33,7 @@ import static org.sonar.process.logging.LogbackJsonLayout.DATE_FORMATTER;
public class LogbackJsonLayoutTest {
- private final LogbackJsonLayout underTest = new LogbackJsonLayout("web");
+ private final LogbackJsonLayout underTest = new LogbackJsonLayout("web", "");
@Test
public void test_simple_log() {
@@ -49,6 +49,25 @@ public class LogbackJsonLayoutTest {
assertThat(json.message).isEqualTo("the message");
assertThat(json.stacktrace).isNull();
assertThat(json.fromMdc).isNull();
+ assertThat(json.nodename).isNull();
+ }
+
+ @Test
+ public void test_simple_log_with_hostname() {
+ LoggingEvent event = new LoggingEvent("org.foundation.Caller", (Logger) LoggerFactory.getLogger("the.logger"), Level.WARN, "the message", null, new Object[0]);
+
+ LogbackJsonLayout underTestWithNodeName = new LogbackJsonLayout("web", "my-nodename");
+ String log = underTestWithNodeName.doLayout(event);
+
+ JsonLog json = new Gson().fromJson(log, JsonLog.class);
+ assertThat(json.process).isEqualTo("web");
+ assertThat(json.timestamp).isEqualTo(DATE_FORMATTER.format(Instant.ofEpochMilli(event.getTimeStamp())));
+ assertThat(json.severity).isEqualTo("WARN");
+ assertThat(json.logger).isEqualTo("the.logger");
+ assertThat(json.message).isEqualTo("the message");
+ assertThat(json.stacktrace).isNull();
+ assertThat(json.fromMdc).isNull();
+ assertThat(json.nodename).isEqualTo("my-nodename");
}
@Test
@@ -140,5 +159,6 @@ public class LogbackJsonLayoutTest {
private String message;
private String fromMdc;
private String[] stacktrace;
+ private String nodename;
}
}