Java 使用SLF4J时日志消息的ID

Java 使用SLF4J时日志消息的ID,java,logging,slf4j,Java,Logging,Slf4j,我想为日志语句添加一个唯一的标识符,这样我就可以向每个日志语句添加文档(外部,例如wiki),这样用户就可以使用id快速访问与消息相关的文档。我想使用的日志框架是SLF4J/logback 我找不到关于相关方法的文档,除了一些关于审计框架的内容 我认为有一个标记概念可以用于ID注入,或者我可以将ID添加到消息文本本身 如何“以正确的方式”向日志记录语句添加ID?有我没想到的可能性吗 编辑 术语unique ID只是表示每个日志语句都应该有一个标识符。例如,开发人员手动将此类ID添加到表/枚举/任

我想为日志语句添加一个唯一的标识符,这样我就可以向每个日志语句添加文档(外部,例如wiki),这样用户就可以使用id快速访问与消息相关的文档。我想使用的日志框架是SLF4J/logback

我找不到关于相关方法的文档,除了一些关于审计框架的内容

我认为有一个标记概念可以用于ID注入,或者我可以将ID添加到消息文本本身

如何“以正确的方式”向日志记录语句添加ID?有我没想到的可能性吗

编辑

术语unique ID只是表示每个日志语句都应该有一个标识符。例如,开发人员手动将此类ID添加到表/枚举/任何内容中,这可能是错误的。 这样的ID必须是稳定的,所以文档可以基于它。所以ID本身不是我想知道的

我的问题是:将ID与消息文本一起推送到记录器的正确方式是什么?标记是否适合这种需求,我应该将ID嵌入到消息文本中,还是存在其他可能性

那么,基本上,我会使用

logger.info(IDMarkers.DB_CONNECTION_FAILED, "no connection to the database");
或者只是

logger.info("[{}] no connection to the database", LogIDs.DB_CONNECTION_FAILED);

第一种方法的优点是显示ID取决于日志系统/其配置。

唯一性仅在某些范围内唯一。最终,甚至会使用每个
int
long

所以,想想“独特性”对你意味着什么。然后使用一个包装器,它将确保您的日志记录是使用插入的id进行处理的

请注意,使用slf4j,您将处理一个
接口
,该接口将使许多日志API保持一致。这意味着您可能无法选择子类,甚至无法注入接口的实现来确保日志记录的一致性。因此,您将受限于包装日志API(最好通过“一致”接口)等技术

这意味着您还必须创建自己的
LoggerFactory
接口

public Logger getLogger(String name) {
  return new LoggerWrapper(org.sql4j.LoggerFactory(name));
}
虽然上面的代码有一些缺点(没有实际测试);希望它能给你一个想法。

Slf4j有

不幸的是,
Marker
s被广告用于不同的目的。仍然可以使用它们唯一地标记日志语句

更麻烦的解决方案是MDC:

MDC.put("MsgId", "EV-1234");
log.info()
MDC.remove("MsgId");
或使用结构测井(需要v2.0.0):


您希望该id如何唯一?打电话?通过线程?按代码行?@zenbeni:log语句(例如
logger.debug('some message text')
)应该获得ID。这样的语句会生成一个日志条目,例如
[ID1234]每次调用都有一些消息文本
。在运行时获取执行上下文的成本很高:因此我认为您应该在消息中静态执行。@zenbeni:我可能错了,但是获取标记的成本并不比从其他地方获取ID时所需的字符串串联成本高。这不涉及获取执行的上下文。在谷歌搜索了一些相关的问题之后,很遗憾,没有太多的信息。我更新了我的问题,指出了它的方向。您建议的解决方案将为每个日志条目提供唯一的ID,这不支持我将文档链接到日志语句……我的解决方案将为您提供唯一的ID,以满足您的任何需求。例如,您可以使用常量字符串构造包装器,然后它将是每个记录器的唯一日志id。或者,您可以使用
getUniqueId()
中的线程检测代码为每个线程指定唯一的id。这取决于你来决定独特性。
MDC.put("MsgId", "EV-1234");
log.info()
MDC.remove("MsgId");
logger.atDebug()
    .addKeyValue("MsgId", "EV-1234")
    .log("Temperature changed.");