Zio-logging and slf4zio have different design constraints. Whereas zio-logging tries to do logging the ZIO way, with SLF4J being just one of many possible backends, slf4zio sticks to the SLF4J way of doing things, just in a ZIO friendly manner. Now you might conclude that the more general and principled approach of zio-logging must certainly be better, and indeed, if not only all your code, but also all the code you’re depending on in libraries and frameworks would use zio-logging, I would be inclined to agree. The reality however is, that most of the libraries in your dependency graph are probably written in Java, and even if they are written in Scala, chances that they use zio-logging are fairly low. SLF4J on the other hand seems to be widely adopted, both in the Scala and in the Java word. Thus, having a simple ZIO friendly interface for SLF4J, that does not introduce any additional abstractions, seems to be a valuable addition to the ZIO ecosystem alongside zio-logging to me.

Zio-logging doesn’t provide access to the underlying logger from side effecting code. Assume that you have some complex, side effecting operation, neatly packed into a zio.Task :

Now imagine that you want to add some log statements to complexTask. Since zio-logging doesn’t expose the underlying side effecting logger implementation, this would force you to either rewrite the whole logic using ZIOs, which might be undesirable for multiple reasons, or to directly access whatever logger implementation zio-logging is using under the hood. If you wanted to access the LogContext that is an integral part of zio-logging, for example to include a correlation ID in your log statements, you would have to do some additional fiddling.

Contrast this with slf4zio, where one of the design principles is to always give you access to the underlying SLF4J logger. If you wanted to include contextual information in your log statements, you would do so using the standard MCD functionality. And while this won’t work out of the box , once you’ve set it up correctly (see zio-interop-log4j2), it will function everywhere, not only in your own, but also in all third party log statements. This brings us directly to the next point:

zio-logging’s logging context cannot be easily integrated with MDC logging. Why? Because MDC is basically a Map[String, String] , while the logging context can be viewed as an heterogeneous map between LogAnnotation[A] and A . And while being strictly less powerful then the LogContext on a theoretical level, MDC is strictly more powerful than the LogContext on a practical level, because it will not only work with your own code, but with all the third party log statements in your dependencies, that most likely outnumber your own log statements by a huge margin. The only thing you have to make sure is to use a ZIO fiber aware MDC implementation, such as provided by zio-interop-log4j2.