diff --git a/slf4j-bridge/src/main/scala/zio/logging/slf4j/bridge/Slf4jBridge.scala b/slf4j-bridge/src/main/scala/zio/logging/slf4j/bridge/Slf4jBridge.scala index 4c54bd793..686782578 100644 --- a/slf4j-bridge/src/main/scala/zio/logging/slf4j/bridge/Slf4jBridge.scala +++ b/slf4j-bridge/src/main/scala/zio/logging/slf4j/bridge/Slf4jBridge.scala @@ -16,7 +16,7 @@ package zio.logging.slf4j.bridge import org.slf4j.impl.ZioLoggerFactory -import zio.{ Runtime, ZIO, ZLayer } +import zio.{ Runtime, Semaphore, Unsafe, ZIO, ZLayer } object Slf4jBridge { @@ -46,12 +46,15 @@ object Slf4jBridge { def initialize(nameAnnotationKey: String): ZLayer[Any, Nothing, Unit] = Runtime.enableCurrentFiber ++ layer(nameAnnotationKey) + private val initLock = Semaphore.unsafe.make(1)(Unsafe.unsafe) + private def layer(nameAnnotationKey: String): ZLayer[Any, Nothing, Unit] = ZLayer { - ZIO.runtime[Any].flatMap { runtime => - ZIO.succeed { - ZioLoggerFactory.initialize(new ZioLoggerRuntime(runtime, nameAnnotationKey)) - } - } + for { + runtime <- ZIO.runtime[Any] + _ <- initLock.withPermit { + ZIO.succeed(ZioLoggerFactory.initialize(new ZioLoggerRuntime(runtime, nameAnnotationKey))) + } + } yield () } } diff --git a/slf4j-bridge/src/test/scala/zio/logging/slf4j/bridge/Slf4jBridgeSpec.scala b/slf4j-bridge/src/test/scala/zio/logging/slf4j/bridge/Slf4jBridgeSpec.scala index ac71f0609..86bcb756e 100644 --- a/slf4j-bridge/src/test/scala/zio/logging/slf4j/bridge/Slf4jBridgeSpec.scala +++ b/slf4j-bridge/src/test/scala/zio/logging/slf4j/bridge/Slf4jBridgeSpec.scala @@ -17,6 +17,16 @@ object Slf4jBridgeSpec extends ZIOSpecDefault { override def spec = suite("Slf4jBridge")( + test("parallel init") { + for { + _ <- + ZIO.foreachPar((1 to 5).toList) { _ => + ZIO + .succeed(org.slf4j.LoggerFactory.getLogger("SLF4J-LOGGER").warn("Test {}!", "WARNING")) + .provide(Slf4jBridge.initialize) + } + } yield assertCompletes + }, test("logs through slf4j - legacy logger name annotation key") { val testFailure = new RuntimeException("test error") for { diff --git a/slf4j2-bridge/src/main/scala/zio/logging/slf4j/bridge/Slf4jBridge.scala b/slf4j2-bridge/src/main/scala/zio/logging/slf4j/bridge/Slf4jBridge.scala index 51e455425..716662978 100644 --- a/slf4j2-bridge/src/main/scala/zio/logging/slf4j/bridge/Slf4jBridge.scala +++ b/slf4j2-bridge/src/main/scala/zio/logging/slf4j/bridge/Slf4jBridge.scala @@ -15,7 +15,7 @@ */ package zio.logging.slf4j.bridge -import zio.{ Runtime, ZIO, ZLayer } +import zio.{ Runtime, Semaphore, Unsafe, ZIO, ZLayer } object Slf4jBridge { @@ -29,15 +29,20 @@ object Slf4jBridge { */ def initializeWithoutFiberRefPropagation: ZLayer[Any, Nothing, Unit] = layer + private val initLock = Semaphore.unsafe.make(1)(Unsafe.unsafe) + private def layer: ZLayer[Any, Nothing, Unit] = ZLayer { - ZIO.runtime[Any].flatMap { runtime => - ZIO.succeed { - org.slf4j.LoggerFactory - .getILoggerFactory() - .asInstanceOf[LoggerFactory] - .attacheRuntime(new ZioLoggerRuntime(runtime)) - } - } + for { + runtime <- ZIO.runtime[Any] + _ <- initLock.withPermit { + ZIO.succeed( + org.slf4j.LoggerFactory + .getILoggerFactory() + .asInstanceOf[LoggerFactory] + .attacheRuntime(new ZioLoggerRuntime(runtime)) + ) + } + } yield () } } diff --git a/slf4j2-bridge/src/test/scala/zio/logging/slf4j/bridge/Slf4jBridgeSpec.scala b/slf4j2-bridge/src/test/scala/zio/logging/slf4j/bridge/Slf4jBridgeSpec.scala index 34af42417..c4dd09bbb 100644 --- a/slf4j2-bridge/src/test/scala/zio/logging/slf4j/bridge/Slf4jBridgeSpec.scala +++ b/slf4j2-bridge/src/test/scala/zio/logging/slf4j/bridge/Slf4jBridgeSpec.scala @@ -15,6 +15,16 @@ object Slf4jBridgeSpec extends ZIOSpecDefault { override def spec = suite("Slf4jBridge")( + test("parallel init") { + for { + _ <- + ZIO.foreachPar((1 to 5).toList) { _ => + ZIO + .succeed(org.slf4j.LoggerFactory.getLogger("SLF4J-LOGGER").warn("Test {}!", "WARNING")) + .provide(Slf4jBridge.initialize) + } + } yield assertCompletes + }, test("logs through slf4j") { val testFailure = new RuntimeException("test error") for {