Overview
Cross-platform pure functional logging library for Scala. Integrates with well known JVM logging frameworks and can also be used standalone in ScalaJS or Scala Native.
Usage
Add the required dependency to your project
val cologVersion = "0.1.0+4-cc9cc849+20190411-2003-SNAPSHOT"
libraryDependencies ++= Seq(
"com.github.alonsodomin.colog" %% "colog-core" % cologVersion,
"com.github.alonsodomin.colog" %% "colog-standalone" % cologVersion, // Cross-platform
"com.github.alonsodomin.colog" %% "colog-slf4j" % cologVersion, // JVM only
)
Now define an environment for your application:
import cats.effect.IO
import colog.{HasLogger, LogRecord, Logger}
case class Env(logger: Logger[IO, LogRecord])
object Env {
implicit val envHasLogger: HasLogger[IO, Env, LogRecord] = new HasLogger[IO, Env, LogRecord] {
override def getLogger(env: Env): Logger[IO, LogRecord] = env.logger
override def setLogger(env: Env)(newLogger: Logger[IO, LogRecord]): Env =
env.copy(logger = newLogger)
}
}
Define also the effect type for your application, the simplest one is based on a ReaderT monad:
import cats.data.ReaderT
type AppIO[A] = ReaderT[IO, Env, A]
And you can get an instance of the logging API:
import colog.Logging
import cats.mtl.implicits._
val logging = Logging.structured[AppIO, Env]
// logging: colog.StructuredLogging[AppIO, Env] = colog.Logging$$anon$2@15c30c2d
logging.info("Hello")
// res0: AppIO[Unit] = Kleisli(
// cats.data.Kleisli$$$Lambda$15892/635955592@39b926e1
// )
So, with the previous, we are now able to emit log messages, which will be embedded in the AppIO
effect we just created.
To be able to run those effects, we need to initialize the desired environment:
import colog.standalone._
final val env = Env(SysLoggers.stdout[IO].formatWithF(LogRecord.defaultFormat[IO]))
// env: Env = Env(Logger(colog.Logger$$Lambda$15895/2020642011@1399fea0))
So now we can do the following:
val logAction = logging.info("Hello")
// logAction: AppIO[Unit] = Kleisli(
// cats.data.Kleisli$$$Lambda$15892/635955592@313cb041
// )
logAction.run(env).unsafeRunSync()
If interested on also having timestamps in your log statements, we just need to use a timestamped logger:
import scala.concurrent.ExecutionContext
implicit val timer = IO.timer(ExecutionContext.global)
// timer: cats.effect.Timer[IO] = cats.effect.internals.IOTimer@29a7ae3b
final val timestampedEnv = Env(
SysLoggers.stdout[IO]
.formatWithF(LogRecord.defaultFormat[IO])
.timestampedWith(LogRecord.defaultTimestampedFormat)
)
// timestampedEnv: Env = Env(
// Logger(colog.Logger$$Lambda$15911/619456870@1da0e8d7)
// )
logAction.run(timestampedEnv).unsafeRunSync()