-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Open
Labels
Description
Use case
Using the MDCContext of the SLF4J extension is cumbersome. It is recommended to use it in the following way:
MDC.put("a", "1")
MDC.put("b", "2")
MDC.put("c", "3")
withContext(MDCContext()) {
// ...
}The code has two problems:
- Many lines required for something that could fit on one line
- The MDC values are leaking into code after the
withContextblock. On backend server applications where threads are reused they could leak into other HTTP calls.
Cleaning up the MDC adds even more boilerplate code:
val closables = listOf(
MDC.putCloseable("a", "1"),
MDC.putCloseable("b", "2"),
MDC.putCloseable("c", "3"),
)
try {
withContext(MDCContext()) {
// ...
}
} finally {
closables.forEach { it.close() }
}The Shape of the API
It would be nice to have a secondary constructor, which takes key values pairs as arguments so I can just write:
withContext(MDCContext("a" to "1", "b" to "2", "c" to "3")) {
// ...
}As a current workaround I use the following function, but I think a secondary constructor as part of the library would be better:
fun MDCContext(vararg keyValuePairs: Pair<String, String>) = MDCContext(
(MDC.getCopyOfContextMap() ?: emptyMap()) + keyValuePairs,
)This offers a concise way of setting up values in the MDC without polluting the current thread. Also, it behaves better than the example from above: The MDC is not only cleaned up, but rather restored to its previous state after the withContext block.
You can find my PR here.
Reactions are currently unavailable