All Downloads are FREE. Search and download functionalities are using the official Maven repository.

zio.telemetry.opentelemetry.logging.Logging.scala Maven / Gradle / Ivy

There is a newer version: 3.0.1
Show newest version
package zio.telemetry.opentelemetry.logging

import io.opentelemetry.api.common.AttributeKey
import io.opentelemetry.api.logs.{Logger, LoggerProvider, Severity}
import io.opentelemetry.context.Context
import zio._
import zio.telemetry.opentelemetry.context.ContextStorage

object Logging {

  def live(
    instrumentationScopeName: String,
    logLevel: LogLevel = LogLevel.Info
  ): URLayer[ContextStorage with LoggerProvider, Unit] =
    ZLayer.scoped(
      for {
        loggerProvider <- ZIO.service[LoggerProvider]
        ctxStorage     <- ZIO.service[ContextStorage]
        logger         <- ZIO.succeed(
                            zioLogger(instrumentationScopeName)(ctxStorage, loggerProvider)
                              .filterLogLevel(_ >= logLevel)
                          )
        _              <- ZIO.withLoggerScoped(logger)
      } yield ()
    )

  private def zioLogger(instrumentationScopeName: String)(
    ctxStorage: ContextStorage,
    loggerProvider: LoggerProvider
  ): ZLogger[String, Unit] =
    new ZLogger[String, Unit] {

      val logger: Logger = loggerProvider.get(instrumentationScopeName)

      override def apply(
        trace: Trace,
        fiberId: FiberId,
        logLevel: LogLevel,
        message: () => String,
        cause: Cause[Any],
        context: FiberRefs,
        spans: List[LogSpan],
        annotations: Map[String, String]
      ): Unit = {
        val builder = logger.logRecordBuilder()

        builder.setBody(message())
        builder.setSeverityText(logLevel.label)
        builder.setSeverity(severityMapping(logLevel))
        annotations.foreach { case (k, v) => builder.setAttribute(AttributeKey.stringKey(k), v) }

        ctxStorage match {
          case cs: ContextStorage.ZIOFiberRef =>
            context.get(cs.ref).foreach(builder.setContext)
          case _: ContextStorage.Native.type  =>
            builder.setContext(Context.current())
        }

        builder.emit()
      }

      private def severityMapping(level: LogLevel): Severity =
        level match {
          case LogLevel.Trace   => Severity.TRACE
          case LogLevel.Debug   => Severity.DEBUG
          case LogLevel.Info    => Severity.INFO
          case LogLevel.Warning => Severity.WARN
          case LogLevel.Error   => Severity.ERROR
          case LogLevel.Fatal   => Severity.FATAL
          case _                => Severity.UNDEFINED_SEVERITY_NUMBER
        }

    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy