Inheritable MDC using Logback
Dependency:
"com.softwaremill.ox" %% "mdc-logback" % "1.0.4"
Ox provides support for setting inheritable MDC (mapped diagnostic context) values, when using the Logback
logging library. Normally, value set using MDC.put aren’t inherited across (virtual) threads, which includes forks
created in concurrency contexts.
Inheritable values are especially useful e.g. when setting a correlation id in an HTTP request interceptor, or at any entrypoint to the application. Such correlation id values can be then added automatically to each log message, provided the appropriate log encoder pattern is used.
To enable using inheritable MDC values, the application’s code should call InheritableMDC.init as soon as possible.
The best place would be the application’s entrypoint (the main method).
Once this is done, inheritable MDC values can be set in a scoped & structured manner using InheritableMDC.supervisedWhere
and variants.
As inheritable MDC values use a ForkLocal under the hood, their usage
restrictions apply: outer concurrency scopes should not be used to create forks within the scopes. Only newly created
scopes, or the provided scope can be used to create forks. That’s why supervisedWhere, unsupervisedWhere and
supervisedErrorWhere methods are provided.
“Normal” MDC usage is not affected. That is, values set using MDC.put are not inherited, and are only available in
the thread where they are set.
For example:
import org.slf4j.MDC
import ox.fork
import ox.logback.InheritableMDC
InheritableMDC.supervisedWhere("a" -> "1", "b" -> "2") {
MDC.put("c", "3") // not inherited
fork {
MDC.get("a") // "1"
MDC.get("b") // "2"
MDC.get("c") // null
}.join()
MDC.get("a") // "1"
MDC.get("b") // "2"
MDC.get("c") // "3"
}