Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

slf4j-bridge - performance improvements #901

Merged
merged 4 commits into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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
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