Inheritable MDC using Logback
Dependency:
"com.softwaremill.ox" %% "mdc-logback" % "0.5.8"
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 supervisedError
, unsupervisedError
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"
}