首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Logback和JsonLayout:无法传递自定义字段

Logback和JsonLayout:无法传递自定义字段
EN

Stack Overflow用户
提问于 2020-06-10 15:00:40
回答 1查看 4.8K关注 0票数 7

我的logback.xml中有这个配置到Spring应用程序(没有Spring )。

代码语言:javascript
复制
<?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>

JSON布局工作良好,但自定义字段"appname":"foobar“没有打印:

代码语言:javascript
复制
{
  "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"
}

我做错了什么?

溶液

我使用了错误的库来满足我的需求:

  • logback-jackson
  • logback-json-classic

由于我需要通过Logstash处理日志,所以我对我的配置进行了如下更正:

pom.xml

代码语言:javascript
复制
<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>

logback.xml

代码语言:javascript
复制
<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>

现在效果很好。

EN

回答 1

Stack Overflow用户

发布于 2022-11-29 20:23:13

我错误地回答了这个问题,因为我也遇到了同样的问题,我找到了一个解决方案,使用logback-jacksonlogback-json-classic

选项1:通过映射的诊断上下文(**MDC**)按线程读取

SLF4j的映射诊断上下文是一个每个线程的键值存储,我们可以使用它将自定义的结构化数据写入日志输出。

代码语言:javascript
复制
MDC.put("customKey", "customValue");

Logback的JsonLayout将在一个特殊的mdc JSON对象下自动打印这个值,而不进行任何进一步的配置。

代码语言:javascript
复制
{ [...], "mdc": {"customKey", "customValue"}} 

请注意,MDC是每个线程构造的,如果它是空的,则不会将mdc字段打印到日志输出。

选项2:全局(适用于所有线程)

如果希望自定义字段出现在JSON输出的根上,则需要创建一个扩展JsonLayout的自定义但简单的布局类。JsonLayout为我们提供了一个可以重写的addCustomDataToJsonMap

代码语言:javascript
复制
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");
  }
}

现在,您只需要告诉Logback在您的CustomJsonLayout文件中使用JsonLayout而不是JsonLayout,其余的保持不变。

代码语言:javascript
复制
<layout class="com.mypackage.CustomJsonLayout">
    ...
</layout>

现在,任何日志消息都将具有以下输出:

代码语言:javascript
复制
{ ..., "customKey": "customValue"}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62306751

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档