如何在Log4j2的JsonTemplateLayout中屏蔽默认的contextMap输出?
Log4j2 JsonTemplateLayout 移除contextMap重复字段
问题场景
需要通过Log4j2的JSON格式输出日志,包含两个自定义字段:
- 固定值字段
myApp - 从ThreadContext(MDC)读取的
customKey1
当前使用JsonTemplateLayout时,customKey1会重复输出:一次在JSON根层级(自定义配置的),一次在默认生成的contextMap节点下,需要屏蔽contextMap的输出。
当前配置
<?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" format="JSON" value='{"$resolver": "mdc", "key": "customKey1"}'/> </JsonTemplateLayout> </Console> </Appenders> <Loggers> <Root level="info" additivity="false"> <AppenderRef ref="console" /> </Root> </Loggers> </Configuration>
当前输出(含重复字段)
{ "instant": { "epochSecond": 1712749405, "nanoOfSecond": 600717045 }, "thread": "t1", "level": "ERROR", "loggerName": "com.example.myapp.Log", "message": "custom log msg", "contextMap": { "customKey1": "customValue" }, "myApp": "MYAPPLICATION", "customKey1": "customValue" }
使用版本
org.springframework.boot:spring-boot-starter-log4j2:2.7.18org.apache.logging.log4j:log4j-layout-template-json:2.21.1
解决方法
JsonTemplateLayout的输出结构完全由指定的JSON模板文件控制,默认模板会包含contextMap字段,只需修改模板移除该字段即可。
步骤
- 找到项目中
classpath:JsonLayout.json模板文件(如果不存在,可从Log4j2的json-layout模块中复制默认模板进行修改) - 移除模板中定义
contextMap的行(通常是类似"contextMap": {"$resolver": "mdc"}的配置) - 保存修改后的模板,重启应用即可生效
修改后的示例模板(JsonLayout.json)
{ "instant": { "$resolver": "timestamp", "pattern": { "$resolver": "pattern", "pattern": "{epochSecond} {nanoOfSecond}", "format": "array" } }, "thread": { "$resolver": "thread", "field": "name" }, "level": { "$resolver": "level", "field": "name" }, "loggerName": { "$resolver": "logger", "field": "name" }, "message": { "$resolver": "message", "stringified": true }, // 移除下面这行即可屏蔽contextMap输出 // "contextMap": {"$resolver": "mdc"}, "myApp": { "$resolver": "eventTemplateAdditionalField", "key": "myApp" }, "customKey1": { "$resolver": "eventTemplateAdditionalField", "key": "customKey1" } }
修改后的输出(无contextMap)
{ "instant": { "epochSecond": 1712749405, "nanoOfSecond": 600717045 }, "thread": "t1", "level": "ERROR", "loggerName": "com.example.myapp.Log", "message": "custom log msg", "myApp": "MYAPPLICATION", "customKey1": "customValue" }
内容的提问来源于stack exchange,提问作者Sumi Silky
相关产品推荐
相关产品推荐

