Closed seveneves closed 4 months ago
Should be reading the documentation better 😅
import zio.*
import zio.logging.backend.SLF4J
object LoggingApp extends ZIOAppDefault {
private val logging: RLayer[Any, Unit] = Runtime.removeDefaultLoggers >>> SLF4J.slf4j
override def run: ZIO[Environment, Any, Any] = ZIO.logInfo("This should support sl4j") *> unsafeLog
override def runtime: Runtime[Any] = Unsafe.unsafe(implicit unsafe => Runtime.unsafe.fromLayer(logging))
private val unsafeLog = ZIO.fromFuture { _ =>
Unsafe.unsafe(implicit u =>
runtime.unsafe.runToFuture(ZIO.logInfo("Direct execution via unsafe does not use sl4j logger"))
)
}
}
works as expected
It seems the correct (and only) way of enabling or disabling loggers is via
ZLayer
. As documentation states this is how a different logging implementation should be added to the applicationWhen running such App, the log entry produce follows slf4j pattern.
However, this does not work for any operation that relies on
runtime.unsafe
for exampleAnd
Direct execution via unsafe does not use sl4j logger
will not follow sl4j structure.This example is superficial and I could just use
ZIO.logInfo
directly of course. However it shows that all interoperability libraries that rely onruntime.unsafe
to execute ZIO effects will not follow the desired logging. Such libraries may requirezio.Runtime[Any]
to be passed as an implicit.This brings a question if it is possible to change logging in a
zio.Runtime[Any]
instead of providing it asZLayer
?ZLayer
works great when one has a ZIO application without any interoperability required. But in modern enterprise applications this is very hard to achieve and some interoperability is always required.