Class MDCInitializer

java.lang.Object
com.streamconverter.logging.MDCInitializer

public final class MDCInitializer extends Object
Installs InheritableMDCAdapter so that MDC context is automatically propagated to child threads (including virtual threads) without manual copying.

Call initialize() once at application startup, before the first log statement, to replace the default Logback MDC adapter. After initialization, MDC values set in a parent thread are automatically visible in any thread it spawns.

If InheritableMDCAdapter is not installed (i.e., initialize() was not called), MDC context will not propagate to child threads. Each thread will have an independent, empty MDC context.

Important: InheritableMDCAdapter is backed by InheritableThreadLocal. In environments that reuse threads (for example, servlet containers or ExecutorService thread pools), MDC values inherited for one logical request can unintentionally be visible to a subsequent, unrelated request running on the same thread unless MDC is reliably cleared. This can lead to log correlation IDs, user identifiers, or other contextual data "leaking" across requests.

When using MDCInitializer together with thread pools, ensure that each task clears MDC in a finally block (for example, by calling MDC.clear() or removing the keys it set), or wrap submitted Runnable/Callable instances so that MDC is captured, applied for the task execution, and then cleared afterwards.

Example usage:


 public static void main(String[] args) {
     MDCInitializer.initialize();
     // ... rest of application startup
 }
 
  • Method Details

    • initialize

      public static void initialize()
      Installs InheritableMDCAdapter into both the SLF4J MDC class and the Logback LoggerContext (if Logback is present on the classpath).

      This method is idempotent: calling it multiple times has no additional effect after the first call. It is also thread-safe; concurrent calls are serialized.

      Note: The key-value map of the current thread's MDC context is migrated into the new adapter. However, deque-based state (pushByKey/popByKey) and values set in other threads are not migrated. For best results, call this method at application startup before any MDC values are set.

      Throws:
      IllegalStateException - if the adapter cannot be installed via reflection