Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to zio/monix FiberRef for contextual logging #2

Merged
merged 9 commits into from
Feb 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,17 @@ docker:
- docker build --cache-from $CONTAINER_IMAGE:latest --tag $CONTAINER_IMAGE:latest --tag $CONTAINER_IMAGE:$CI_COMMIT_SHA .
- docker push $CONTAINER_IMAGE

test:
format:
stage: test
image: $CONTAINER_IMAGE:$CI_COMMIT_SHA
script:
- sbt -Dmode=strict test publishLocal
- sbt -Dmode=strict scalafmtCheckAll

unit:
stage: test
image: $CONTAINER_IMAGE:$CI_COMMIT_SHA
script:
- sbt -Dmode=strict +test publishLocal

artifacts:
stage: deploy
Expand Down
80 changes: 44 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,72 +39,80 @@ libraryDependencies ++=
## Usage

```scala
import cats.effect.{ExitCode, IO, IOApp}
import java.util.UUID

import cats.effect.ExitCode
import cats.implicits._
import io.circe.JsonObject
import io.circe.syntax._
import io.taig.flog.algebra.{ContextualLogger, Logger}
import io.taig.flog.data.Scope
import io.taig.flog.interop.monix._
import monix.eval._

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

object Main extends IOApp {
def loadWebsite(url: String, logger: Logger[IO]): IO[String] =
object Playground extends TaskApp {
def loadWebsite(url: String, logger: Logger[Task]): Task[String] =
for {
_ <- logger.info(
Scope.Root / "request",
message = url
)
body <- IO(Source.fromURL(url).mkString)
body <- Task(Source.fromURL(url))
.bracket(source => Task(source.mkString))(
source => Task(source.close())
)
_ <- 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)
def app(logger: Logger[Task]): Task[Unit] =
(loadWebsite(url = "https://typelevel.org", logger) *>
loadWebsite(url = "foobar", logger)).void
.onErrorHandleWith { throwable =>
logger.error(message = "Execution failed", throwable = throwable.some)
}

override def run(args: List[String]): Task[ExitCode] =
(for {
// Pick a simple std out logger ...
stdOutLogger <- Logger.stdOut[Task]
// ... and lift it into contextual mode (which is only possible with
// monix.eval.Task and ZIO)
contextualLogger <- ContextualLogger[Task](stdOutLogger)
uuid <- Task(UUID.randomUUID())
_ <- contextualLogger.locally(_.trace(uuid))(app(contextualLogger))
} yield ExitCode.Success)
.executeWithOptions(_.enableLocalContextPropagation)
}
```

```
[2019-09-20 10:15:48.919][info][load / request] https://typelevel.org
[2020-02-05 18:57:13.504][info][request] https://typelevel.org
{
"trace" : "1125b13f-69fc-4883-9f54-ca092a74455c"
"trace" : "95cf9ca5-9e10-4451-9d61-111f8850ca0a"
}
[2019-09-20 10:15:49.263][info][load / response] https://typelevel.org
[2020-02-05 18:57:13.659][info][response] https://typelevel.org
{
"trace" : "1125b13f-69fc-4883-9f54-ca092a74455c",
"trace" : "95cf9ca5-9e10-4451-9d61-111f8850ca0a",
"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
[2020-02-05 18:57:13.659][info][request] foobar
{
"trace" : "64aae8ad-0bdf-4ce9-ba8e-9d4e99842e7d"
"trace" : "95cf9ca5-9e10-4451-9d61-111f8850ca0a"
}
[2019-09-20 10:15:49.265][failure][load]
[2020-02-05 18:57:13.661][error][/] Execution failed
{
"trace" : "64aae8ad-0bdf-4ce9-ba8e-9d4e99842e7d"
"trace" : "95cf9ca5-9e10-4451-9d61-111f8850ca0a"
}
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 java.net.URL.<init>(URL.java:610)
at java.net.URL.<init>(URL.java:507)
at java.net.URL.<init>(URL.java:456)
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)
[...]
```
48 changes: 44 additions & 4 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,22 +1,35 @@
import sbtcrossproject.CrossPlugin.autoImport.{crossProject, CrossType}

val CatsEffectVersion = "2.0.0"
val CatsEffectVersion = "2.1.0"
val CirceVersion = "0.12.3"
val GoogleApiClientVersion = "1.25.1"
val GoogleApiServicesSheetsVersion = "v4-rev581-1.25.0"
val GoogleCloudLoggingVersion = "1.99.0"
val GoogleCloudLoggingVersion = "1.100.0"
val GoogleOauthClientJettyVersion = "1.25.0"
val MonixVersion = "3.1.0"
val ScalaCollectionCompatVersion = "2.1.3"
val ScalatestVersion = "3.1.0"
val Slf4jVersion = "1.7.29"
val Slf4jVersion = "1.7.30"
val ZioVersion = "1.0.0-RC17"

lazy val flog = project
.in(file("."))
.settings(noPublishSettings)
.aggregate(core.jvm, core.js, slf4j, sheets, stackdriver)
.aggregate(
core.jvm,
core.js,
zio.jvm,
monix.jvm,
monix.js,
zio.js,
slf4j,
sheets,
stackdriver
)

lazy val core = crossProject(JVMPlatform, JSPlatform)
.crossType(CrossType.Pure)
.in(file("modules/core"))
.settings(sonatypePublishSettings)
.settings(
libraryDependencies ++=
Expand All @@ -26,7 +39,32 @@ lazy val core = crossProject(JVMPlatform, JSPlatform)
Nil
)

lazy val zio = crossProject(JVMPlatform, JSPlatform)
.crossType(CrossType.Pure)
.in(file("modules/interop-zio"))
.settings(sonatypePublishSettings)
.settings(
libraryDependencies ++=
"dev.zio" %%% "zio" % ZioVersion ::
Nil,
name := "interop-zio"
)
.dependsOn(core)

lazy val monix = crossProject(JVMPlatform, JSPlatform)
.crossType(CrossType.Pure)
.in(file("modules/interop-monix"))
.settings(sonatypePublishSettings)
.settings(
libraryDependencies ++=
"io.monix" %%% "monix" % MonixVersion ::
Nil,
name := "interop-monix"
)
.dependsOn(core)

lazy val slf4j = project
.in(file("modules/slf4j"))
.settings(sonatypePublishSettings)
.settings(
libraryDependencies ++=
Expand All @@ -36,6 +74,7 @@ lazy val slf4j = project
.dependsOn(core.jvm)

lazy val sheets = project
.in(file("modules/sheets"))
.settings(sonatypePublishSettings)
.settings(
libraryDependencies ++=
Expand All @@ -48,6 +87,7 @@ lazy val sheets = project
.dependsOn(core.jvm)

lazy val stackdriver = project
.in(file("modules/stackdriver"))
.settings(sonatypePublishSettings)
.settings(
libraryDependencies ++=
Expand Down
153 changes: 0 additions & 153 deletions core/src/main/scala/io/taig/flog/Logger.scala

This file was deleted.

Loading