Skip to content

Commit

Permalink
Merge pull request #305 from tpolecat/merge-with-master
Browse files Browse the repository at this point in the history
merge with master
  • Loading branch information
tpolecat authored Mar 31, 2021
2 parents 8406f36 + c04a1cd commit 50fa06b
Show file tree
Hide file tree
Showing 18 changed files with 432 additions and 135 deletions.
71 changes: 48 additions & 23 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@

val scala212Version = "2.12.12"
val scala213Version = "2.13.4"
val scala30PreviousVersion = "3.0.0-M3"
val scala30Version = "3.0.0-RC1"
val scala213Version = "2.13.5"
val scala30PreviousVersion = "3.0.0-RC1"
val scala30Version = "3.0.0-RC2"

val collectionCompatVersion = "2.4.3"

val catsVersion = "2.4.2"
val catsEffectVersion = "3.0.0-RC2"
val catsVersion = "2.5.0"
val catsEffectVersion = "3.0.1"

// We do `evictionCheck` in CI and don't sweat the Java deps for now.
inThisBuild(Seq(
Expand All @@ -21,6 +22,7 @@ inThisBuild(Seq(
"com.newrelic.telemetry" % "*" % "always",
"org.typelevel" % "*" % "semver-spec",
"org.scala-js" % "*" % "semver-spec",
"org.jctools" % "*" % "always",
)
))

Expand All @@ -45,6 +47,13 @@ lazy val commonSettings = Seq(
)
),

// Testing
libraryDependencies ++= Seq(
"org.scalameta" %%% "munit" % "0.7.23" % Test,
"org.typelevel" %%% "munit-cats-effect-2" % "1.0.1" % Test,
),
testFrameworks += new TestFramework("munit.Framework"),

// Compilation
scalaVersion := scala213Version,
crossScalaVersions := Seq(scala212Version, scala213Version, scala30PreviousVersion, scala30Version),
Expand Down Expand Up @@ -133,14 +142,14 @@ lazy val coreJS = core.js

lazy val jaeger = project
.in(file("modules/jaeger"))
.dependsOn(coreJVM)
.dependsOn(coreJVM, opentracing)
.enablePlugins(AutomateHeaderPlugin)
.settings(commonSettings)
.settings(
name := "natchez-jaeger",
description := "Jaeger support for Natchez.",
libraryDependencies ++= Seq(
"org.scala-lang.modules" %% "scala-collection-compat" % "2.4.2",
"org.scala-lang.modules" %% "scala-collection-compat" % collectionCompatVersion,
"io.jaegertracing" % "jaeger-client" % "1.5.0",
)
)
Expand All @@ -154,7 +163,7 @@ lazy val honeycomb = project
name := "natchez-honeycomb",
description := "Honeycomb support for Natchez.",
libraryDependencies ++= Seq(
"org.scala-lang.modules" %% "scala-collection-compat" % "2.4.2",
"org.scala-lang.modules" %% "scala-collection-compat" % collectionCompatVersion,
"io.honeycomb.libhoney" % "libhoney-java" % "1.3.1"
)
)
Expand All @@ -174,14 +183,14 @@ lazy val opencensus = project

lazy val lightstep = project
.in(file("modules/lightstep"))
.dependsOn(coreJVM)
.dependsOn(coreJVM, opentracing)
.enablePlugins(AutomateHeaderPlugin)
.settings(commonSettings)
.settings(
name := "natchez-lightstep",
description := "Lightstep support for Natchez.",
libraryDependencies ++= Seq(
"org.scala-lang.modules" %% "scala-collection-compat" % "2.4.2",
"org.scala-lang.modules" %% "scala-collection-compat" % collectionCompatVersion,
"com.lightstep.tracer" % "lightstep-tracer-jre" % "0.30.3"
)
)
Expand All @@ -196,8 +205,8 @@ lazy val lightstepGrpc = project
description := "Lightstep gRPC bindings for Natchez.",
libraryDependencies ++= Seq(
"com.lightstep.tracer" % "tracer-grpc" % "0.30.1",
"io.grpc" % "grpc-netty" % "1.35.0",
"io.netty" % "netty-tcnative-boringssl-static" % "2.0.36.Final"
"io.grpc" % "grpc-netty" % "1.36.1",
"io.netty" % "netty-tcnative-boringssl-static" % "2.0.38.Final"
)
)

