Created
December 2, 2022 07:01
-
-
Save paulpdaniels/1c8e91fae21a6073b0c70b86a012be73 to your computer and use it in GitHub Desktop.
A ZIO2 compatible LogStage encoding
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package compat | |
import izumi.functional.mono.SyncSafe | |
import izumi.fundamentals.platform.language.CodePositionMaterializer | |
import izumi.logstage.api.Log | |
import izumi.logstage.api.Log.{CustomContext, Entry, Level, LogArg, Message} | |
import izumi.logstage.api.logger.AbstractLogger | |
import izumi.logstage.api.rendering.AnyEncoded | |
import izumi.logstage.macros.LogIOMacroMethods._ | |
import logstage.UnsafeLogIO.UnsafeLogIOSyncSafeInstance | |
import LogZIOAsk.LogZIOAskImpl | |
import logstage.{IzLogger, LogIO, UnsafeLogIO} | |
import zio.{UIO, URIO, ZIO, ZLayer} | |
trait LogZIO extends UnsafeLogIO[UIO] { | |
self => | |
// final def raw: LogIORaw[UIO, AnyEncoded] = new izumi.logstage.api.logger.LogIORaw(this) | |
final def trace(message: String): UIO[Unit] = macro scTraceMacro[UIO] | |
final def debug(message: String): UIO[Unit] = macro scDebugMacro[UIO] | |
final def info(message: String): UIO[Unit] = macro scInfoMacro[UIO] | |
final def warn(message: String): UIO[Unit] = macro scWarnMacro[UIO] | |
final def error(message: String): UIO[Unit] = macro scErrorMacro[UIO] | |
final def crit(message: String): UIO[Unit] = macro scCritMacro[UIO] | |
def log(entry: Entry): UIO[Unit] | |
def log(logLevel: Level)(messageThunk: => Message)(implicit pos: CodePositionMaterializer): UIO[Unit] | |
def withCustomContext(context: CustomContext): LogZIO | |
final def apply(context: CustomContext): LogZIO = withCustomContext(context) | |
final def withCustomContext(context: (String, AnyEncoded)*): LogZIO = withCustomContextMap(context.toMap) | |
final def withCustomContextMap(context: Map[String, AnyEncoded]): LogZIO = withCustomContext( | |
CustomContext.fromMap(context) | |
) | |
final def apply(context: (String, AnyEncoded)*): LogZIO = withCustomContextMap(context.toMap) | |
final def apply(context: Map[String, AnyEncoded]): LogZIO = withCustomContextMap(context) | |
} | |
object LogZIO { | |
private implicit val zioSyncSafe: SyncSafe[UIO] = new SyncSafe[UIO] { | |
def syncSafe[A](unexceptionalEff: => A): UIO[A] = ZIO.succeed(unexceptionalEff) | |
} | |
object log extends LogZIOAskImpl(identity) | |
val nullLogger = fromLogger(IzLogger.NullLogger) | |
val nullLayer = ZLayer.succeed(nullLogger) | |
def fromLogger(logger: AbstractLogger): LogZIO = { | |
new UnsafeLogIOSyncSafeInstance[UIO](logger)(SyncSafe[UIO]) with LogZIO { | |
def log(entry: Log.Entry): UIO[Unit] = ZIO.logAnnotations.map { annotations => | |
logger.log(entry.addCustomContext(customContext(annotations))) | |
} | |
def log(logLevel: Level)(messageThunk: => Log.Message)(implicit pos: CodePositionMaterializer): UIO[Unit] = | |
ZIO.logAnnotations.map { annotations => | |
logger.withCustomContext(customContext(annotations)).log(logLevel)(messageThunk) | |
} | |
def withCustomContext(context: CustomContext): LogZIO = | |
fromLogger(logger.withCustomContext(context)) | |
private def customContext(annotations: Map[String, String]): CustomContext = | |
CustomContext(annotations.view.map { case (k, v) => LogArg(Seq(k), v, hiddenName = false, None) }.toSeq) | |
} | |
} | |
} | |
object LogZIOAsk { | |
/** Lets you carry LogIO3 capability in environment | |
* | |
* {{{ | |
* import logstage.{LogIO3, LogIO3Ask} | |
* import logstage.LogIO3Ask.log | |
* import zio.ZIO | |
* | |
* def fn[F[-_, +_, +_]: LogIO3Ask]: F[LogIO3Ask.Service[F], Unit] = { | |
* log.info(s"I'm logging with ${log}stage!") | |
* } | |
* | |
* fn[ZIO] | |
* }}} | |
*/ | |
@inline def log(implicit l: LogZIOAskImpl): l.type = l | |
class LogZIOAskImpl(f: LogZIO => LogZIO) extends LogIO[URIO[LogZIO, *]] { | |
override final def log(entry: Log.Entry): URIO[LogZIO, Unit] = | |
ZIO.serviceWithZIO(f(_).log(entry)) | |
override final def log(logLevel: Level)(messageThunk: => Log.Message)(implicit | |
pos: CodePositionMaterializer | |
): URIO[LogZIO, Unit] = | |
ZIO.serviceWithZIO(f(_).log(logLevel)(messageThunk)) | |
override final def unsafeLog(entry: Log.Entry): ZIO[LogZIO, Nothing, Unit] = | |
ZIO.serviceWithZIO(f(_).log(entry)) | |
override final def acceptable(loggerId: Log.LoggerId, logLevel: Level): ZIO[LogZIO, Nothing, Boolean] = | |
ZIO.serviceWithZIO(f(_).acceptable(loggerId, logLevel)) | |
override final def acceptable(logLevel: Level)(implicit | |
pos: CodePositionMaterializer | |
): ZIO[LogZIO, Nothing, Boolean] = | |
ZIO.serviceWithZIO(f(_).acceptable(logLevel)) | |
override final def createEntry(logLevel: Level, message: Log.Message)(implicit | |
pos: CodePositionMaterializer | |
): ZIO[LogZIO, Nothing, Log.Entry] = | |
ZIO.serviceWithZIO(f(_).createEntry(logLevel, message)) | |
override final def createContext(logLevel: Level, customContext: CustomContext)(implicit | |
pos: CodePositionMaterializer | |
): ZIO[LogZIO, Nothing, Log.Context] = | |
ZIO.serviceWithZIO(f(_).createContext(logLevel, customContext)) | |
override final def withCustomContext(context: CustomContext): LogIO[URIO[LogZIO, *]] = { | |
new LogZIOAskImpl(_.withCustomContext(context)) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment