例如,假设我有在运行时确定的应用程序版本。我希望所有日志消息都显示应用程序版本。
我知道有ThreadContext。我的理解是,如果我这样做
ThreadContext.put("version", myAppVersion);
,那么它将一直有效,直到出现另一个线程。在这种情况下,该版本将不可用。
在每个线程中运行
ThreadContext.put("version", "1.0.0")
是 Log4j API 中提供每个事件的上下文映射中的值的唯一方法。
但是,如果您愿意实施特定于后端的解决方案,还有更好的解决方案。
在 Log4j API 的参考实现(称为 Log4j Core)中,您可以实现
ContextDataProvider
接口并将其注册为 Java 服务提供者(参见 ServiceLoader
)。
实现可能如下所示:
public class VersionContextDataProvider implements ContextDataProvider {
private static final Map<String, String> MAP = Map.of("version", "1.0.0");
@Override
public Map<String, String> supplyContextData() {
return MAP;
}
// Garbage-free optimization (optional)
private static final StringMap STRING_MAP = new SortedArrayStringMap(MAP);
static {
STRING_MAP.freeze();
}
@Override
public StringMap supplyStringMap() {
return STRING_MAP;
}
}
MDCAdapter
(参见如何向 slf4j 提供我自己的 MDCAdapter?)我不知道如何向上下文映射添加其他值。
然而,自 SLF4J 2.x 以来,引入了类似的键/值对概念(参见
LoggingEventBuilder#addKeyValue
)。