Do not use jsonevent-layout for error logs in JSON format
So far the net.logstash.log4j.jsonevent-layout package was used to format the error logs to JSON. This format was not suitable for the httpd- and sshd logs and thus was not used there. Also the format provided by the dependency was not configurable, e.g. did not allow to change the timestamp. This resulted in different timestamp formats for the text- and the json-formatted error logs. To be more flexible in the formatting of the json logs, this change removes the dependency. It keeps however the ISO8601-formatted timestamp, but adds the timezone offset and thus does not assume the UTC timezone. In a followup change the timestamps of all logs will be adapted to the same standard. Change-Id: I3a2bdba5d4b25067d0324fb63438e2a6ec726c68
This commit is contained in:
@@ -72,8 +72,6 @@ Apache2.0
|
||||
* jetty:server
|
||||
* jetty:servlet
|
||||
* jetty:util
|
||||
* log:json-smart
|
||||
* log:jsonevent-layout
|
||||
* log:log4j
|
||||
* lucene:lucene-analyzers-common
|
||||
* lucene:lucene-core-and-backward-codecs-merged
|
||||
|
@@ -322,12 +322,6 @@ maven_jar(
|
||||
sha1 = "5af35056b4d257e4b64b9e8069c0746e8b08629f",
|
||||
)
|
||||
|
||||
maven_jar(
|
||||
name = "jsonevent-layout",
|
||||
artifact = "net.logstash.log4j:jsonevent-layout:1.7",
|
||||
sha1 = "507713504f0ddb75ba512f62763519c43cf46fde",
|
||||
)
|
||||
|
||||
maven_jar(
|
||||
name = "json-smart",
|
||||
artifact = "net.minidev:json-smart:1.1.1",
|
||||
|
@@ -17,12 +17,13 @@ java_library(
|
||||
"//java/com/google/gerrit/server/restapi",
|
||||
"//java/com/google/gerrit/server/schema",
|
||||
"//java/com/google/gerrit/util/cli",
|
||||
"//java/com/google/gerrit/util/logging",
|
||||
"//lib:args4j",
|
||||
"//lib:gson",
|
||||
"//lib:guava",
|
||||
"//lib:jgit",
|
||||
"//lib/flogger:api",
|
||||
"//lib/guice",
|
||||
"//lib/log:jsonevent-layout",
|
||||
"//lib/log:log4j",
|
||||
],
|
||||
)
|
||||
|
@@ -20,7 +20,6 @@ import com.google.gerrit.server.config.SitePaths;
|
||||
import com.google.gerrit.server.util.SystemLog;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import net.logstash.log4j.JSONEventLayoutV1;
|
||||
import org.apache.log4j.ConsoleAppender;
|
||||
import org.apache.log4j.Level;
|
||||
import org.apache.log4j.LogManager;
|
||||
@@ -84,7 +83,7 @@ public class ErrorLogFile {
|
||||
if (json) {
|
||||
root.addAppender(
|
||||
SystemLog.createAppender(
|
||||
logdir, LOG_NAME + JSON_SUFFIX, new JSONEventLayoutV1(), rotate));
|
||||
logdir, LOG_NAME + JSON_SUFFIX, new ErrorLogJsonLayout(), rotate));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
133
java/com/google/gerrit/pgm/util/ErrorLogJsonLayout.java
Normal file
133
java/com/google/gerrit/pgm/util/ErrorLogJsonLayout.java
Normal file
@@ -0,0 +1,133 @@
|
||||
// Copyright (C) 2020 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.pgm.util;
|
||||
|
||||
import com.google.gerrit.util.logging.JsonLayout;
|
||||
import com.google.gerrit.util.logging.JsonLogEntry;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.apache.log4j.spi.LoggingEvent;
|
||||
import org.apache.log4j.spi.ThrowableInformation;
|
||||
|
||||
/** Layout for formatting error log events in the JSON format. */
|
||||
public class ErrorLogJsonLayout extends JsonLayout {
|
||||
|
||||
@Override
|
||||
public DateTimeFormatter createDateTimeFormatter() {
|
||||
return DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonLogEntry toJsonLogEntry(LoggingEvent event) {
|
||||
return new ErrorJsonLogEntry(event);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private class ErrorJsonLogEntry extends JsonLogEntry {
|
||||
/** Timestamp of when the log entry was created. */
|
||||
@SerializedName("@timestamp")
|
||||
public final String timestamp;
|
||||
|
||||
/** Hostname of the machine running Gerrit. */
|
||||
public final String sourceHost;
|
||||
/** Logged message. */
|
||||
public final String message;
|
||||
/** File containing the code creating the log entry. */
|
||||
public final String file;
|
||||
/** Line number of code creating the log entry. */
|
||||
public final String lineNumber;
|
||||
|
||||
/** Class from which the log entry was created. */
|
||||
@SerializedName("class")
|
||||
public final String clazz;
|
||||
|
||||
/** Method from which the log entry was created. */
|
||||
public final String method;
|
||||
/** Name of the logger creating the log entry. */
|
||||
public final String loggerName;
|
||||
|
||||
/** Mapped diagnostic context. */
|
||||
@SuppressWarnings("rawtypes")
|
||||
public final Map mdc;
|
||||
|
||||
/** Nested diagnostic context. */
|
||||
public final String ndc;
|
||||
/** Logging level/severity. */
|
||||
public final String level;
|
||||
/** Thread executing the code creating the log entry. */
|
||||
public final String threadName;
|
||||
|
||||
/** Version of log format. */
|
||||
@SerializedName("@version")
|
||||
public final int version = 2;
|
||||
|
||||
/**
|
||||
* Map containing information of a logged exception. It contains the following key-value pairs:
|
||||
* exception_class: Which class threw the exception exception_method: Which method threw the
|
||||
* exception stacktrace: The exception stacktrace
|
||||
*/
|
||||
public Map<String, String> exception;
|
||||
|
||||
public ErrorJsonLogEntry(LoggingEvent event) {
|
||||
this.timestamp = formatDate(event.getTimeStamp());
|
||||
this.sourceHost = getSourceHost();
|
||||
this.message = event.getRenderedMessage();
|
||||
this.file = event.getLocationInformation().getFileName();
|
||||
this.lineNumber = event.getLocationInformation().getLineNumber();
|
||||
this.clazz = event.getLocationInformation().getClassName();
|
||||
this.method = event.getLocationInformation().getMethodName();
|
||||
this.loggerName = event.getLoggerName();
|
||||
this.mdc = event.getProperties();
|
||||
this.ndc = event.getNDC();
|
||||
this.level = event.getLevel().toString();
|
||||
this.threadName = event.getThreadName();
|
||||
if (event.getThrowableInformation() != null) {
|
||||
this.exception = getException(event.getThrowableInformation());
|
||||
}
|
||||
}
|
||||
|
||||
private String getSourceHost() {
|
||||
try {
|
||||
return InetAddress.getLocalHost().getHostName();
|
||||
} catch (UnknownHostException e) {
|
||||
return "unknown-host";
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, String> getException(ThrowableInformation throwable) {
|
||||
HashMap<String, String> exceptionInformation = new HashMap<>();
|
||||
|
||||
String throwableName = throwable.getThrowable().getClass().getCanonicalName();
|
||||
if (throwableName != null) {
|
||||
exceptionInformation.put("exception_class", throwableName);
|
||||
}
|
||||
|
||||
String throwableMessage = throwable.getThrowable().getMessage();
|
||||
if (throwableMessage != null) {
|
||||
exceptionInformation.put("exception_message", throwableMessage);
|
||||
}
|
||||
|
||||
String[] stackTrace = throwable.getThrowableStrRep();
|
||||
if (stackTrace != null) {
|
||||
exceptionInformation.put("stacktrace", String.join("\n", stackTrace));
|
||||
}
|
||||
return exceptionInformation;
|
||||
}
|
||||
}
|
||||
}
|
@@ -40,17 +40,6 @@ java_library(
|
||||
exports = ["@log4j//jar"],
|
||||
)
|
||||
|
||||
java_library(
|
||||
name = "jsonevent-layout",
|
||||
data = ["//lib:LICENSE-Apache2.0"],
|
||||
visibility = ["//visibility:public"],
|
||||
exports = ["@jsonevent-layout//jar"],
|
||||
runtime_deps = [
|
||||
":json-smart",
|
||||
"//lib/commons:lang",
|
||||
],
|
||||
)
|
||||
|
||||
java_library(
|
||||
name = "json-smart",
|
||||
data = ["//lib:LICENSE-Apache2.0"],
|
||||
|
Reference in New Issue
Block a user