javalog4j2threadcontext

Log4j ThreadContext from child thread


I'm using with Log4J2 and ThreadContext and basically, I want the ThreadContext shared across all threads (or an alternative to ThreadContext, as the name seems to imply it should be thread-specific).

Right now I have both of these flags set in my programs arguments (added both, although I think the 2nd legacy):

-Dlog4j2.isThreadContextMapInheritable=true
-DisThreadContextMapInheritable=true

If, when my application first starts up, I do:

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

The logs both in my parent thread and child thread will both output "value", so I am assuming the ThreadContext is successfully shared between the threads.

However, if I update that message just before my child runs with:

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

My child thread still has the original "value", but the next message on the parent thread will be "anotherValue".

Same thing happens if I update the value in my child thread. The child thread will output "anotherValue" but the parent thread will still output "value".

I'm assuming I am missing something crucial about how the ThreadContext works, as what is happening makes no sense to me.


Solution

  • The documentation for ThreadContext explicitly states:

    The MDC is managed on a per thread basis. To enable automatic inheritance of copies of the MDC to newly created threads, enable the "isThreadContextMapInheritable" Log4j system property.

    Even when you enable isThreadContextMapInheritable the ThreadContext is not shared - the child thread receives a copy, if you change either the parents ThreadContext or the childs ThreadContext they will diverge.


    The log4j2 manual has the following hints that may help you in implementing your required functionality:

    Custom context data injectors

    Log4j 2.7 adds a flexible mechanism to tag logging statements with context data coming from other sources than the ThreadContext. See the manual page on extending Log4j for details.

    The manual page on extending Log4j contains some hints that you can implement the org.apache.logging.log4j.core.util.ContextDataProvider and register it as additional context data provider.

    I myself have no experience in implementing such a ContextDataProvider.