Expand All @@ -214,18 +223,34 @@ lazy val lightstepHttp = project
)
)

lazy val opentracing = project
.in(file("modules/opentracing"))
.dependsOn(coreJVM)
.enablePlugins(AutomateHeaderPlugin)
.settings(commonSettings)
.settings(
name := "natchez-opentracing",
description := "Base OpenTracing Utilities for Natchez",
libraryDependencies ++= Seq(
"org.scala-lang.modules" %% "scala-collection-compat" % collectionCompatVersion,
"io.opentracing" % "opentracing-api" % "0.33.0" % "provided",
"io.opentracing" % "opentracing-util" % "0.33.0" % "provided"
)
)


lazy val datadog = project
.in(file("modules/datadog"))
.dependsOn(coreJVM)
.dependsOn(coreJVM, opentracing)
.enablePlugins(AutomateHeaderPlugin)
.settings(commonSettings)
.settings(
name := "natchez-datadog",
description := "Lightstep HTTP bindings for Natchez.",
description := "Datadog bindings for Natchez.",
libraryDependencies ++= Seq(
"org.scala-lang.modules" %% "scala-collection-compat" % "2.4.2",
"com.datadoghq" % "dd-trace-ot" % "0.72.0",
"com.datadoghq" % "dd-trace-api" % "0.72.0"
"org.scala-lang.modules" %% "scala-collection-compat" % collectionCompatVersion,
"com.datadoghq" % "dd-trace-ot" % "0.77.0",
"com.datadoghq" % "dd-trace-api" % "0.77.0"
)
)

Expand Down Expand Up @@ -262,10 +287,10 @@ lazy val newrelic = project
description := "Newrelic bindings for Natchez.",
libraryDependencies ++= Seq(
"io.circe" %% "circe-core" % "0.13.0",
"org.scala-lang.modules" %% "scala-collection-compat" % "2.4.2",
"org.scala-lang.modules" %% "scala-collection-compat" % collectionCompatVersion,
"com.newrelic.telemetry" % "telemetry" % "0.10.0",
"com.newrelic.telemetry" % "telemetry-core" % "0.11.0",
"com.newrelic.telemetry" % "telemetry-http-okhttp" % "0.11.0"
"com.newrelic.telemetry" % "telemetry-core" % "0.12.0",
"com.newrelic.telemetry" % "telemetry-http-okhttp" % "0.12.0"
).filterNot(_ => isDotty.value)
)

Expand All @@ -277,7 +302,7 @@ lazy val mtl = crossProject(JSPlatform, JVMPlatform)
name := "natchez-mtl",
description := "cats-mtl bindings for Natchez.",
libraryDependencies ++= Seq(
"org.typelevel" %%% "cats-mtl" % "1.1.2",
"org.typelevel" %%% "cats-mtl" % "1.1.3",
)
)

Expand Down Expand Up @@ -310,7 +335,7 @@ lazy val mock = project
description := "Mock Open Tracing implementation",
libraryDependencies ++= Seq(
"io.opentracing" % "opentracing-mock" % "0.33.0",
"org.scala-lang.modules" %% "scala-collection-compat" % "2.4.2"
"org.scala-lang.modules" %% "scala-collection-compat" % collectionCompatVersion
))


Expand Down
39 changes: 39 additions & 0 deletions modules/datadog/src/main/scala/DDEntryPoint.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (c) 2019-2020 by Rob Norris and Contributors
// This software is licensed under the MIT License (MIT).
// For more information see LICENSE or https://opensource.org/licenses/MIT

package natchez
package datadog

import cats.effect._
import cats.syntax.all._
import io.opentracing.propagation.{Format, TextMapAdapter}
import io.{opentracing => ot}

import java.net.URI
import scala.jdk.CollectionConverters._

