Márton Matusek
10/30/2025, 3:25 PMMDCContext is not enough because MDC is ThreadLocal and one request can "pollute" another. Do you have any suggestions in the topic? I was thinking about using ReactorContext to store log data and retrieve it right before logging. What are your thoughts?Márton Matusek
10/30/2025, 3:25 PMthanksforallthefish
10/30/2025, 3:52 PMimport java.util.concurrent.Executors
import io.micrometer.context.ContextExecutorService;
import io.micrometer.context.ContextRegistry;
import io.micrometer.context.ContextSnapshotFactory;
import io.micrometer.context.integration.Slf4jThreadLocalAccessor;
import io.micrometer.core.instrument.kotlin.asContextElement
import io.micrometer.observation.ObservationRegistry
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
val contextSnapshotFactory = ContextSnapshotFactory.builder().build()
val dispatcher = ContextExecutorService.wrap(Executors.newVirtualThreadPerTaskExecutor(), contextSnapshotFactory::captureAll).asCoroutineDispatcher()
val observationRegistry: ObservationRegistry // this one is a spring bean, created in `ObservationAutoConfiguration`, it should be available on all platform
CoroutineScope(dispatcher).async(observationRegistry.asContextElement()) { do things }
then the problem become feeding information to the observation registry, and that is the part that is probably more specific to webfluxEmil Kantis
10/30/2025, 5:42 PMMárton Matusek
10/30/2025, 6:19 PMsdeleuze
10/31/2025, 11:20 AMspring.reactor.context-propagation=auto and it will work out of the box.sdeleuze
10/31/2025, 11:22 AMMárton Matusek
10/31/2025, 3:35 PMContextRegistry.getInstance().registerThreadLocalAccessor(Slf4jThreadLocalAccessor())
Does this make sense?
Also, I was able to make it work on Spring Boot 3.5.7 using spring.reactor.context-propagation=auto and adding io.micrometer:context-propagation:1.1.3 as a dependency. I imagine that's included in Spring Boot 4 by default.sdeleuze
10/31/2025, 4:20 PM4.0.0-RC1 . I am not an observability expert but I think if you use https://docs.spring.io/spring-boot/reference/actuator/tracing.html#actuator.micrometer-tracing.logging it should work with just io.micrometer:context-propagation dependency and spring.reactor.context-propagation=auto.
Could you please explain your use case with more details and maybe share a git repo or zip archive with a minimal repro. I would like to understand why you need this Slf4jThreadLocalAccessor. I think there will be conflicts between what Slf4jThreadLocalAccessor does and what Spring Boot 4 + Micrometer context propagation does, so I don't think that's recommended to use it, but I need to understand your use case more to be sure.Márton Matusek
11/02/2025, 1:54 PM@RestController
class TestController {
init {
ContextRegistry.getInstance().registerThreadLocalAccessor(Slf4jThreadLocalAccessor())
}
val logger: Logger = LoggerFactory.getLogger(this::class.java)
@GetMapping("/test")
suspend fun test(): String {
MDC.put("testKey", "testValue")
testTask()
delay(50000)
return "test"
}
suspend fun testTask() {
logger.info("Test endpoint called")
}
@GetMapping("/other")
suspend fun other(): String {
MDC.put("otherKey", "otherValue")
otherTask()
return "other"
}
suspend fun otherTask() {
// if the same thread executes the request that put testKey into MDC
// the testValue will "leak" into this log from the other endpoint
logger.info("Other endpoint called")
}
}
I would like to be able to use MDC to automatically enrich logs without having to pass the keys down the call stack as parameters. The problem is (as the comment explains) that MDC uses ThreadLocal and even if I use MDCContext to propagate MDC context updates across coroutines, that does not solve the problem of the same thread working on different requests.sdeleuze
11/03/2025, 9:18 AMMárton Matusek
11/03/2025, 9:22 AMsdeleuze
11/03/2025, 9:22 AMMárton Matusek
11/03/2025, 9:23 AMsdeleuze
11/03/2025, 9:34 AMsdeleuze
11/03/2025, 9:35 AMMárton Matusek
11/03/2025, 9:37 AMMárton Matusek
11/03/2025, 9:38 AM