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

如何使用Log4J发送结构化日志字段?(附SLF4J实现示例)

如何用Log4J实现带自定义键值对的结构化日志(适配Azure Monitor)

问题背景

我在使用SLF4J时,可以通过以下方式添加自定义键值对属性并输出结构化日志:

logger.atInfo()
  .setMessage("My message")
  .addKeyValue("foo", "bar")
  .addKeyValue("code", 42)
  .log()

将其配合Azure Monitor OpenTelemetry Exporter及Logback Appender使用时,会在App Insight的traces表中生成包含自定义属性的日志条目。

现在需要实现相同效果,但使用Log4J日志接口,我没找到可直接接受额外属性的方法重载,请问该如何操作?

解决方案

方法1:利用Log4J的MDC(映射诊断上下文)传递属性

Log4J的**MDC(ThreadContext)**是传递自定义上下文属性的标准方式,Azure Monitor OpenTelemetry Exporter会自动识别MDC中的键值对,并将其写入App Insight的traces表:

import org.apache.logging.log4j.ThreadContext

// 添加自定义属性到MDC
ThreadContext.put("foo", "bar")
ThreadContext.put("code", "42")

// 输出日志
logger.info("My message")

// 若无需后续日志继承这些属性,记得清理
ThreadContext.clearAll()

方法2:使用Log4J 2.x原生结构化日志API

Log4J 2.11及以上版本提供了MapMessage类,可以直接构建包含自定义键值对的结构化日志事件,无需依赖MDC:

import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.message.MapMessage

val logger = LogManager.getLogger(getClass)
val structuredMessage = new MapMessage()
structuredMessage.setMessage("My message")
structuredMessage.put("foo", "bar")
structuredMessage.put("code", 42)

logger.info(structuredMessage)

方法3:参数化日志配合结构化布局(可选)

如果需要更灵活的格式控制,可以使用参数化日志,再通过Log4J的JsonTemplateLayout配置将参数解析为结构化属性:

// 参数化日志输出
logger.info("My message [foo={}, code={}]", "bar", 42)

然后在Log4J配置文件中启用JsonTemplateLayout,确保参数被映射为自定义字段,Azure Exporter就能正确识别并上传到traces表。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 04:02:12