Skip to content

Commit

Permalink
slf4j-bridge - performance improvements (#901)
Browse files Browse the repository at this point in the history
* slf4j-bridge - annotations for logger

* slf4j2-bridge - annotations for logger
  • Loading branch information
justcoon authored Nov 6, 2024
1 parent f605763 commit b846352
Show file tree
Hide file tree
Showing 17 changed files with 225 additions and 204 deletions.
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 12 additions & 0 deletions core/jvm/src/test/scala/zio/logging/LoggerNameExtractorSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 =>
Expand Down
12 changes: 6 additions & 6 deletions slf4j-bridge/src/main/java/org/slf4j/helpers/ZioLoggerBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,18 @@ 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,
arguments: Array[AnyRef],
throwable: Throwable
): Unit

def isEnabled(name: String, level: Level): Boolean
def isEnabled(logger: LoggerData, level: Level): Boolean
}
7 changes: 5 additions & 2 deletions slf4j-bridge/src/main/scala/org/slf4j/impl/ZioLogger.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,19 @@ 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,
messagePattern: String,
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)
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,30 @@ 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

private[impl] def attachRuntime(runtime: LoggerRuntime): Unit =
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))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<KeyValuePair> keyValues);

boolean isEnabled(String name, Level level);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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)
Expand All @@ -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
)
}

Expand Down
101 changes: 0 additions & 101 deletions slf4j2-bridge/src/main/java/zio/logging/slf4j/bridge/Logger.java

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public String getRequestedApiVersion() {
@Override
public void initialize() {
markerFactory = new BasicMarkerFactory();
loggerFactory = new LoggerFactory();
loggerFactory = new ZioLoggerFactory();
mdcAdapter = new BasicMDCAdapter();
}
}
Loading

0 comments on commit b846352

Please sign in to comment.