final class DDEntryPoint[F[_]: Sync](tracer: ot.Tracer, uriPrefix: Option[URI]) extends EntryPoint[F] {
override def root(name: String): Resource[F, Span[F]] =
Resource.make(
Sync[F].delay(tracer.buildSpan(name).start()))(
s => Sync[F].delay(s.finish()))
.map(DDSpan(tracer, _, uriPrefix))

override def continue(name: String, kernel: Kernel): Resource[F, Span[F]] =
Resource.make(
Sync[F].delay {
val spanContext = tracer.extract(
Format.Builtin.HTTP_HEADERS,
new TextMapAdapter(kernel.toHeaders.asJava)
)
tracer.buildSpan(name).asChildOf(spanContext).start()
}
)(s => Sync[F].delay(s.finish())).map(DDSpan(tracer, _, uriPrefix))

override def continueOrElseRoot(name: String, kernel: Kernel): Resource[F, Span[F]] =
continue(name, kernel) flatMap {
case null => root(name) // hurr, means headers are incomplete or invalid
case span => span.pure[Resource[F, *]]
}
}
41 changes: 9 additions & 32 deletions modules/datadog/src/main/scala/DDTracer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,45 +11,22 @@ import cats.effect._
import cats.syntax.all._
import _root_.datadog.opentracing.{DDTracer => NativeDDTracer}
import _root_.datadog.opentracing.DDTracer.DDTracerBuilder
import io.opentracing.propagation.{Format, TextMapAdapter}

import scala.jdk.CollectionConverters._
import natchez.opentracing.GlobalTracer

object DDTracer {

def entryPoint[F[_]: Sync](
buildFunc: DDTracerBuilder => F[NativeDDTracer],
uriPrefix: Option[URI] = None
): Resource[F, EntryPoint[F]] = {
Resource.make(
Sync[F].delay(NativeDDTracer.builder()).flatMap(buildFunc))(
s => Sync[F].delay(s.close()).void)
.map { tracer =>
new EntryPoint[F] {
override def root(name: String): Resource[F, Span[F]] =
Resource.make(
Sync[F].delay(tracer.buildSpan(name).start()))(
s => Sync[F].delay(s.finish()))
.map(DDSpan(tracer, _, uriPrefix))

override def continue(name: String, kernel: Kernel): Resource[F, Span[F]] =
Resource.make(
Sync[F].delay {
val spanContext = tracer.extract(
Format.Builtin.HTTP_HEADERS,
new TextMapAdapter(kernel.toHeaders.asJava)
)
tracer.buildSpan(name).asChildOf(spanContext).start()
}
)(s => Sync[F].delay(s.finish())).map(DDSpan(tracer, _, uriPrefix))
val createAndRegister =
Sync[F].delay(NativeDDTracer.builder())
.flatMap(buildFunc)
.flatTap(GlobalTracer.registerTracer[F])

override def continueOrElseRoot(name: String, kernel: Kernel): Resource[F, Span[F]] =
continue(name, kernel) flatMap {
case null => root(name) // hurr, means headers are incomplete or invalid
case span => span.pure[Resource[F, *]]
}
}
}
Resource.make(createAndRegister)(t => Sync[F].delay(t.close()))
.map(new DDEntryPoint[F](_, uriPrefix))
}

def globalTracerEntryPoint[F[_]: Sync](uriPrefix: Option[URI]): F[Option[EntryPoint[F]]] =
GlobalTracer.fetch.map(_.map(new DDEntryPoint[F](_, uriPrefix)))
}
10 changes: 7 additions & 3 deletions modules/examples/src/main/scala-2/Example.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import java.net.URI

