-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implementation of a SLF4J MDC Context
- Loading branch information
Showing
12 changed files
with
233 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
binary-compatibility-validator/reference-public-api/kotlinx-coroutines-slf4j.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
public final class kotlinx/coroutines/experimental/slf4j/MDCContext : kotlin/coroutines/experimental/AbstractCoroutineContextElement { | ||
public static final field Key Lkotlinx/coroutines/experimental/slf4j/MDCContext$Key; | ||
public fun <init> ()V | ||
public fun <init> (Ljava/util/Map;)V | ||
public synthetic fun <init> (Ljava/util/Map;ILkotlin/jvm/internal/DefaultConstructorMarker;)V | ||
public final fun getContextMap ()Ljava/util/Map; | ||
} | ||
|
||
public final class kotlinx/coroutines/experimental/slf4j/MDCContext$Key : kotlin/coroutines/experimental/CoroutineContext$Key { | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Module kotlinx-coroutines-slf4j | ||
|
||
Integration with SLF4J [MDC](https://logback.qos.ch/manual/mdc.html). | ||
|
||
## Example | ||
|
||
Add [MDCContext] to the coroutine context so that the SLF4J MDC context is captured and passed into the coroutine. | ||
|
||
```kotlin | ||
MDC.put("kotlin", "rocks") // put a value into the MDC context | ||
|
||
launch(MDCContext()) { | ||
logger.info { "..." } // the MDC context will contain the mapping here | ||
} | ||
``` | ||
|
||
# Package kotlinx.coroutines.experimental.slf4j | ||
|
||
Integration with SLF4J [MDC](https://logback.qos.ch/manual/mdc.html). | ||
|
||
<!--- MODULE kotlinx-coroutines-slf4j --> | ||
<!--- INDEX kotlinx.coroutines.experimental.slf4j --> | ||
[MDCContext]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-slf4j/kotlinx.coroutines.experimental.slf4j/-m-d-c-context/index.html | ||
<!--- END --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
dependencies { | ||
compile 'org.slf4j:slf4j-api:1.7.25' | ||
testCompile 'io.github.microutils:kotlin-logging:1.5.4' | ||
testRuntime 'ch.qos.logback:logback-classic:1.2.3' | ||
testRuntime 'ch.qos.logback:logback-core:1.2.3' | ||
} | ||
|
||
tasks.withType(dokka.getClass()) { | ||
externalDocumentationLink { | ||
url = new URL("https://www.slf4j.org/apidocs/") | ||
} | ||
} |
1 change: 1 addition & 0 deletions
1
...j/resources/META-INF/services/kotlinx.coroutines.experimental.CoroutineContextThreadLocal
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
kotlinx.coroutines.experimental.slf4j.MDCContextThreadLocal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/* | ||
* Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. | ||
*/ | ||
|
||
package kotlinx.coroutines.experimental.slf4j | ||
|
||
import kotlinx.coroutines.experimental.* | ||
import org.slf4j.MDC | ||
import kotlin.coroutines.experimental.AbstractCoroutineContextElement | ||
import kotlin.coroutines.experimental.Continuation | ||
import kotlin.coroutines.experimental.ContinuationInterceptor | ||
import kotlin.coroutines.experimental.CoroutineContext | ||
|
||
/** | ||
* The value of [MDC] context map. | ||
* See [MDC.getCopyOfContextMap]. | ||
*/ | ||
public typealias MDCContextMap = Map<String, String>? | ||
|
||
/** | ||
* [MDC] context element for [CoroutineContext]. | ||
* | ||
* Example: | ||
* | ||
* ``` | ||
* MDC.put("kotlin", "rocks") // put a value into the MDC context | ||
* | ||
* launch(MDCContext()) { | ||
* logger.info { "..." } // the MDC context contains the mapping here | ||
* } | ||
* ``` | ||
*/ | ||
public class MDCContext( | ||
/** | ||
* The value of [MDC] context map. | ||
*/ | ||
public val contextMap: MDCContextMap = MDC.getCopyOfContextMap() | ||
) : AbstractCoroutineContextElement(Key) { | ||
/** | ||
* Key of [MDCContext] in [CoroutineContext]. | ||
*/ | ||
companion object Key : CoroutineContext.Key<MDCContext> | ||
} | ||
|
||
internal class MDCContextThreadLocal : CoroutineContextThreadLocal<MDCContextMap> { | ||
override fun updateThreadContext(context: CoroutineContext): MDCContextMap { | ||
val oldValue = MDC.getCopyOfContextMap() | ||
val contextMap = context[MDCContext]?.contextMap | ||
if (contextMap == null) { | ||
MDC.clear() | ||
} else { | ||
MDC.setContextMap(contextMap) | ||
} | ||
return oldValue | ||
} | ||
|
||
override fun restoreThreadContext(context: CoroutineContext, oldValue: MDCContextMap) { | ||
if (oldValue == null) { | ||
MDC.clear() | ||
} else { | ||
MDC.setContextMap(oldValue) | ||
} | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
integration/kotlinx-coroutines-slf4j/test-resources/logback-test.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<configuration debug="false"> | ||
|
||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> | ||
<layout> | ||
<Pattern>%X{first} %X{last} - %m%n</Pattern> | ||
</layout> | ||
</appender> | ||
|
||
<root level="DEBUG"> | ||
<appender-ref ref="CONSOLE" /> | ||
</root> | ||
</configuration> | ||
|
||
|
97 changes: 97 additions & 0 deletions
97
integration/kotlinx-coroutines-slf4j/test/MDCContextTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
/* | ||
* Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. | ||
*/ | ||
|
||
package kotlinx.coroutines.experimental.slf4j | ||
|
||
import kotlinx.coroutines.experimental.* | ||
import org.junit.After | ||
import org.junit.Before | ||
import org.junit.Test | ||
import org.slf4j.MDC | ||
import kotlin.coroutines.experimental.* | ||
import kotlin.test.assertEquals | ||
|
||
class MDCContextTest : TestBase() { | ||
@Before | ||
fun setUp() { | ||
MDC.clear() | ||
} | ||
|
||
@After | ||
fun tearDown() { | ||
MDC.clear() | ||
} | ||
|
||
@Test | ||
fun mdcContextIsNotPassedByDefaultBetweenCoroutines() = runTest { | ||
expect(1) | ||
MDC.put("myKey", "myValue") | ||
|
||
launch { | ||
assertEquals(null, MDC.get("myKey")) | ||
expect(2) | ||
}.join() | ||
|
||
finish(3) | ||
} | ||
|
||
@Test | ||
fun mdcContextCanBePassedBetweenCoroutines() = runTest { | ||
expect(1) | ||
MDC.put("myKey", "myValue") | ||
|
||
launch(MDCContext()) { | ||
assertEquals("myValue", MDC.get("myKey")) | ||
expect(2) | ||
}.join() | ||
|
||
finish(3) | ||
} | ||
|
||
@Test | ||
fun mdcContextNotPassedWhileOnMainThread() { | ||
MDC.put("myKey", "myValue") | ||
|
||
runBlocking { | ||
assertEquals(null, MDC.get("myKey")) | ||
} | ||
} | ||
|
||
@Test | ||
fun mdcContextCanBePassedWhileOnMainThread() { | ||
MDC.put("myKey", "myValue") | ||
|
||
runBlocking(MDCContext()) { | ||
assertEquals("myValue", MDC.get("myKey")) | ||
} | ||
} | ||
|
||
@Test | ||
fun mdcContextNeededWithOtherContext() { | ||
MDC.put("myKey", "myValue") | ||
|
||
runBlocking(MDCContext()) { | ||
assertEquals("myValue", MDC.get("myKey")) | ||
} | ||
} | ||
|
||
@Test | ||
fun mdcContextMayBeEmpty() { | ||
runBlocking(MDCContext()) { | ||
assertEquals(null, MDC.get("myKey")) | ||
} | ||
} | ||
|
||
@Test | ||
fun mdcContextWithContext() = runTest { | ||
MDC.put("myKey", "myValue") | ||
val mainDispatcher = kotlin.coroutines.experimental.coroutineContext[ContinuationInterceptor]!! | ||
withContext(DefaultDispatcher + MDCContext()) { | ||
assertEquals("myValue", MDC.get("myKey")) | ||
withContext(mainDispatcher) { | ||
assertEquals("myValue", MDC.get("myKey")) | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters