Scala Logger Build Status Maven Central

Usage

Add to sbt:

libraryDependencies += "com.emarsys" %% "scala-logger" % "x.y.z"

The latest released version can be found on the maven badge above.

Examples

All examples expect the appropriate Logging[F] instance. For example, log[IO].info(...) expects an implicit Logging[IO] instance in scope. To get an effectful logging instance, use:

implicit val logging: Logging[IO] = Logging.createEffectLogger("logger-name")

In case of a non effectful logger (e.g. when using Logging[Id] or Logging[Future]), just import the unsafe instances:

import com.emarsys.logger.unsafe.implicits._

Basic unsafe logging without effects (unsafeLog uses Logging[Id]):

import com.emarsys.logger.syntax._
import com.emarsys.logger.unsafe.implicits._

val context = LoggingContext("job1")

unsafeLog.info("This executes immediately!")(context)

Basic effectful logging:

import com.emarsys.logger.syntax._

val context = LoggingContext("job1")

log[IO].info("My first log!")(context).unsafeRunSync()

Passing context implicitly:

import com.emarsys.logger.syntax._

implicit val context: LoggingContext = LoggingContext("job1")

log[IO].info("Implicit context!").unsafeRunSync()

Adding contextual information:

import com.emarsys.logger.syntax._

implicit val context: LoggingContext =
  LoggingContext("job1") <>
    "id" -> 1 <>
    "customer" -> "Joe"

log[IO].info("Contextual information!").unsafeRunSync()

Passing context as typeclass

import com.emarsys.logger.{Logging, Context}
import com.emarsys.logger.syntax._

def work[F[_]: Logging: Context](): F[Unit] = {
  log[F].info("Typeclasses!")
}

Adding contextual information when using typeclasses

import com.emarsys.logger.{Logging, Context}
import com.emarsys.logger.syntax._

def work[F[_]: Logging: Context](): F[Unit] = {
  extendContext("id" -> 1, "job" -> "job01") {
    log[F].info("Typeclasses!")
  }
}

Providing implementation for a tagless final algebra with logging

import com.emarsys.logger.Logged
import com.emarsys.logger.syntax._
import cats.syntax.applicative._

trait Clock[F[_]] {
  def now(): F[Long]
}

class SystemClock extends Clock[Logged[IO, ?]] {
  override def now(): Logged[IO, Long] = withContext { implicit ctx =>
      for {
        time <- IO { System.currentTimeMillis() }
        _ <- log[IO].info(s"Current time: $currentTime")
      } yield time
  }
}