Skip to content

Commit 12a154a

Browse files
committed
Fix #565 - [logger-f-logback-mdc-monix3] is not compatible with logback 1.5.17 due to changes in slf4j 2.0.17
- Update slf4j to 2.0.17, logback to 1.5.17 and logback-scala-interop to 1.17.0 - Add slf4j MDC support to set MDCAdapter in MDC
1 parent 610a93e commit 12a154a

File tree

4 files changed

+109
-10
lines changed

4 files changed

+109
-10
lines changed

build.sbt

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ lazy val loggerF = (project in file("."))
8181
// sbtLoggingJs,
8282
catsJvm,
8383
// catsJs,
84+
slf4jMdcJvm,
85+
// slf4jMdcJs,
8486
logbackMdcMonix3Jvm,
8587
// logbackMdcMonix3Js,
8688
testKitJvm,
@@ -253,6 +255,24 @@ lazy val cats =
253255
lazy val catsJvm = cats.jvm
254256
lazy val catsJs = cats.js
255257

258+
lazy val slf4jMdc = module(ProjectName("slf4j-mdc"), crossProject(JVMPlatform, JSPlatform))
259+
.settings(
260+
description := "Logger for F[_] - A tool to set MDC's MDCAdapter",
261+
libraryDependencies ++= Seq(
262+
libs.slf4jApi,
263+
libs.cats % Test,
264+
) ++ libs.tests.hedgehogLibs,
265+
libraryDependencies := libraryDependenciesRemoveScala3Incompatible(
266+
scalaVersion.value,
267+
libraryDependencies.value,
268+
),
269+
)
270+
.dependsOn(
271+
core
272+
)
273+
lazy val slf4jMdcJvm = slf4jMdc.jvm
274+
lazy val slf4jMdcJs = slf4jMdc.js
275+
256276
lazy val logbackMdcMonix3 = module(ProjectName("logback-mdc-monix3"), crossProject(JVMPlatform, JSPlatform))
257277
.settings(
258278
description := "Logger for F[_] - logback MDC context map support for Monix 3",
@@ -270,6 +290,7 @@ lazy val logbackMdcMonix3 = module(ProjectName("logback-mdc-monix3"), crossPr
270290
)
271291
.dependsOn(
272292
core,
293+
slf4jMdc,
273294
monix % Test,
274295
slf4jLogger % Test,
275296
)
@@ -554,14 +575,14 @@ lazy val props =
554575

555576
final val ExtrasVersion = "0.25.0"
556577

557-
final val Slf4JVersion = "2.0.16"
558-
final val LogbackVersion = "1.5.16"
578+
final val Slf4JVersion = "2.0.17"
579+
final val LogbackVersion = "1.5.17"
559580

560581
final val Log4sVersion = "1.10.0"
561582

562583
final val Log4JVersion = "2.19.0"
563584

564-
val LogbackScalaInteropVersion = "1.16.0"
585+
val LogbackScalaInteropVersion = "1.17.0"
565586
}
566587

567588
lazy val libs =

modules/logger-f-logback-mdc-monix3/shared/src/main/scala/loggerf/logger/logback/Monix3MdcAdapter.scala

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package loggerf.logger.logback
33
import ch.qos.logback.classic.LoggerContext
44
import logback_scala_interop.JLoggerFMdcAdapter
55
import monix.execution.misc.Local
6-
import org.slf4j.{LoggerFactory, MDC}
6+
import org.slf4j.LoggerFactory
77

