diff --git a/build.sbt b/build.sbt index 32586ea9..36fce16e 100644 --- a/build.sbt +++ b/build.sbt @@ -139,7 +139,7 @@ lazy val slf4j2Bridge = project .settings(enableZIO()) .settings(mimaSettings(failOnProblem = true)) .settings( - compileOrder := CompileOrder.JavaThenScala, + compileOrder := CompileOrder.ScalaThenJava, javacOptions := jpmsOverwriteModulePath((Compile / dependencyClasspath).value.map(_.data))(javacOptions.value), javaOptions := jpmsOverwriteModulePath((Compile / dependencyClasspath).value.map(_.data))(javaOptions.value), Compile / doc / sources := Seq.empty // module-info.java compilation issue diff --git a/core/jvm/src/test/scala/zio/logging/LoggerNameExtractorSpec.scala b/core/jvm/src/test/scala/zio/logging/LoggerNameExtractorSpec.scala index 4d0aa832..cc0132c3 100644 --- a/core/jvm/src/test/scala/zio/logging/LoggerNameExtractorSpec.scala +++ b/core/jvm/src/test/scala/zio/logging/LoggerNameExtractorSpec.scala @@ -56,6 +56,18 @@ object LoggerNameExtractorSpec extends ZIOSpecDefault { assertTrue(result == Some(value)) } }, + test("loggerNameAnnotationOrTrace with empty trace") { + val extractor = LoggerNameExtractor.loggerNameAnnotationOrTrace + check(Gen.alphaNumericString) { annotation => + val annotations = Map(loggerNameAnnotationKey -> annotation) + val result = extractor( + Trace.empty, + FiberRefs.empty, + annotations + ) + assertTrue(result == Some(annotation)) + } + }, test("trace") { val extractor = LoggerNameExtractor.trace check(Gen.alphaNumericString) { trace => diff --git a/slf4j-bridge/src/main/java/org/slf4j/helpers/ZioLoggerBase.java b/slf4j-bridge/src/main/java/org/slf4j/helpers/ZioLoggerBase.java index e9c1ad1f..b991e923 100644 --- a/slf4j-bridge/src/main/java/org/slf4j/helpers/ZioLoggerBase.java +++ b/slf4j-bridge/src/main/java/org/slf4j/helpers/ZioLoggerBase.java @@ -26,7 +26,7 @@ public ZioLoggerBase(String name) { abstract protected void log(Level level, Marker marker, String messagePattern, Object[] arguments, Throwable throwable); - abstract protected boolean isEnabled(String name, Level level); + abstract protected boolean isEnabled(Level level); private void logWithThrowable(Level level, Marker marker, String msg, Throwable t) { log(level, marker, msg, null, t); @@ -56,27 +56,27 @@ private void logWithArgs(Level level, Marker marker, String msg, Object[] args) @Override public boolean isTraceEnabled() { - return isEnabled(name, Level.TRACE); + return isEnabled(Level.TRACE); } @Override public boolean isDebugEnabled() { - return isEnabled(name, Level.DEBUG); + return isEnabled(Level.DEBUG); } @Override public boolean isErrorEnabled() { - return isEnabled(name, Level.ERROR); + return isEnabled(Level.ERROR); } @Override public boolean isWarnEnabled() { - return isEnabled(name, Level.WARN); + return isEnabled(Level.WARN); } @Override public boolean isInfoEnabled() { - return isEnabled(name, Level.INFO); + return isEnabled(Level.INFO); } @Override diff --git a/slf4j-bridge/src/main/scala/org/slf4j/impl/LoggerRuntime.scala b/slf4j-bridge/src/main/scala/org/slf4j/impl/LoggerRuntime.scala index ac342f00..2c4e5eb4 100644 --- a/slf4j-bridge/src/main/scala/org/slf4j/impl/LoggerRuntime.scala +++ b/slf4j-bridge/src/main/scala/org/slf4j/impl/LoggerRuntime.scala @@ -17,11 +17,12 @@ package org.slf4j.impl import org.slf4j.Marker import org.slf4j.event.Level +import zio.logging.slf4j.bridge.LoggerData trait LoggerRuntime { def log( - name: String, + logger: LoggerData, level: Level, marker: Marker, messagePattern: String, @@ -29,5 +30,5 @@ trait LoggerRuntime { throwable: Throwable ): Unit - def isEnabled(name: String, level: Level): Boolean + def isEnabled(logger: LoggerData, level: Level): Boolean } diff --git a/slf4j-bridge/src/main/scala/org/slf4j/impl/ZioLogger.scala b/slf4j-bridge/src/main/scala/org/slf4j/impl/ZioLogger.scala index 29459812..cb504443 100644 --- a/slf4j-bridge/src/main/scala/org/slf4j/impl/ZioLogger.scala +++ b/slf4j-bridge/src/main/scala/org/slf4j/impl/ZioLogger.scala @@ -18,8 +18,11 @@ package org.slf4j.impl import org.slf4j.Marker import org.slf4j.event.Level import org.slf4j.helpers.ZioLoggerBase +import zio.logging.slf4j.bridge.LoggerData final class ZioLogger(name: String, factory: ZioLoggerFactory) extends ZioLoggerBase(name) { + private val data: LoggerData = LoggerData(name) + override protected def log( level: Level, marker: Marker, @@ -27,7 +30,7 @@ final class ZioLogger(name: String, factory: ZioLoggerFactory) extends ZioLogger arguments: Array[AnyRef], throwable: Throwable ): Unit = - factory.log(name, level, marker, messagePattern, arguments, throwable) + factory.log(data, level, marker, messagePattern, arguments, throwable) - override protected def isEnabled(name: String, level: Level): Boolean = factory.isEnabled(name, level) + override protected def isEnabled(level: Level): Boolean = factory.isEnabled(data, level) } diff --git a/slf4j-bridge/src/main/scala/org/slf4j/impl/ZioLoggerFactory.scala b/slf4j-bridge/src/main/scala/org/slf4j/impl/ZioLoggerFactory.scala index 6a453689..e96d4a8c 100644 --- a/slf4j-bridge/src/main/scala/org/slf4j/impl/ZioLoggerFactory.scala +++ b/slf4j-bridge/src/main/scala/org/slf4j/impl/ZioLoggerFactory.scala @@ -17,11 +17,12 @@ package org.slf4j.impl import org.slf4j.event.Level import org.slf4j.{ ILoggerFactory, Logger, Marker } +import zio.logging.slf4j.bridge.LoggerData import java.util.concurrent.ConcurrentHashMap import scala.jdk.CollectionConverters._ -class ZioLoggerFactory extends ILoggerFactory { +final class ZioLoggerFactory extends ILoggerFactory { private var runtime: LoggerRuntime = null private val loggers = new ConcurrentHashMap[String, Logger]().asScala @@ -29,17 +30,17 @@ class ZioLoggerFactory extends ILoggerFactory { this.runtime = runtime private[impl] def log( - name: String, + logger: LoggerData, level: Level, marker: Marker, messagePattern: String, arguments: Array[AnyRef], throwable: Throwable ): Unit = - if (runtime != null) runtime.log(name, level, marker, messagePattern, arguments, throwable) + if (runtime != null) runtime.log(logger, level, marker, messagePattern, arguments, throwable) - private[impl] def isEnabled(name: String, level: Level): Boolean = - if (runtime != null) runtime.isEnabled(name, level) else false + private[impl] def isEnabled(logger: LoggerData, level: Level): Boolean = + if (runtime != null) runtime.isEnabled(logger, level) else false override def getLogger(name: String): Logger = loggers.getOrElseUpdate(name, new ZioLogger(name, this)) diff --git a/slf4j2-bridge/src/main/java/zio/logging/slf4j/bridge/LoggerRuntime.java b/slf4j-bridge/src/main/scala/zio/logging/slf4j/bridge/LoggerData.scala similarity index 65% rename from slf4j2-bridge/src/main/java/zio/logging/slf4j/bridge/LoggerRuntime.java rename to slf4j-bridge/src/main/scala/zio/logging/slf4j/bridge/LoggerData.scala index 02eab4ff..98106cef 100644 --- a/slf4j2-bridge/src/main/java/zio/logging/slf4j/bridge/LoggerRuntime.java +++ b/slf4j-bridge/src/main/scala/zio/logging/slf4j/bridge/LoggerData.scala @@ -13,15 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package zio.logging.slf4j.bridge; +package zio.logging.slf4j.bridge -import org.slf4j.event.KeyValuePair; -import org.slf4j.event.Level; +final case class LoggerData(name: String) { -import java.util.List; + lazy val annotations: Map[String, String] = Map(zio.logging.loggerNameAnnotationKey -> name) -interface LoggerRuntime { - void log(String name, Level level, String messagePattern, Object[] arguments, Throwable throwable, List keyValues); - - boolean isEnabled(String name, Level level); } diff --git a/slf4j-bridge/src/main/scala/zio/logging/slf4j/bridge/ZioLoggerRuntime.scala b/slf4j-bridge/src/main/scala/zio/logging/slf4j/bridge/ZioLoggerRuntime.scala index af13bb91..a6655461 100644 --- a/slf4j-bridge/src/main/scala/zio/logging/slf4j/bridge/ZioLoggerRuntime.scala +++ b/slf4j-bridge/src/main/scala/zio/logging/slf4j/bridge/ZioLoggerRuntime.scala @@ -25,7 +25,7 @@ import zio.{ Cause, Fiber, FiberId, FiberRef, FiberRefs, LogLevel, Runtime, Trac final class ZioLoggerRuntime(runtime: Runtime[Any], filter: LogFilter[Any]) extends LoggerRuntime { override def log( - name: String, + logger: LoggerData, level: Level, marker: Marker, messagePattern: String, @@ -44,14 +44,13 @@ final class ZioLoggerRuntime(runtime: Runtime[Any], filter: LogFilter[Any]) exte runtime.fiberRefs.joinAs(fiberId)(currentFiber.unsafe.getFiberRefs()) } - val logSpan = zio.LogSpan(name, java.lang.System.currentTimeMillis()) - val loggerName = (zio.logging.loggerNameAnnotationKey -> name) + val logSpan = zio.LogSpan(logger.name, java.lang.System.currentTimeMillis()) val fiberRefs = currentFiberRefs .updatedAs(fiberId)(FiberRef.currentLogSpan, logSpan :: currentFiberRefs.getOrDefault(FiberRef.currentLogSpan)) .updatedAs(fiberId)( FiberRef.currentLogAnnotations, - currentFiberRefs.getOrDefault(FiberRef.currentLogAnnotations) + loggerName + currentFiberRefs.getOrDefault(FiberRef.currentLogAnnotations) ++ logger.annotations ) val fiberRuntime = zio.internal.FiberRuntime(fiberId, fiberRefs, runtime.runtimeFlags) @@ -71,18 +70,18 @@ final class ZioLoggerRuntime(runtime: Runtime[Any], filter: LogFilter[Any]) exte fiberRuntime.log(() => msg, cause, Some(logLevel), trace) } - override def isEnabled(name: String, level: Level): Boolean = { + override def isEnabled(logger: LoggerData, level: Level): Boolean = { val logLevel = ZioLoggerRuntime.logLevelMapping(level) filter( - Trace(name, "", 0), + Trace.empty, FiberId.None, logLevel, () => "", Cause.empty, FiberRefs.empty, List.empty, - Map(zio.logging.loggerNameAnnotationKey -> name) + logger.annotations ) } diff --git a/slf4j2-bridge/src/main/java/zio/logging/slf4j/bridge/Logger.java b/slf4j2-bridge/src/main/java/zio/logging/slf4j/bridge/Logger.java deleted file mode 100644 index 37dc2c54..00000000 --- a/slf4j2-bridge/src/main/java/zio/logging/slf4j/bridge/Logger.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2019-2024 John A. De Goes and the ZIO Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package zio.logging.slf4j.bridge; - -import org.slf4j.Marker; -import org.slf4j.event.Level; -import org.slf4j.event.LoggingEvent; -import org.slf4j.helpers.AbstractLogger; -import org.slf4j.spi.LoggingEventAware; - -import java.util.Collections; - -final class Logger extends AbstractLogger implements LoggingEventAware { - - private LoggerFactory factory; - - Logger(String name, LoggerFactory factory) { - this.name = name; - this.factory = factory; - } - - @Override - protected String getFullyQualifiedCallerName() { - return null; - } - - @Override - protected void handleNormalizedLoggingCall(Level level, Marker marker, String messagePattern, Object[] arguments, Throwable throwable) { - factory.log(name, level, messagePattern, arguments, throwable, Collections.emptyList()); - } - - @Override - public boolean isTraceEnabled() { - return factory.isEnabled(name, Level.TRACE); - } - - @Override - public boolean isTraceEnabled(Marker marker) { - return isTraceEnabled(); - } - - @Override - public boolean isDebugEnabled() { - return factory.isEnabled(name, Level.DEBUG); - } - - @Override - public boolean isDebugEnabled(Marker marker) { - return isDebugEnabled(); - } - - @Override - public boolean isInfoEnabled() { - return factory.isEnabled(name, Level.INFO); - } - - @Override - public boolean isInfoEnabled(Marker marker) { - return isInfoEnabled(); - } - - @Override - public boolean isWarnEnabled() { - return factory.isEnabled(name, Level.WARN); - } - - @Override - public boolean isWarnEnabled(Marker marker) { - return isWarnEnabled(); - } - - @Override - public boolean isErrorEnabled() { - return factory.isEnabled(name, Level.ERROR); - } - - @Override - public boolean isErrorEnabled(Marker marker) { - return isErrorEnabled(); - } - - @Override - public void log(LoggingEvent event) { - if (factory.isEnabled(name, event.getLevel())) { - factory.log(name, event.getLevel(), event.getMessage(), event.getArgumentArray(), event.getThrowable(), event.getKeyValuePairs()); - } - } -} diff --git a/slf4j2-bridge/src/main/java/zio/logging/slf4j/bridge/LoggerFactory.java b/slf4j2-bridge/src/main/java/zio/logging/slf4j/bridge/LoggerFactory.java deleted file mode 100644 index 6c489cb3..00000000 --- a/slf4j2-bridge/src/main/java/zio/logging/slf4j/bridge/LoggerFactory.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2019-2024 John A. De Goes and the ZIO Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package zio.logging.slf4j.bridge; - -import org.slf4j.ILoggerFactory; -import org.slf4j.Marker; -import org.slf4j.event.KeyValuePair; -import org.slf4j.event.Level; - -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -final class LoggerFactory implements ILoggerFactory { - - private Map loggers = new ConcurrentHashMap(); - - private LoggerRuntime runtime = null; - - void attachRuntime(LoggerRuntime runtime) { - this.runtime = runtime; - } - - void log(String name, Level level, String messagePattern, Object[] arguments, Throwable throwable, List keyValues) { - if (runtime != null) { - runtime.log(name, level, messagePattern, arguments, throwable, keyValues); - } - } - - boolean isEnabled(String name, Level level) { - if (runtime != null) { - return runtime.isEnabled(name, level); - } else { - return false; - } - } - - @Override - public org.slf4j.Logger getLogger(String name) { - return loggers.computeIfAbsent(name, n -> new Logger(n, this)); - } -} diff --git a/slf4j2-bridge/src/main/java/zio/logging/slf4j/bridge/ZioSLF4JServiceProvider.java b/slf4j2-bridge/src/main/java/zio/logging/slf4j/bridge/ZioSLF4JServiceProvider.java index 2045e58e..d1817247 100644 --- a/slf4j2-bridge/src/main/java/zio/logging/slf4j/bridge/ZioSLF4JServiceProvider.java +++ b/slf4j2-bridge/src/main/java/zio/logging/slf4j/bridge/ZioSLF4JServiceProvider.java @@ -52,7 +52,7 @@ public String getRequestedApiVersion() { @Override public void initialize() { markerFactory = new BasicMarkerFactory(); - loggerFactory = new LoggerFactory(); + loggerFactory = new ZioLoggerFactory(); mdcAdapter = new BasicMDCAdapter(); } } diff --git a/slf4j2-bridge/src/main/scala/zio/logging/slf4j/bridge/LoggerData.scala b/slf4j2-bridge/src/main/scala/zio/logging/slf4j/bridge/LoggerData.scala new file mode 100644 index 00000000..98106cef --- /dev/null +++ b/slf4j2-bridge/src/main/scala/zio/logging/slf4j/bridge/LoggerData.scala @@ -0,0 +1,22 @@ +/* + * Copyright 2019-2024 John A. De Goes and the ZIO Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package zio.logging.slf4j.bridge + +final case class LoggerData(name: String) { + + lazy val annotations: Map[String, String] = Map(zio.logging.loggerNameAnnotationKey -> name) + +} diff --git a/slf4j2-bridge/src/main/scala/zio/logging/slf4j/bridge/LoggerRuntime.scala b/slf4j2-bridge/src/main/scala/zio/logging/slf4j/bridge/LoggerRuntime.scala new file mode 100644 index 00000000..f1f54f1c --- /dev/null +++ b/slf4j2-bridge/src/main/scala/zio/logging/slf4j/bridge/LoggerRuntime.scala @@ -0,0 +1,32 @@ +/* + * Copyright 2019-2024 John A. De Goes and the ZIO Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package zio.logging.slf4j.bridge + +import org.slf4j.event.{ KeyValuePair, Level } + +trait LoggerRuntime { + + def log( + logger: LoggerData, + level: Level, + messagePattern: String, + arguments: Array[AnyRef], + throwable: Throwable, + keyValues: java.util.List[KeyValuePair] + ): Unit + + def isEnabled(logger: LoggerData, level: Level): Boolean +} 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 9240b145..05a0b0cb 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 @@ -65,12 +65,7 @@ object Slf4jBridge { for { runtime <- ZIO.runtime[Any] _ <- initLock.withPermit { - ZIO.succeed( - org.slf4j.LoggerFactory - .getILoggerFactory() - .asInstanceOf[LoggerFactory] - .attachRuntime(new ZioLoggerRuntime(runtime, filter)) - ) + ZIO.succeed(ZioLoggerFactory.initialize(new ZioLoggerRuntime(runtime, filter))) } } yield () diff --git a/slf4j2-bridge/src/main/scala/zio/logging/slf4j/bridge/ZioLogger.scala b/slf4j2-bridge/src/main/scala/zio/logging/slf4j/bridge/ZioLogger.scala new file mode 100644 index 00000000..af906c39 --- /dev/null +++ b/slf4j2-bridge/src/main/scala/zio/logging/slf4j/bridge/ZioLogger.scala @@ -0,0 +1,59 @@ +package zio.logging.slf4j.bridge + +import org.slf4j.Marker +import org.slf4j.event.{ KeyValuePair, Level, LoggingEvent } +import org.slf4j.helpers.AbstractLogger +import org.slf4j.spi.LoggingEventAware + +import java.util.Collections; + +final class ZioLogger private[bridge] (name: String, factory: ZioLoggerFactory) + extends AbstractLogger + with LoggingEventAware { + + private val data: LoggerData = LoggerData(name) + + override def getName: String = name + + override protected def getFullyQualifiedCallerName: String = null + + override protected def handleNormalizedLoggingCall( + level: Level, + marker: Marker, + messagePattern: String, + arguments: Array[AnyRef], + throwable: Throwable + ): Unit = + factory.log(data, level, messagePattern, arguments, throwable, Collections.emptyList[KeyValuePair]()) + + override def isTraceEnabled: Boolean = factory.isEnabled(data, Level.TRACE) + + override def isTraceEnabled(marker: Marker): Boolean = isTraceEnabled + + override def isDebugEnabled: Boolean = factory.isEnabled(data, Level.DEBUG) + + override def isDebugEnabled(marker: Marker): Boolean = isDebugEnabled + + override def isInfoEnabled: Boolean = factory.isEnabled(data, Level.INFO) + + override def isInfoEnabled(marker: Marker): Boolean = isInfoEnabled + + override def isWarnEnabled: Boolean = factory.isEnabled(data, Level.WARN) + + override def isWarnEnabled(marker: Marker): Boolean = isWarnEnabled + + override def isErrorEnabled: Boolean = factory.isEnabled(data, Level.ERROR) + + override def isErrorEnabled(marker: Marker): Boolean = isErrorEnabled + + override def log(event: LoggingEvent): Unit = + if (factory.isEnabled(data, event.getLevel)) + factory.log( + data, + event.getLevel, + event.getMessage, + event.getArgumentArray, + event.getThrowable, + event.getKeyValuePairs + ) +} diff --git a/slf4j2-bridge/src/main/scala/zio/logging/slf4j/bridge/ZioLoggerFactory.scala b/slf4j2-bridge/src/main/scala/zio/logging/slf4j/bridge/ZioLoggerFactory.scala new file mode 100644 index 00000000..bf617500 --- /dev/null +++ b/slf4j2-bridge/src/main/scala/zio/logging/slf4j/bridge/ZioLoggerFactory.scala @@ -0,0 +1,58 @@ +/* + * Copyright 2019-2024 John A. De Goes and the ZIO Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package zio.logging.slf4j.bridge + +import org.slf4j.event.{ KeyValuePair, Level } +import org.slf4j.{ ILoggerFactory, Logger } + +import java.util.concurrent.ConcurrentHashMap +import scala.jdk.CollectionConverters._ + +final class ZioLoggerFactory extends ILoggerFactory { + private var runtime: LoggerRuntime = null + private val loggers = new ConcurrentHashMap[String, Logger]().asScala + + private[bridge] def attachRuntime(runtime: LoggerRuntime): Unit = + this.runtime = runtime + + private[bridge] def log( + logger: LoggerData, + level: Level, + messagePattern: String, + arguments: Array[AnyRef], + throwable: Throwable, + keyValues: java.util.List[KeyValuePair] + ): Unit = + if (runtime != null) runtime.log(logger, level, messagePattern, arguments, throwable, keyValues) + + private[bridge] def isEnabled(logger: LoggerData, level: Level): Boolean = + if (runtime != null) runtime.isEnabled(logger, level) else false + + override def getLogger(name: String): Logger = + loggers.getOrElseUpdate(name, new ZioLogger(name, this)) +} + +object ZioLoggerFactory { + + def initialize(runtime: LoggerRuntime): Unit = { + val factory = org.slf4j.LoggerFactory + .getILoggerFactory() + .asInstanceOf[ZioLoggerFactory] + + factory.attachRuntime(runtime) + } + +} diff --git a/slf4j2-bridge/src/main/scala/zio/logging/slf4j/bridge/ZioLoggerRuntime.scala b/slf4j2-bridge/src/main/scala/zio/logging/slf4j/bridge/ZioLoggerRuntime.scala index 43ac3313..c1e3bacf 100644 --- a/slf4j2-bridge/src/main/scala/zio/logging/slf4j/bridge/ZioLoggerRuntime.scala +++ b/slf4j2-bridge/src/main/scala/zio/logging/slf4j/bridge/ZioLoggerRuntime.scala @@ -25,7 +25,7 @@ import scala.jdk.CollectionConverters._ final class ZioLoggerRuntime(runtime: Runtime[Any], filter: LogFilter[Any]) extends LoggerRuntime { override def log( - name: String, + logger: LoggerData, level: Level, messagePattern: String, arguments: Array[AnyRef], @@ -44,19 +44,19 @@ final class ZioLoggerRuntime(runtime: Runtime[Any], filter: LogFilter[Any]) exte runtime.fiberRefs.joinAs(fiberId)(currentFiber.unsafe.getFiberRefs()) } - val logSpan = zio.LogSpan(name, java.lang.System.currentTimeMillis()) - val loggerName = (zio.logging.loggerNameAnnotationKey -> name) - val logAnnotations = if (keyValues != null) { - keyValues.asScala.map(kv => (kv.key, kv.value.toString)).toMap + val logSpan = zio.LogSpan(logger.name, java.lang.System.currentTimeMillis()) + + val logAnnotations = if (keyValues != null && !keyValues.isEmpty) { + keyValues.asScala.map(kv => (kv.key, kv.value.toString)).toMap ++ logger.annotations } else { - Map.empty + logger.annotations } val fiberRefs = currentFiberRefs .updatedAs(fiberId)(FiberRef.currentLogSpan, logSpan :: currentFiberRefs.getOrDefault(FiberRef.currentLogSpan)) .updatedAs(fiberId)( FiberRef.currentLogAnnotations, - currentFiberRefs.getOrDefault(FiberRef.currentLogAnnotations) ++ logAnnotations + loggerName + currentFiberRefs.getOrDefault(FiberRef.currentLogAnnotations) ++ logAnnotations ) val fiberRuntime = zio.internal.FiberRuntime(fiberId, fiberRefs, runtime.runtimeFlags) @@ -76,18 +76,18 @@ final class ZioLoggerRuntime(runtime: Runtime[Any], filter: LogFilter[Any]) exte fiberRuntime.log(() => msg, cause, Some(logLevel), trace) } - override def isEnabled(name: String, level: Level): Boolean = { + override def isEnabled(logger: LoggerData, level: Level): Boolean = { val logLevel = ZioLoggerRuntime.logLevelMapping(level) filter( - Trace(name, "", 0), + Trace.empty, FiberId.None, logLevel, () => "", Cause.empty, FiberRefs.empty, List.empty, - Map(zio.logging.loggerNameAnnotationKey -> name) + logger.annotations ) }