Yur*_*uri 8 logging spring logback logback-classic
我在 logback.xml 中将此配置放入 Spring Web 应用程序(无 Spring Boot)。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<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>
<jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
<prettyPrint>true</prettyPrint>
</jsonFormatter>
</layout>
<customFields>{"appname":"foobar"}</customFields>
</encoder>
</appender>
<!-- LOG everything at INFO level -->
<root level="INFO">
<appender-ref ref="Console" />
</root>
</configuration>
Run Code Online (Sandbox Code Playgroud)
JSON 布局工作正常,但不会打印“appname”:“foobar”这样的自定义字段:
{
"timestamp" : "2020-06-10T14:55:25.534Z",
"level" : "INFO",
"thread" : "Catalina-utility-1",
"logger" : "org.springframework.web.servlet.DispatcherServlet",
"message" : "FrameworkServlet 'dispatcher': initialization completed in 72 ms",
"context" : "default"
}
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
解决方案
我使用了错误的库来满足我的需求:
由于我需要通过 Logstash 处理日志,因此我更正了我的配置,如下所示:
pom.xml
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>6.4</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
日志记录文件
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<customFields>{"customer":"X", "appname":"Y", "environment":"dev"}</customFields>
</encoder>
</appender>
Run Code Online (Sandbox Code Playgroud)
现在效果很好。
我只是偶然发现了这个问题,因为我遇到了同样的问题,并且我找到了一个解决方案,使用logback-jackson和logback-json-classic。
选项 1:通过映射诊断上下文按线程 ( MDC)
SLF4j 的映射诊断上下文是一个每线程键值存储,我们可以使用它来将自定义结构化数据写入日志输出。
MDC.put("customKey", "customValue");
Run Code Online (Sandbox Code Playgroud)
LogbackJsonLayout将自动在特殊的 JSON 对象下打印该值,mdc无需任何进一步配置。
{ [...], "mdc": {"customKey", "customValue"}}
Run Code Online (Sandbox Code Playgroud)
请注意,MDC是按线程构造的,如果它为空,则不mdc会将任何字段打印到日志输出中。
选项 2:全局(适用于所有线程)
如果您希望自定义字段出现在 JSON 输出的根目录中,则需要创建一个扩展的自定义但简单的 Layout 类JsonLayout。JsonLayout为我们提供了一个addCustomDataToJsonMap我们可以重写的方法。
package com.mypackage;
import ch.qos.logback.contrib.json.classic.JsonLayout;
public class CustomJsonLayout extends JsonLayout {
@Override
protected void addCustomDataToJsonMap(Map<String, Object> map, ILoggingEvent event) {
map.put("customKey", "customValue");
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您只需告诉 Logback在您的文件中使用CustomJsonLayout而不是使用,并保持其余部分相同。JsonLayoutlogback.xml
<layout class="com.mypackage.CustomJsonLayout">
...
</layout>
Run Code Online (Sandbox Code Playgroud)
现在,任何日志消息都将具有以下输出:
{ ..., "customKey": "customValue"}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8695 次 |
| 最近记录: |