Is anyone familiar with how to get MDC calls such ...
# ktor
r
Is anyone familiar with how to get MDC calls such as
MDC.put(“key”, “val”)
to work within Ktor within a call pipeline? Is there a specific way to get this to work for the logger within Ktor? I’m using SLF4J with a JSON output and my goal is to simply add additional metadata to the JSON output based on the call.
j
org.jetbrains.kotlinx:kotlinx-coroutines-slf4j:kotlinxCoroutines
we have a util
Copy code
/**
 * Use this to make MDC work properly with Kotlin coroutines.
 * Null values will be excluded.
 */
public suspend fun <T> withMdc(mdc: Map<String, Any?>, block: suspend () -> T): T {
  val contextMap = buildMap {
    putAll(MDC.getCopyOfContextMap())
    mdc.forEach { (key, value) ->
      value ?: return@forEach // Don't include null values in MDC.
      put(key, mdcMapper.writeValueAsStringSpecial(value))
    }
  }

  return withContext(MDCContext(contextMap)) {
    block()
  }
}
This makes it work nicely with coroutines. Otherwise since MDC stores things on the thread context it borks
r
Oh cool, I was seeing MDCContext come up but I wasn’t sure how it was meant to be used within the context of Ktor. Thanks, I’ll give that a try.
Where do the Kairo artifacts get published to?
j
I don't know if you need to use Kairo necessarily — it's a small framework I maintain that only 2 companies use afaik. Although you're welcome to!
Copy code
plugins {
  id("com.google.cloud.artifactregistry.gradle-plugin")
}

maven {
  url = uri("<artifactregistry://us-central1-maven.pkg.dev/airborne-software/maven>")
}

dependencies {
  implementation("kairo:kairo-mdc:4.2.0")
}
Alternatively you could use
org.jetbrains.kotlinx:kotlinx-coroutines-slf4j:kotlinxCoroutines
directly and just copy this file
But if you find other pieces of Kairo useful, feel free! They're all relatively independent from each other and actively maintained by my company
I think the other thing to look at would be https://github.com/Kotlin/kotlinx.coroutines/blob/master/integration/kotlinx-coroutines-slf4j/src/MDCContext.kt if you're curious how this works at a deeper level
r
Yeah, digging into it I am a little bit lost on how this should work with our logger. Would logger calls be done within the block passed into the context functions?
Ope I think I got it
Within the call I have the
MDC.put
calls, and then:
Copy code
call.launch(MDCContext()) {
    <http://application.log.info|application.log.info>(“…”)
}
For future reference for anyone else running into this^
a
Also, you can use the CallLogging plugin to put a diagnostic context value in the call context.
r
I needed to dynamically add a bunch of values to a call for a specific endpoint.