Skip to content
Functional logging with metadata
Scala Dockerfile
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
core/src/main/scala/io/taig/flog
project
sheets/src/main/scala/io/taig/flog/sheets
stackdriver/src/main/scala/io/taig/flog/stackdriver
.gitignore
.gitlab-ci.yml
CHANGELOG.md
Dockerfile
LICENSE
README.md
build.sbt
scalaVersion.sbt
version.sbt

README.md

Flog

Functional logging with metadata

GitLab CI Maven Central License

libraryDependencies ++=
  "io.taig" %% "flog-core" % "x.x.x" ::
  "io.taig" %% "flog-sheets" % "x.x.x" ::
  "io.taig" %% "flog-stackdriver" % "x.x.x" ::
  Nil

The core module is also available for Scala.js.

libraryDependencies ++=
  "io.taig" %%% "flog-core" % "x.x.x" ::
  Nil

Available loggers

  • WriterLogger
    Print events to a Writer (e.g. std out)
  • BatchLogger
    Collect events for a given interval before forwarding to another Logger
  • BroadcastLogger
    Forward events to multiple Loggers
  • SheetsLogger
    Send events to Google Sheets
  • StackdriverLogger
    Send events to Stackdriver (on Google Cloud Platform)
  • NoopLogger

Usage

import cats.effect.{ExitCode, IO, IOApp}
import cats.implicits._
import io.circe.JsonObject

import scala.io.Source
import io.circe.syntax._

object Main extends IOApp {
  def loadWebsite(url: String, logger: Logger[IO]): IO[String] =
    for {
      _ <- logger.info(
        Scope.Root / "request",
        message = url
      )
      body <- IO(Source.fromURL(url).mkString)
      _ <- logger.info(
        Scope.Root / "response",
        message = url,
        payload = JsonObject("body" -> (body.take(100) + "...").asJson)
      )
    } yield body

  override def run(args: List[String]): IO[ExitCode] =
    WriterLogger.stdOut[IO]
      // Prefix all log events with the "load" scope
      .map(_.prefix(Scope.Root / "load"))
      // Create a reporting Tracer that automatically logs failures
      .map(Tracer.reporting)
      .flatMap { tracer =>
        tracer.run(logger => loadWebsite(url = "https://typelevel.org", logger)) *>
        tracer.run(logger => loadWebsite(url = "foobar", logger))
      }.attempt.as(ExitCode.Success)
}
[2019-09-20 10:15:48.919][info][load / request] https://typelevel.org
{
  "trace" : "1125b13f-69fc-4883-9f54-ca092a74455c"
}
[2019-09-20 10:15:49.263][info][load / response] https://typelevel.org
{
  "trace" : "1125b13f-69fc-4883-9f54-ca092a74455c",
  "body" : "<!DOCTYPE html>\n<html>\n  <head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" co..."
}
[2019-09-20 10:15:49.264][info][load / request] foobar
{
  "trace" : "64aae8ad-0bdf-4ce9-ba8e-9d4e99842e7d"
}
[2019-09-20 10:15:49.265][failure][load] 
{
  "trace" : "64aae8ad-0bdf-4ce9-ba8e-9d4e99842e7d"
}
java.net.MalformedURLException: no protocol: foobar
	at java.net.URL.<init>(URL.java:593)
	at java.net.URL.<init>(URL.java:490)
	at java.net.URL.<init>(URL.java:439)
	at scala.io.Source$.fromURL(Source.scala:132)
	at io.taig.flog.Main$.$anonfun$loadWebsite$4(Main.scala:17)
	at cats.effect.internals.IORunLoop$.cats$effect$internals$IORunLoop$$loop(IORunLoop.scala:87)
	at cats.effect.internals.IORunLoop$RestartCallback.signal(IORunLoop.scala:355)
	at cats.effect.internals.IORunLoop$RestartCallback.apply(IORunLoop.scala:376)
	at cats.effect.internals.IORunLoop$RestartCallback.apply(IORunLoop.scala:316)
	at cats.effect.internals.IOShift$Tick.run(IOShift.scala:36)
	at cats.effect.internals.PoolUtils$$anon$2$$anon$3.run(PoolUtils.scala:51)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
You can’t perform that action at this time.