object Main extends IOApp {

<<<<<<< HEAD
// Intentionally slow parallel quicksort, to demonstrate branching. If we run too quickly it seems
// to break Jaeger with "skipping clock skew adjustment" so let's pause a bit each time.
def qsort[F[_]: Parallel: Trace: Temporal, A: Order](as: List[A]): F[List[A]] =
Expand All @@ -30,10 +31,13 @@ object Main extends IOApp {
}

def runF[F[_]: Async: Trace: Parallel]: F[Unit] =
=======
def runF[F[_]: Sync: Trace: Parallel: Timer]: F[Unit] =
>>>>>>> master
Trace[F].span("Sort some stuff!") {
for {
as <- Sync[F].delay(List.fill(10)(Random.nextInt(1000)))
_ <- qsort[F, Int](as)
_ <- Sort.qsort[F, Int](as)
u <- Trace[F].traceUri
_ <- u.traverse(uri => Sync[F].delay(println(s"View this trace at $uri")))
_ <- Sync[F].delay(println("Done."))
Expand All @@ -50,8 +54,8 @@ object Main extends IOApp {
// }
// }

// The following would be the minimal entrypoint setup for Lighstep. Note that
// by default examples project uses lighstep HTTP binding. To change that,
// The following would be the minimal entrypoint setup for Lightstep. Note that
// by default examples project uses lightstep HTTP binding. To change that,
// edit the project dependencies.
// def entryPoint[F[_]: Sync]: Resource[F, EntryPoint[F]] =
// Lightstep.entryPoint[F] { ob =>
Expand Down
60 changes: 60 additions & 0 deletions modules/examples/src/main/scala-2/GlobalTracerExample.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (c) 2019-2020 by Rob Norris and Contributors
// This software is licensed under the MIT License (MIT).
// For more information see LICENSE or https://opensource.org/licenses/MIT

package example

import cats._
import cats.data.Kleisli
import cats.effect._
import cats.syntax.all._
import natchez._
import scala.util.Random
import scala.concurrent.duration._
import java.net.URI


object GlobalTracerMain extends IOApp {

def runF[F[_]: Sync: Trace: Parallel: Timer]: F[Unit] =
Trace[F].span("Sort some stuff!") {
for {
as <- Sync[F].delay(List.fill(10)(Random.nextInt(1000)))
_ <- Sort.qsort[F, Int](as)
u <- Trace[F].traceUri
_ <- u.traverse(uri => Sync[F].delay(println(s"View this trace at $uri")))
_ <- Sync[F].delay(println("Done."))
} yield ()
}

def globalTracerEntryPoint[F[_]: Sync]: F[Option[EntryPoint[F]]] = {
// Datadog
// import natchez.datadog.DDTracer
// val prefix = Some(new URI("https://app.datadoghq.com")) // https://app.datadoghq.eu for Europe
// DDTracer.globalTracerEntryPoint[F](prefix)

// Jaeger
import natchez.jaeger.Jaeger
val prefix = Some(new URI("http://localhost:16686"))
Jaeger.globalTracerEntryPoint[F](prefix)

// Lightstep
// import natchez.lightstep.Lightstep
// Lightstep.globalTracerEntryPoint[F]

}

def run(args: List[String]): IO[ExitCode] = {
globalTracerEntryPoint[IO].flatMap {
case None => IO.delay {
println("No tracer registered to the global tracer. Is your agent attached with tracing enabled?")
} as ExitCode.Error
case Some(ep) =>
ep.root("this is the root span")
.use(span => runF[Kleisli[IO, Span[IO], *]].run(span)) *>
IO.sleep(1.second) as ExitCode.Success // Turns out Tracer.close() in Jaeger doesn't block. Annoying. Maybe fix in there?
}
}


}
28 changes: 28 additions & 0 deletions modules/examples/src/main/scala-2/Sort.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) 2019-2020 by Rob Norris and Contributors
// This software is licensed under the MIT License (MIT).
// For more information see LICENSE or https://opensource.org/licenses/MIT

package example

import cats._
import cats.effect.Timer
import cats.syntax.all._
import natchez.Trace
import scala.concurrent.duration._

object Sort {

// Intentionally slow parallel quicksort, to demonstrate branching. If we run too quickly it seems
// to break Jaeger with "skipping clock skew adjustment" so let's pause a bit each time.
def qsort[F[_]: Monad: Parallel: Trace: Timer, A: Order](as: List[A]): F[List[A]] =
Trace[F].span(as.mkString(",")) {
Timer[F].sleep(10.milli) *> {
as match {
case Nil => Monad[F].pure(Nil)
case h :: t =>
val (a, b) = t.partition(_ <= h)
(qsort[F, A](a), qsort[F, A](b)).parMapN(_ ++ List(h) ++ _)
}
}
}
}
Loading

0 comments on commit 50fa06b

Please sign in to comment.