# Slf4j's MDC and Coroutines

**URL:** <https://discuss.kotlinlang.org/t/slf4js-mdc-and-coroutines/18903>\
**Category:** Web Development\
**Created:** [August 24, 2020, 1:38pm UTC](https://discuss.kotlinlang.org/t/slf4js-mdc-and-coroutines/18903 "2020-08-24T13:38:11Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![uykusuz](https://avatars.discourse-cdn.com/v4/letter/u/7feea3/32.png) [@uykusuz](https://discuss.kotlinlang.org/u/uykusuz)\
**Post date:** [August 24, 2020, 1:38pm UTC](https://discuss.kotlinlang.org/t/slf4js-mdc-and-coroutines/18903/1 "2020-08-24T13:38:11Z")

</div>

Hi guys,

I hope I’m in the right place to ask my question. If that’s not the case, please tell me.

My question in short is: is there a way to hook into the activation/execution of basically every coroutine and do some stuff there?  
In Spring WebFlux, specifically reactor, there’s the concept of Hooks. There you can hook into the activation of a mono/flux operator and do stuff before the code inside it is executed. I’m searching for a similar concept for coroutines.

My particular use case is the following:

I rewrite rest controllers to be suspending functions instead of returning `Mono` and `Flux`.

I have a Spring `RestController` like the following:

```auto
@GetMapping("/dummy")
suspend fun dummyEndpoint(): ResponseEntity<String> {
    logger.debug("dummy")
    return ResponseEntity.ok("OK")
}

```

The question is how to propagate the MDC context. I could do the following:

```auto
@GetMapping("/dummy")
suspend fun dummyEndpoint(): ResponseEntity<String> {
    withContext(MDCContext()) {
        logger.debug("dummy")
        return ResponseEntity.ok("OK")
   }
}

```

from [this package](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-slf4j/).

I’m searching for a solution for not having to explicitly do this. In WebFlux I could have a standalone configuration, where I use reactor hooks to hook into every operator and execute setup code.

---

<div class="post-metadata">

**Author:** ![uykusuz](https://avatars.discourse-cdn.com/v4/letter/u/7feea3/32.png) [@uykusuz](https://discuss.kotlinlang.org/u/uykusuz)\
**Post date:** [August 27, 2020, 6:27am UTC](https://discuss.kotlinlang.org/t/slf4js-mdc-and-coroutines/18903/2 "2020-08-27T06:27:47Z")

</div>

For the sake of completeness: I solved it using aspects after all. The aspect will insert the `withContext...` part before invoking the functions in question.

---

<div class="post-metadata">

**Author:** ![Checketts](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/checketts/32/8927_2.png) [@Checketts](https://discuss.kotlinlang.org/u/Checketts)\
**Post date:** [October 15, 2021, 4:23am UTC](https://discuss.kotlinlang.org/t/slf4js-mdc-and-coroutines/18903/3 "2021-10-15T04:23:55Z")

</div>

Do you have a snippet you can share? I would love to use it.

---

<div class="post-metadata">

**Author:** ![dineshmatrix675](https://avatars.discourse-cdn.com/v4/letter/d/e495f1/32.png) [@dineshmatrix675](https://discuss.kotlinlang.org/u/dineshmatrix675)\
**Post date:** [July 24, 2025, 2:56pm UTC](https://discuss.kotlinlang.org/t/slf4js-mdc-and-coroutines/18903/4 "2025-07-24T14:56:29Z")

</div>

Hey I’m also facing similar problem can someone help me Instead of passing only MDC context i want to pass my custom threadLocal context as well and then reset this threadLocal at the end of request. I know in can pass thread local **asContextElement** but earlier with single thread model i was flushing and resting my custom threadLocal in a filter. Considering return response can be picked by another thread so is it possible to use same filter approach now if yes how ?

---

<div class="post-metadata">

**Author:** ![broot](https://avatars.discourse-cdn.com/v4/letter/b/a88e57/32.png) [@broot](https://discuss.kotlinlang.org/u/broot)\
**Post date:** [July 24, 2025, 7:34pm UTC](https://discuss.kotlinlang.org/t/slf4js-mdc-and-coroutines/18903/5 "2025-07-24T19:34:09Z")

</div>

As said in another thread, just do:

```kotlin
withContext(myThreadLocal.asContextElement("foo")) {
    // handle request
}

```

And this should be it. Also, you don’t need the filter, as the thread local is already cleared at the end of the block.
