You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Log4j2 JsonTemplateLayout仅在ThreadContext有值时输出自定义字段

解决Log4j2 JsonTemplateLayout自定义字段按需显示问题

需求说明

  • 采用Log4j2的JSON格式记录2个自定义字段:
    • 固定值字段myApp,值为MYAPPLICATION
    • 动态字段customKey1,取值自ThreadContext,仅当该字段有值时才打印,无值时从日志中省略
  • 使用JsonTemplateLayout实现上述需求

当前配置

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
   <Appenders>
      <Console name="console" target="SYSTEM_OUT">
          <JsonTemplateLayout eventTemplateUri="classpath:JsonLayout.json">
              <EventTemplateAdditionalField key="myApp" value="MYAPPLICATION" />
              <EventTemplateAdditionalField key="customKey1" value="$${ctx:customKey1:-}" />
                        
          </JsonTemplateLayout>
      </Console>
   </Appenders>
    <Loggers>
        <Root level="info" additivity="false">
            <AppenderRef ref="console" />
        </Root>
    </Loggers>
</Configuration>

版本信息

  • org.springframework.boot:spring-boot-starter-log4j2:2.7.18
  • org.apache.logging.log4j:log4j-layout-template-json:2.21.1

问题

使用JsonLayout时,customKey1仅在ThreadContext有值时显示;但切换到JsonTemplateLayout后,即使未设置customKey1,该字段仍会以空字符串形式出现在日志中,不符合“无值时省略”的要求。

解决方案

问题根源在于EventTemplateAdditionalField的默认值处理:$${ctx:customKey1:-}会在无值时返回空字符串,而JsonTemplateLayout会将空字符串视为有效值保留字段。要实现无值时省略字段,需要通过自定义JSON模板来控制字段显示逻辑:

1. 自定义JSON模板文件

创建customJsonLayout.json文件(放置在classpath下),基于默认模板添加字段非空判断逻辑:

{
  "timestamp": {
    "$resolver": "timestamp",
    "pattern": {
      "$format": "yyyy-MM-dd'T'HH:mm:ss.SSSZZ"
    }
  },
  "level": {
    "$resolver": "level",
    "field": "name"
  },
  "logger": {
    "$resolver": "logger",
    "field": "name"
  },
  "message": {
    "$resolver": "message",
    "stringified": true
  },
  "myApp": "MYAPPLICATION",
  "customKey1": {
    "$resolver": "mdc",
    "key": "customKey1",
    "suppressEmpty": true
  }
}

其中"suppressEmpty": true是mdc解析器的内置配置,会在customKey1无值时自动省略该字段。

2. 修改Log4j2配置文件

将模板路径指定为自定义的customJsonLayout.json:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
   <Appenders>
      <Console name="console" target="SYSTEM_OUT">
          <JsonTemplateLayout eventTemplateUri="classpath:customJsonLayout.json" />
      </Console>
   </Appenders>
    <Loggers>
        <Root level="info" additivity="false">
            <AppenderRef ref="console" />
        </Root>
    </Loggers>
</Configuration>

补充说明

如果不想完全重写模板,可以从log4j-layout-template-json包中找到官方默认的JsonLayout.json,只修改或添加自定义字段的逻辑即可,避免重复编写默认字段的配置。

内容的提问来源于stack exchange,提问作者Sumi Silky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 04:24:57