Skip to content
Simple convenience layer on top of SLF4J for ZIO
Branch: master
Clone or download
Type Name Latest commit message Commit time
Failed to load latest commit information.
src Cosmetics Jul 22, 2019
.gitignore Initial import Jun 24, 2019
LICENSE Add LICENSE Jun 24, 2019
README.MD Documentation Jun 28, 2019
build.sbt Publish for Scala 2.11 (fixes #1) Jul 24, 2019



Integrates SLF4J with ZIO in the simplest possible manner.

Maven Central

When to Use

If your code is based on ZIO and you want to log with SLF4J.

When not to Use

If you want to track logging effects using the ZIO Environment try zio-slf4j. If you are into Tagless Final, take a look at log4cats.

How to Use

Creating loggers safely as needed

import com.github.mlangc.slf4zio.api._
import zio.Task
// ...
class SomeClass
// ...
for {
    logger <- makeLogger[SomeClass]
    _ <- logger.debugIO("Debug me tender")
    // ...
    _ <- Task {
      // Note that makeLogger just returns a plain SLF4J logger; you can therefore use it from
      // effectful code directly:"Don't be shy")
      // ...
      logger.warn("Please take me home")
} yield ()

Using the LoggingSupport convenience trait

import zio.TaskR
import zio.random
import zio.random.Random
import com.github.mlangc.slf4zio.api._

class SomeClass extends LoggingSupport {
  def doStuff: TaskR[Random, Unit] =
    for {
      _ <- logger.warnIO("What the heck")
      _ <- random.nextBoolean.flatMap {
        case true => logger.infoIO("Uff, that was close")
        case false => logger.errorIO("Game over", new IllegalStateException("This is the end"))
    } yield ()

Note that the logger field in the LoggingSupport trait is lazy. Since the implicit class that implements the various **IO methods, like debugIO, infoIO and so forth, wraps the logger using a by-name parameter, logger initialization won't happen before unsafeRun, if you don't access the logger directly from non effectful code. To ensure referential transparency for creating an object of a class that inherits the LoggingSupport trait even with outright broken or strange logger implementations, you have wrap the creation of the object in an effect of its own. It might make more sense to use another logger implementation though. For practical purposes, I would consider obtaining a logger to be a pure operation as soon as the logging framework has finished its initialization, and not care too much about this subtlety.

You can’t perform that action at this time.