来自子线程的Log4j ThreadContext



我与Log4J2和ThreadContext一起使用,基本上,我希望ThreadContext在所有线程之间共享(或者ThreadContext的替代方案,因为名称似乎意味着它应该是特定于线程的(。

现在,我已经在程序参数中设置了这两个标志(添加了两个,尽管我认为是第二个遗留问题(:

-Dlog4j2.isThreadContextMapInheritable=true
-DisThreadContextMapInheritable=true

如果,当我的应用程序第一次启动时,我会:

ThreadContext.put("key", "value");

我的父线程和子线程中的日志都将输出";值";,所以我假设ThreadContext在线程之间成功共享。

然而,如果我在孩子跑步前更新了这条消息:

ThreadContext.put("key", "anotherValue");

我的孩子线程仍然有原来的";值";,但是父线程上的下一个消息将是"0";anotherValue";。

如果我更新子线程中的值,也会发生同样的情况。子线程将输出"0";另一个值";但是父线程仍将输出"0";值";。

我想我错过了一些关于ThreadContext如何工作的关键内容,因为正在发生的事情对我来说毫无意义。

ThreadContext的文档明确指出:

MDC是在每个线程的基础上管理的。为了使MDC的拷贝能够自动继承到新创建的线程;isThreadContextMapInheritable;Log4j系统属性。

即使启用isThreadContextMapInheritable,ThreadContext也不会共享-子线程会收到一份副本,如果更改父线程ThreadContext或子线程ThreadContext,它们也会分叉。


log4j2手册有以下提示,可以帮助您实现所需的功能:

自定义上下文数据注入器

Log4j 2.7添加了一种灵活的机制,用来自ThreadContext之外的其他来源的上下文数据标记日志记录语句。有关详细信息,请参阅扩展Log4j的手册页面。

关于扩展Log4j的手册页面包含一些提示,您可以实现org.apache.logging.log4j.core.util.ContextDataProvider并将其注册为额外的上下文数据提供程序。

我自己没有实施这种ContextDataProvider的经验。

最新更新