Slf4j、logback - 从JSON中删除MDC标签

4

我正在使用MDC为日志记录添加上下文信息:

MDC.put("Correlation-ID", UUID.randomUUID().toString()); 

我正在使用以下的logback编码器:

    <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
        <layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
            <timestampFormat>yyyy-MM-dd'T'HH:mm:ss.SSSX</timestampFormat>
            <timestampFormatTimezoneId>Etc/UTC</timestampFormatTimezoneId>
            <appendLineSeparator>true</appendLineSeparator>

            <jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
                <prettyPrint>false</prettyPrint>
            </jsonFormatter>
        </layout>
    </encoder> 

我有以下日志:

{"timestamp":"2020-01-20T11:40:09.850Z","level":"INFO","thread":"main","mdc":{"Correlation-ID":"66f7843c-9855-450d-ad97-b1c78404f051"},"logger":"liquibase.Liquibase"...

我想删除根MDC标记,以得到:
{"timestamp":"2020-01-20T11:40:09.850Z","level":"INFO","thread":"main","Correlation-ID":"66f7843c-9855-450d-ad97-b1c78404f051","logger":"liquibase.Liquibase"...

我该如何实现这个目标?

Log4j允许显式获取这些变量:例如pattern="%d{ISO8601} %-5p - %-26.26c{1} - %notEmpty{[username=%X{username}] - }%m\n"。我认为logback可能有类似的功能? - Rob Audenaerde
3个回答

3
你可以使用 logstash logback JSON编码器
将以下依赖项添加到你的 pom.xml 中:
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>${slf4j.version}</version>
</dependency>

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-core</artifactId>
    <version>${logback.version}</version>
</dependency>

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>${logback.version}</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>${jackson.version}</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>${jackson.version}</version>
</dependency>

<dependency>
    <groupId>net.logstash.logback</groupId>
    <artifactId>logstash-logback-encoder</artifactId>
    <version>${logstash.version}</version>
</dependency>

这里有一个示例:

<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
    <providers>
        <pattern>
            <omitEmptyFields>true</omitEmptyFields>
            <pattern>
                {
                    "timestamp": "%d{yyyy-MM-dd'T'HH:mm:ss.SSSZ}",
                    "level": "%level",
                    "thread": "%t",
                    "Correlation-ID": "%mdc{Correlation-ID}",
                    "logger": "%logger",
                    ...
                }
            </pattern>
        </pattern>
    </providers>
</encoder>

文档在这里


0

如果您想保留相关ID,则可以扩展JSON Layout类并在Map上设置属性。

public class CustomJsonLayout extends JsonLayout {
@Override
protected Map toJsonMap(ILoggingEvent iLoggingEvent) {
    LinkedHashMap var2 = new LinkedHashMap();
    this.addTimestamp("timestamp", this.includeTimestamp, iLoggingEvent.getTimeStamp(), var2);
    this.add("level", this.includeLevel, String.valueOf(iLoggingEvent.getLevel()), var2);
    this.add("thread", this.includeThreadName, iLoggingEvent.getThreadName(), var2);
    this.add("logger", this.includeLoggerName, iLoggingEvent.getLoggerName(), var2);
    this.add("message", this.includeFormattedMessage, iLoggingEvent.getFormattedMessage(), var2);
    this.add("raw-message", this.includeMessage, iLoggingEvent.getMessage(), var2);
    this.add("context", this.includeContextName, iLoggingEvent.getLoggerContextVO().getName(), var2);
    this.addThrowableInfo("exception", this.includeException, iLoggingEvent, var2);
    this.addCustomDataToJsonMap(var2, iLoggingEvent);
    Map<String,String> mdc = iLoggingEvent.getMDCPropertyMap();
    String correlationId = mdc.getOrDefault("Correlation-ID","");
    this.add("Correlation-ID", this.includeMDC, correlationId , var2);
    return var2;
}
}

在布局中添加新类。
 <layout class="com.test.utils.CustomJsonLayout">

-2
  • 这里有一个简单的解决方案,使用<includeMDC>false</includeMDC>

    <layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
                   <appendLineSeparator>true</appendLineSeparator>
                  <includeMDC>false</includeMDC>
                <jsonFormatter
                    class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
                    <prettyPrint>true</prettyPrint>
                </jsonFormatter>
            </layout>
    

1
OP正在寻求一种解决方案,将MDC参数从嵌套对象移动到日志事件的根目录。这个答案完全删除了日志中的MDC参数,是不正确的。 - Lo-Tan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接