Skip to content

Commit 34fd7d8

Browse files
committed
Close #441: Update Cats Effect to 3.6.3 and optimize Ce3MdcAdapter (WIP)
- Update cats-effect 3 to `3.6.3` - Optimize `Ce3MdcAdapter` and `Ce3MdcAdapterWithIoRuntime` by caching `localContext.unsafeThreadLocal()` to `threadLocalContext` - Enable `Test / fork` in `logbackMdcCatsEffect3` settings - Update tests in `Ce3MdcAdapterSpec` and `Ce3MdcAdapterWithIoRuntimeSpec` - Enable debug logging in MDC adapters
1 parent 9a9efd3 commit 34fd7d8

File tree

6 files changed

+93
-69
lines changed

6 files changed

+93
-69
lines changed

build.sbt

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -347,17 +347,18 @@ lazy val logbackMdcCatsEffect3 = module(ProjectName("logback-mdc-cats-effect3
347347
.settings(
348348
description := "Logger for F[_] - logback MDC context map support for Cats Effect 3",
349349
libraryDependencies ++= Seq(
350-
libs.logbackClassic,
350+
libs.logbackClassicLatest,
351351
libs.logbackScalaInterop,
352-
libs.catsEffect3,
353-
libs.tests.effectieCatsEffect3,
354-
libs.tests.extrasHedgehogCatsEffect3,
355-
) ++ libs.tests.hedgehogLibs,
352+
libs.libCatsEffect(props.catsEffect3Version).value,
353+
libs.tests.effectieCatsEffect3.value,
354+
libs.tests.extrasHedgehogCatsEffect3.value,
355+
) ++ libs.tests.hedgehogLibs.value,
356356
libraryDependencies := libraryDependenciesRemoveScala3Incompatible(
357357
scalaVersion.value,
358358
libraryDependencies.value,
359359
),
360360
javaOptions += "-Dcats.effect.trackFiberContext=true",
361+
Test / fork := true,
361362
)
362363
.dependsOn(
363364
core,
@@ -432,7 +433,7 @@ lazy val catsEffectJs = catsEffect
432433
jsSettingsForFuture,
433434
)
434435

435-
lazy val catsEffect3 =
436+
lazy val catsEffect3 =
436437
module(ProjectName("cats-effect3"), crossProject(JVMPlatform, JSPlatform))
437438
.settings(
438439
description := "Logger for F[_] - Cats Effect 3",
@@ -447,8 +448,8 @@ lazy val catsEffect3 =
447448
)
448449
.settings(noPublish)
449450
.dependsOn(core % props.IncludeTest, cats)
450-
lazy val catsEffect3Jvm = catsEffect3.jvm
451-
lazy val catsEffect3Js = catsEffect3
451+
lazy val catsEffect3Jvm = catsEffect3.jvm
452+
lazy val catsEffect3Js = catsEffect3
452453
.js
453454
.settings(
454455
jsSettings,
@@ -742,7 +743,7 @@ lazy val props =
742743

743744
final val CatsVersion = "2.12.0"
744745

745-
val catsEffect3Version = "3.3.14"
746+
val catsEffect3Version = "3.6.3"
746747
val catsEffect3ForNativeVersion = "3.7.0-RC1"
747748

748749
val Monix3Version = "3.4.0"

modules/logger-f-logback-mdc-cats-effect3/shared/src/main/scala/loggerf/logger/logback/Ce3MdcAdapter.scala

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import scala.jdk.CollectionConverters._
1414
*/
1515
class Ce3MdcAdapter extends JLoggerFMdcAdapter {
1616

17-
private[this] val localContext: IOLocal[Map[String, String]] =
17+
private[this] lazy val localContext: IOLocal[Map[String, String]] =
1818
IOLocal[Map[String, String]](Map.empty[String, String])
1919
.syncStep(100)
2020
.flatMap(
@@ -26,32 +26,34 @@ class Ce3MdcAdapter extends JLoggerFMdcAdapter {
2626
)
2727
.unsafeRunSync()
2828

29+
private lazy val threadLocalContext: ThreadLocal[Map[String, String]] = localContext.unsafeThreadLocal()
30+
2931
override def put(key: String, `val`: String): Unit = {
30-
val unsafeThreadLocal = localContext.unsafeThreadLocal()
32+
val unsafeThreadLocal = threadLocalContext
3133
unsafeThreadLocal.set(unsafeThreadLocal.get + (key -> `val`))
3234
}
3335

3436
@SuppressWarnings(Array("org.wartremover.warts.Null", "org.wartremover.warts.StringPlusAny"))
3537
override def get(key: String): String =
36-
localContext.unsafeThreadLocal().get.getOrElse(key, null) // scalafix:ok DisableSyntax.null
38+
threadLocalContext.get.getOrElse(key, null) // scalafix:ok DisableSyntax.null
3739

3840
override def remove(key: String): Unit = {
39-
val unsafeThreadLocal = localContext.unsafeThreadLocal()
41+
val unsafeThreadLocal = threadLocalContext
4042
unsafeThreadLocal.set(unsafeThreadLocal.get - key)
4143
}
4244

43-
override def clear(): Unit = localContext.unsafeThreadLocal().set(Map.empty[String, String])
45+
override def clear(): Unit = threadLocalContext.set(Map.empty[String, String])
4446

4547
override def getCopyOfContextMap: JMap[String, String] = getPropertyMap0
4648

4749
override def setContextMap0(contextMap: JMap[String, String]): Unit =
48-
localContext.unsafeThreadLocal().set(contextMap.asScala.toMap)
50+
threadLocalContext.set(contextMap.asScala.toMap)
4951

50-
private def getPropertyMap0: JMap[String, String] = localContext.unsafeThreadLocal().get.asJava
52+
private def getPropertyMap0: JMap[String, String] = threadLocalContext.get.asJava
5153

5254
override def getPropertyMap: JMap[String, String] = getPropertyMap0
5355

54-
override def getKeys: JSet[String] = localContext.unsafeThreadLocal().get.keySet.asJava
56+
override def getKeys: JSet[String] = threadLocalContext.get.keySet.asJava
5557

5658
}
5759
object Ce3MdcAdapter extends Ce3MdcAdapterOps
@@ -86,13 +88,13 @@ trait Ce3MdcAdapterOps {
8688

8789
loggerContext.setMDCAdapter(adapter)
8890
if (loggerContext.getMDCAdapter == adapter) {
89-
// println("[LoggerContext] It's set by setMDCAdapter.")
91+
println("[DEBUG][LoggerContext] It's set by setMDCAdapter.")
9092
adapter
9193
} else {
92-
// println(
93-
// "[LoggerContext] The old setMDCAdapter doesn't replace `mdcAdapter` if it has already been set, " +
94-
// "so it will use reflection to set it in the `mdcAdapter` field."
95-
// )
94+
println(
95+
"[DEBUG][LoggerContext] The old setMDCAdapter doesn't replace `mdcAdapter` if it has already been set, " +
96+
"so it will use reflection to set it in the `mdcAdapter` field."
97+
)
9698
val loggerContextClass = classOf[LoggerContext]
9799
val field = loggerContextClass.getDeclaredField("mdcAdapter")
98100
field.setAccessible(true)

modules/logger-f-logback-mdc-cats-effect3/shared/src/main/scala/loggerf/logger/logback/Ce3MdcAdapterWithIoRuntime.scala

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,32 +17,34 @@ class Ce3MdcAdapterWithIoRuntime(private val ioRuntime: unsafe.IORuntime) extend
1717
IOLocal[Map[String, String]](Map.empty[String, String])
1818
.unsafeRunSync()(ioRuntime)
1919

20+
private lazy val threadLocalContext: ThreadLocal[Map[String, String]] = localContext.unsafeThreadLocal()
21+
2022
override def put(key: String, `val`: String): Unit = {
21-
val unsafeThreadLocal = localContext.unsafeThreadLocal()
23+
val unsafeThreadLocal = threadLocalContext
2224
unsafeThreadLocal.set(unsafeThreadLocal.get + (key -> `val`))
2325
}
2426

25-
@SuppressWarnings(Array("org.wartremover.warts.Null", "org.wartremover.warts.StringPlusAny"))
27+
@SuppressWarnings(Array("org.wartremover.warts.Null"))
2628
override def get(key: String): String =
27-
localContext.unsafeThreadLocal().get.getOrElse(key, null) // scalafix:ok DisableSyntax.null
29+
threadLocalContext.get.getOrElse(key, null) // scalafix:ok DisableSyntax.null
2830

2931
override def remove(key: String): Unit = {
30-
val unsafeThreadLocal = localContext.unsafeThreadLocal()
32+
val unsafeThreadLocal = threadLocalContext
3133
unsafeThreadLocal.set(unsafeThreadLocal.get - key)
3234
}
3335

34-
override def clear(): Unit = localContext.unsafeThreadLocal().set(Map.empty[String, String])
36+
override def clear(): Unit = threadLocalContext.set(Map.empty[String, String])
3537

3638
override def getCopyOfContextMap: JMap[String, String] = getPropertyMap0
3739

3840
override def setContextMap0(contextMap: JMap[String, String]): Unit =
39-
localContext.unsafeThreadLocal().set(contextMap.asScala.toMap)
41+
threadLocalContext.set(contextMap.asScala.toMap)
4042

41-
private def getPropertyMap0: JMap[String, String] = localContext.unsafeThreadLocal().get.asJava
43+
private def getPropertyMap0: JMap[String, String] = threadLocalContext.get.asJava
4244

4345
override def getPropertyMap: JMap[String, String] = getPropertyMap0
4446

45-
override def getKeys: JSet[String] = localContext.unsafeThreadLocal().get.keySet.asJava
47+
override def getKeys: JSet[String] = threadLocalContext.get.keySet.asJava
4648

4749
}
4850
object Ce3MdcAdapterWithIoRuntime extends Ce3MdcAdapterWithIoRuntimeOps
@@ -82,13 +84,13 @@ trait Ce3MdcAdapterWithIoRuntimeOps {
8284

8385
loggerContext.setMDCAdapter(adapter)
8486
if (loggerContext.getMDCAdapter == adapter) {
85-
// println("[LoggerContext] It's set by setMDCAdapter.")
87+
println("[LoggerContext] It's set by setMDCAdapter.")
8688
adapter
8789
} else {
88-
// println(
89-
// "[LoggerContext] The old setMDCAdapter doesn't replace `mdcAdapter` if it has already been set, " +
90-
// "so it will use reflection to set it in the `mdcAdapter` field."
91-
// )
90+
println(
91+
"[LoggerContext] The old setMDCAdapter doesn't replace `mdcAdapter` if it has already been set, " +
92+
"so it will use reflection to set it in the `mdcAdapter` field."
93+
)
9294
val loggerContextClass = classOf[LoggerContext]
9395
val field = loggerContextClass.getDeclaredField("mdcAdapter")
9496
field.setAccessible(true)

modules/logger-f-logback-mdc-cats-effect3/shared/src/test/scala/loggerf/logger/logback/Ce3MdcAdapterSpec.scala

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@ import scala.jdk.CollectionConverters._
1414
* @since 2023-07-07
1515
*/
1616
object Ce3MdcAdapterSpec extends Properties {
17+
println(
18+
s"${this.getClass.getSimpleName.stripSuffix("$")}[B] cats.effect.trackFiberContext=${sys.props.getOrElse("cats.effect.trackFiberContext", "NOT SET")}"
19+
)
1720
private val oldValue = sys.props.put("cats.effect.trackFiberContext", "true")
1821
println(
19-
s"${this.getClass.getSimpleName.stripSuffix("$")}[B] cats.effect.trackFiberContext=${oldValue.getOrElse("")}"
22+
s"${this.getClass.getSimpleName.stripSuffix("$")}[B] cats.effect.trackFiberContext=${oldValue.getOrElse("NOT SET")}"
2023
)
2124
println(
2225
s"${this.getClass.getSimpleName.stripSuffix("$")}[A] cats.effect.trackFiberContext=${sys.props.getOrElse("cats.effect.trackFiberContext", "")}"
@@ -102,13 +105,13 @@ object Ce3MdcAdapterSpec extends Properties {
102105

103106
before()
104107

105-
val beforeSet = (MDC.get("key-1") ==== null).log("before set") // scalafix:ok DisableSyntax.null
106-
MDC.put("key-1", a)
108+
// val beforeSet = (MDC.get("key-1") ==== null).log("before set") // scalafix:ok DisableSyntax.null
109+
// MDC.put("key-1", a)
107110

108-
val afterBeforeSetBeforeBefore = (MDC.get("key-1") ==== a).log("after beforeSet and before before")
111+
// val afterBeforeSetBeforeBefore = (MDC.get("key-1") ==== a).log("after beforeSet and before before")
109112

110113
val test = for {
111-
// _ <- IO(MDC.put("key-1", a))
114+
_ <- IO(MDC.put("key-1", a))
112115
before <- IO((MDC.get("key-1") ==== a).log("before"))
113116
beforeIsolated <- IO((MDC.get("key-1") ==== a).log("beforeIsolated"))
114117
.start
@@ -139,8 +142,8 @@ object Ce3MdcAdapterSpec extends Properties {
139142
) // scalafix:ok DisableSyntax.null
140143
} yield Result.all(
141144
List(
142-
beforeSet,
143-
afterBeforeSetBeforeBefore,
145+
// beforeSet,
146+
// afterBeforeSetBeforeBefore,
144147
before,
145148
beforeIsolated,
146149
isolated1Before,
@@ -178,12 +181,20 @@ object Ce3MdcAdapterSpec extends Properties {
178181
.log(s"""after beforeSet: MDC.get("key-1") should be $a2""") // scalafix:ok DisableSyntax.null
179182

180183
val test = for {
181-
// beforeSet2 <- IO((MDC.get("key-1") ==== a2).log(s"""before set2: MDC.get("key-1") should be $a2""")) // scalafix:ok DisableSyntax.null
182-
// _ <- IO(MDC.put("key-1", a))
183-
beforeSet2 <- IO(
184-
(MDC.get("key-1") ==== a).log(s"""before set2: MDC.get("key-1") should be $a""")
185-
) // scalafix:ok DisableSyntax.null
186-
before <-
184+
beforeBeforeSet1 <- IO(
185+
(MDC.get("key-1") ==== null)
186+
.log(s"""before `before set(key-1) with $a2`: MDC.get("key-1") should be null""")
187+
) // scalafix:ok DisableSyntax.null
188+
_ <- IO(MDC.put("key-1", a2))
189+
beforeBeforeSet2 <-
190+
IO(
191+
(MDC.get("key-1") ==== a2).log(s"""before `before set(key-1) with $a`: MDC.get("key-1") should be $a2""")
192+
) // scalafix:ok DisableSyntax.null
193+
_ <- IO(MDC.put("key-1", a))
194+
beforeSet2 <- IO(
195+
(MDC.get("key-1") ==== a).log(s"""before set2: MDC.get("key-1") should be $a""")
196+
) // scalafix:ok DisableSyntax.null
197+
before <-
187198
IO {
188199
val actual1 = MDC.get("key-1")
189200
val actual2 = MDC.get("key-2")
@@ -198,12 +209,12 @@ object Ce3MdcAdapterSpec extends Properties {
198209
), // scalafix:ok DisableSyntax.null
199210
)
200211
}
201-
beforeIsolated <- IO {
202-
val actual = MDC.get("key-1")
203-
(actual ==== a).log(s"""beforeIsolated: MDC.get("key-1") should be $a, but it is $actual""")
204-
}
205-
.start
206-
.flatMap(_.joinWithNever)
212+
beforeIsolated <- IO {
213+
val actual = MDC.get("key-1")
214+
(actual ==== a).log(s"""beforeIsolated: MDC.get("key-1") should be $a, but it is $actual""")
215+
}
216+
.start
217+
.flatMap(_.joinWithNever)
207218

208219
isolated1 <-
209220
(
@@ -306,6 +317,8 @@ object Ce3MdcAdapterSpec extends Properties {
306317
} yield List(
307318
beforeSet,
308319
afterBeforeSet,
320+
beforeBeforeSet1,
321+
beforeBeforeSet2,
309322
beforeSet2,
310323
) ++ before ++ List(
311324
beforeIsolated

modules/logger-f-logback-mdc-cats-effect3/shared/src/test/scala/loggerf/logger/logback/Ce3MdcAdapterWithIoRuntimeSpec.scala

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,13 @@ object Ce3MdcAdapterWithIoRuntimeSpec extends Properties {
102102

103103
before()
104104

105-
val beforeSet = (MDC.get("key-1") ==== null).log("before set") // scalafix:ok DisableSyntax.null
106-
MDC.put("key-1", a)
107-
val afterBeforeSet = (MDC.get("key-1") ==== a).log("""after beforeSet: `MDC.get("key-1") ==== a` failed""")
105+
// val beforeSet = (MDC.get("key-1") ==== null).log("before set") // scalafix:ok DisableSyntax.null
106+
// MDC.put("key-1", a)
107+
// val afterBeforeSet = (MDC.get("key-1") ==== a).log("""after beforeSet: `MDC.get("key-1") ==== a` failed""")
108108

109109
val test = for {
110-
// _ <- IO(MDC.put("key-1", a))
110+
beforeSet <- IO((MDC.get("key-1") ==== null).log("before set")) // scalafix:ok DisableSyntax.null
111+
_ <- IO(MDC.put("key-1", a))
111112
before <- IO((MDC.get("key-1") ==== a).log("before"))
112113
beforeIsolated <- IO((MDC.get("key-1") ==== a).log("beforeIsolated"))
113114
.start
@@ -130,16 +131,19 @@ object Ce3MdcAdapterWithIoRuntimeSpec extends Properties {
130131

131132
joinedIsolated1 <- isolated1.joinWithNever
132133
joinedIsolated2 <- isolated2.joinWithNever
134+
133135
(isolated1Before, isolated1After) = joinedIsolated1
136+
134137
(isolated2Before, isolated2After) = joinedIsolated2
138+
135139
key1Result <- IO((MDC.get("key-1") ==== a).log(s"""After: MDC.get("key-1") is not $a"""))
136140
key2Result <- IO(
137141
(MDC.get("key-2") ==== null).log("""After: MDC.get("key-2") is not null""")
138142
) // scalafix:ok DisableSyntax.null
139143
} yield Result.all(
140144
List(
141145
beforeSet,
142-
afterBeforeSet,
146+
// afterBeforeSet,
143147
before,
144148
beforeIsolated,
145149
isolated1Before,
@@ -170,13 +174,15 @@ object Ce3MdcAdapterWithIoRuntimeSpec extends Properties {
170174

171175
before()
172176

173-
val beforeSet = (MDC.get("key-1") ==== null).log("before set") // scalafix:ok DisableSyntax.null
174-
MDC.put("key-1", a2)
175-
val afterBeforeSet =
176-
(MDC.get("key-1") ==== a2)
177-
.log(s"""after beforeSet: MDC.get("key-1") should be $a2""") // scalafix:ok DisableSyntax.null
177+
// val beforeSet = (MDC.get("key-1") ==== null).log("before set") // scalafix:ok DisableSyntax.null
178+
// MDC.put("key-1", a2)
179+
// val afterBeforeSet =
180+
// (MDC.get("key-1") ==== a2)
181+
// .log(s"""after beforeSet: MDC.get("key-1") should be $a2""") // scalafix:ok DisableSyntax.null
178182

179183
val test = for {
184+
beforeSet <- IO((MDC.get("key-1") ==== null).log("before set")) // scalafix:ok DisableSyntax.null
185+
_ <- IO(MDC.put("key-1", a2))
180186
beforeSet1 <- IO((MDC.get("key-1") ==== a2).log("before set2")) // scalafix:ok DisableSyntax.null
181187
_ <- IO(MDC.put("key-1", a))
182188
beforeSet2 <- IO(
@@ -305,7 +311,7 @@ object Ce3MdcAdapterWithIoRuntimeSpec extends Properties {
305311
) // scalafix:ok DisableSyntax.null
306312
} yield List(
307313
beforeSet,
308-
afterBeforeSet,
314+
// afterBeforeSet,
309315
beforeSet1,
310316
beforeSet2,
311317
) ++ before ++ List(

modules/logger-f-slf4j-mdc/shared/src/main/scala/org/slf4j/SetMdcAdapter.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ object SetMdcAdapter {
1818
try {
1919
val method = mdcClass.getDeclaredMethod("setMDCAdapter", classOf[MDCAdapter])
2020
val _ = method.invoke(null, mdcAdapter) // scalafix:ok DisableSyntax.null
21-
// println("[MDC] A method named `setMDCAdapter` was found, so it was set using `setMDCAdapter` with reflection.")
21+
println("[debug][MDC] A method named `setMDCAdapter` was found, so it was set using `setMDCAdapter` with reflection.")
2222
()
2323
} catch {
2424
case NonFatal(_) =>
25-
// println(
26-
// "[MDC] No method named `setMDCAdapter` was found, so it will instead be set to the `mdcAdapter` field using reflection."
27-
// )
25+
println(
26+
"[debug][MDC] No method named `setMDCAdapter` was found, so it will instead be set to the `mdcAdapter` field using reflection."
27+
)
2828
val field = mdcClass.getDeclaredField("mdcAdapter")
2929
field.setAccessible(true)
3030
field.set(null, mdcAdapter) // scalafix:ok DisableSyntax.null

0 commit comments

Comments
 (0)