88
import java.util.{Map => JMap, Set => JSet}
99
import scala.jdk.CollectionConverters._
@@ -45,10 +45,7 @@ trait Monix3MdcAdapterOps {
4545

4646
@SuppressWarnings(Array("org.wartremover.warts.Null"))
4747
protected def initialize0(monix3MdcAdapter: Monix3MdcAdapter): Monix3MdcAdapter = {
48-
val field = classOf[MDC].getDeclaredField("mdcAdapter")
49-
field.setAccessible(true)
50-
field.set(null, monix3MdcAdapter) // scalafix:ok DisableSyntax.null
51-
field.setAccessible(false)
48+
org.slf4j.SetMdcAdapter(monix3MdcAdapter)
5249
monix3MdcAdapter
5350
}
5451

modules/logger-f-logback-mdc-monix3/shared/src/test/scala/loggerf/logger/logback/Monix3MdcAdapterSpec.scala

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@ import cats.syntax.all._
44
import hedgehog._
55
import hedgehog.runner._
66
import monix.eval.{Task, TaskLocal}
7-
import org.slf4j.MDC
7+
import org.slf4j.spi.MDCAdapter
8+
import org.slf4j.{MDC, SetMdcAdapter}
89

10+
import java.io.{PrintWriter, StringWriter}
911
import java.time.Instant
12+
import java.util
1013
import scala.jdk.CollectionConverters._
14+
import scala.util.control.NonFatal
1115

1216
/** @author Kevin Lee
1317
* @since 2023-07-03
@@ -20,7 +24,23 @@ object Monix3MdcAdapterSpec extends Properties {
2024
*/
2125
implicit val opts: Task.Options = Task.defaultOptions.enableLocalContextPropagation
2226

23-
private val monixMdcAdapter: Monix3MdcAdapter = Monix3MdcAdapter.initialize()
27+
@SuppressWarnings(Array("org.wartremover.warts.Throw"))
28+
private val monixMdcAdapter: Monix3MdcAdapter =
29+
try {
30+
Monix3MdcAdapter.initialize()
31+
} catch {
32+
case NonFatal(ex) =>
33+
val writer = new StringWriter()
34+
val out = new PrintWriter(writer)
35+
ex.printStackTrace(out)
36+
System
37+
.err
38+
.println(
39+
s"""Error when initializing Monix3MdcAdapter: ${writer.toString}
40+
|""".stripMargin
41+
)
42+
throw ex // scalafix:ok DisableSyntax.throw
43+
}
2444

2545
override def tests: List[Test] = List(
2646
property("Task - MDC should be able to put and get a value", testPutAndGet),
@@ -39,6 +59,7 @@ object Monix3MdcAdapterSpec extends Properties {
3959
property("Task - MDC: It should return context map for getCopyOfContextMap", testGetCopyOfContextMap),
4060
property("Task - MDC: It should return context map for getPropertyMap", testGetPropertyMap),
4161
property("Task - MDC: It should return context map for getKeys", testGetKeys),
62+
property("test SetMdcAdapter", testSetMdcAdapter),
4263
)
4364

4465
def before(): Unit =
@@ -484,4 +505,48 @@ object Monix3MdcAdapterSpec extends Properties {
484505
}.toMap
485506
}
486507

508+
@SuppressWarnings(Array("org.wartremover.warts.Equals"))
509+
def testSetMdcAdapter: Property = for {
510+
mdcAdapterName1 <- Gen.string(Gen.ascii, Range.linear(5, 5)).log("mdcAdapterName1")
511+
mdcAdapterName2 <- Gen.string(Gen.ascii, Range.linear(5, 5)).log("mdcAdapterName2")
512+
mdcAdapterName <- Gen.constant(mdcAdapterName1 + mdcAdapterName2).log("mdcAdapterName")
513+
} yield {
514+
val mdcAdapter = TestMdcAdapter(mdcAdapterName)
515+
val before = MDC.getMDCAdapter()
516+
517+
SetMdcAdapter(mdcAdapter)
518+
519+
val after = MDC.getMDCAdapter()
520+
521+
Result.all(
522+
List(
523+
Result.diffNamed("before should not be equal to the new MDCAdapter", before, mdcAdapter)(_ != _),
524+
(after ==== mdcAdapter).log("after SetMdcAdapter should be equal to the new MDCAdapter"),
525+
)
526+
)
527+
}
528+
529+
@SuppressWarnings(Array("org.wartremover.warts.Var"))
530+
final case class TestMdcAdapter(name: String) extends MDCAdapter {
531+
532+
override def put(key: String, `val`: String): Unit = ???
533+
534+
override def get(key: String): String = ???
535+
536+
override def remove(key: String): Unit = ???
537+
538+
override def clear(): Unit = ???
539+
540+
override def getCopyOfContextMap: util.Map[String, String] = ???
541+
542+
override def setContextMap(contextMap: util.Map[String, String]): Unit = ???
543+
544+
override def pushByKey(key: String, value: String): Unit = ???
545+
546+
override def popByKey(key: String): String = ???
547+
548+
override def getCopyOfDequeByKey(key: String): util.Deque[String] = ???
549+
550+
override def clearDequeByKey(key: String): Unit = ???
551+
}
487552
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package org.slf4j
2+
3+
import org.slf4j.spi.MDCAdapter
4+
5+
/** @author Kevin Lee
6+
* @since 2025-03-09
7+
*/
8+
trait SetMdcAdapter {
9+
def apply(mdcAdapter: MDCAdapter): Unit
10+
}
11+
12+
object SetMdcAdapter {
13+
def apply(mdcAdapter: MDCAdapter): Unit = {
14+
MDC.setMDCAdapter(mdcAdapter)
15+
}
16+
}

0 commit comments

Comments
 (0)