diff --git a/docs/opentelemetry-example.md b/docs/opentelemetry-example.md index 892f7b2e..93e2e1f4 100644 --- a/docs/opentelemetry-example.md +++ b/docs/opentelemetry-example.md @@ -3,7 +3,7 @@ id: opentelemetry-example title: "OpenTelemetry Example" --- -You can find the source code [here](https://github.com/zio/zio-telemetry/tree/series/2.x/opentracing-example). +You can find the source code [here](https://github.com/zio/zio-telemetry/tree/series/2.x/opentelemetry-example). For an explanation in more detail, check the [OpenTracing Example](opentracing-example.md). diff --git a/docs/opentelemetry-instrumentation-example.md b/docs/opentelemetry-instrumentation-example.md index 0c11405c..93e8d1ea 100644 --- a/docs/opentelemetry-instrumentation-example.md +++ b/docs/opentelemetry-instrumentation-example.md @@ -3,6 +3,8 @@ id: opentelemetry-instrumentation-example title: "OpenTelemetry Automatic Instrumentation Example" --- +You can find the source code [here](https://github.com/zio/zio-telemetry/tree/series/2.x/opentelemetry-instrumentation-example). + Firstly, download OpenTelemetry JVM agent JAR: ```bash OTEL_AGENT_PATH=$(cs fetch --classpath "io.opentelemetry.javaagent:opentelemetry-javaagent:latest.release") diff --git a/docs/opentelemetry.md b/docs/opentelemetry.md index 8c954a33..1a7c48af 100644 --- a/docs/opentelemetry.md +++ b/docs/opentelemetry.md @@ -66,19 +66,22 @@ import zio._ ZIO.serviceWithZIO[Baggage] { baggage => val carrier = OutgoingContextCarrier.default() - for { + val upstream = for { // add new key/value into the baggage of current tracing context _ <- baggage.set("zio", "telemetry") // import current baggage data into carrier so it can be used by downstream consumer _ <- baggage.inject(BaggagePropagator.default, carrier) } yield () - for { + val downstream = for { // extract current baggage data from the carrier _ <- baggage.extract(BaggagePropagator.default, IncomingContextCarrier.default(carrier.kernel)) // get value from the extracted baggage data <- baggage.get("zio") } yield data + + upstream *> downstream + }.provide(Baggage.live, ContextStorage.fiberRef) ``` @@ -99,9 +102,15 @@ ZIO.serviceWithZIO[Tracing] { tracing => val propagator = TraceContextPropagator.default val kernel = mutable.Map().empty - tracing.inject(propagator, OutgoingContextCarrier.default(kernel)) @@ root("span of upstream service") *> + val upstream = + tracing.inject(propagator, OutgoingContextCarrier.default(kernel)) @@ root("span of upstream service") + + val downstream = extractSpan(propagator, IncomingContextCarrier.default(kernel), "span of downstream service") -} + + upstream *> downstream + +}.provide(Tracing.live, ContextStorage.fiberRef, JaegerTracer.live) ``` ### Usage with OpenTelemetry automatic instrumentation @@ -115,7 +124,7 @@ Since [version 1.25.0](https://github.com/open-telemetry/opentelemetry-java-inst OpenTelemetry JVM agent supports ZIO. To enable interoperability between automatic instrumentation and `zio-opentelemetry`, `Tracing` has to be created -using `ContextStorage` backed by OpenTelemetry's `Context`. +using `ContextStorage` backed by OpenTelemetry's `Context` and `Tracer` provided by globally registered `TracerProvider`. ```scala import zio.telemetry.opentelemetry.tracing.Tracing @@ -132,7 +141,7 @@ val app = ZIO.logInfo("Hello") @@ root("root span", SpanKind.INTERNAL, errorMapper) }.provide( Tracing.live, - ContextStorage.openTelemetryContext, // <<< - JaegerTracer.live + ContextStorage.openTelemetryContext, // <<< ContextStorage + ZLayer.fromZIO(ZIO.attempt(GlobalOpenTelemetry.getTracer("hello"))) // <<< Tracer ) ``` diff --git a/example.patch.txt b/example.patch.txt deleted file mode 100644 index 2f70cfae..00000000 --- a/example.patch.txt +++ /dev/null @@ -1,159 +0,0 @@ -diff --git a/opentelemetry-instrumentation-example/src/main/resources/application.conf b/opentelemetry-instrumentation-example/src/main/resources/application.conf -index fff39f3..71b5484 100644 ---- a/opentelemetry-instrumentation-example/src/main/resources/application.conf -+++ b/opentelemetry-instrumentation-example/src/main/resources/application.conf -@@ -2,7 +2,3 @@ server { - host = "0.0.0.0" - port = 9000 - } -- --tracer { -- host = "http://localhost:14250" --} -\ No newline at end of file -diff --git a/opentelemetry-instrumentation-example/src/main/scala/zio/telemetry/opentelemetry/instrumentation/example/JaegerTracer.scala b/opentelemetry-instrumentation-example/src/main/scala/zio/telemetry/opentelemetry/instrumentation/example/JaegerTracer.scala -deleted file mode 100644 -index 6e112b2..0000000 ---- a/opentelemetry-instrumentation-example/src/main/scala/zio/telemetry/opentelemetry/instrumentation/example/JaegerTracer.scala -+++ /dev/null -@@ -1,42 +0,0 @@ --package zio.telemetry.opentelemetry.instrumentation.example -- --import io.opentelemetry.api.common.Attributes --import io.opentelemetry.api.trace.Tracer --import io.opentelemetry.exporter.jaeger.JaegerGrpcSpanExporter --import io.opentelemetry.sdk.OpenTelemetrySdk --import io.opentelemetry.sdk.resources.Resource --import io.opentelemetry.sdk.trace.SdkTracerProvider --import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor --import io.opentelemetry.semconv.resource.attributes.ResourceAttributes --import zio._ --import zio.telemetry.opentelemetry.instrumentation.example.config.AppConfig -- --object JaegerTracer { -- -- def live: RLayer[AppConfig, Tracer] = -- ZLayer { -- for { -- config <- ZIO.service[AppConfig] -- tracer <- makeTracer(config.tracer.host) -- } yield tracer -- } -- -- def makeTracer(host: String): Task[Tracer] = -- for { -- spanExporter <- ZIO.attempt(JaegerGrpcSpanExporter.builder().setEndpoint(host).build()) -- spanProcessor <- ZIO.succeed(SimpleSpanProcessor.create(spanExporter)) -- tracerProvider <- -- ZIO.attempt( -- SdkTracerProvider -- .builder() -- .setResource( -- Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, "opentelemetry-instrumentation-example")) -- ) -- .addSpanProcessor(spanProcessor) -- .build() -- ) -- openTelemetry <- ZIO.succeed(OpenTelemetrySdk.builder().setTracerProvider(tracerProvider).build()) -- tracer <- ZIO.succeed(openTelemetry.getTracer("zio.telemetry.opentelemetry.example.instrumentation.JaegerTracer")) -- } yield tracer -- --} -diff --git a/opentelemetry-instrumentation-example/src/main/scala/zio/telemetry/opentelemetry/instrumentation/example/ServerApp.scala b/opentelemetry-instrumentation-example/src/main/scala/zio/telemetry/opentelemetry/instrumentation/example/ServerApp.scala -index 30290f8..f5a383e 100644 ---- a/opentelemetry-instrumentation-example/src/main/scala/zio/telemetry/opentelemetry/instrumentation/example/ServerApp.scala -+++ b/opentelemetry-instrumentation-example/src/main/scala/zio/telemetry/opentelemetry/instrumentation/example/ServerApp.scala -@@ -1,8 +1,9 @@ - package zio.telemetry.opentelemetry.instrumentation.example - -+import io.opentelemetry.api.GlobalOpenTelemetry - import zio._ --import zio.config.typesafe.TypesafeConfig - import zio.config.magnolia._ -+import zio.config.typesafe.TypesafeConfig - import zio.telemetry.opentelemetry.context.ContextStorage - import zio.telemetry.opentelemetry.instrumentation.example.config.AppConfig - import zio.telemetry.opentelemetry.instrumentation.example.http.{ HttpServer, HttpServerApp } -@@ -20,7 +21,7 @@ object ServerApp extends ZIOAppDefault { - HttpServer.live, - HttpServerApp.live, - Tracing.live, -- JaegerTracer.live, -+ ZLayer.fromZIO(ZIO.attempt(GlobalOpenTelemetry.getTracer("opentelemetry-instrumentation-example"))), - ContextStorage.openTelemetryContext - ) - -diff --git a/opentelemetry-instrumentation-example/src/main/scala/zio/telemetry/opentelemetry/instrumentation/example/config/AppConfig.scala b/opentelemetry-instrumentation-example/src/main/scala/zio/telemetry/opentelemetry/instrumentation/example/config/AppConfig.scala -index 667698b..be83be5 100644 ---- a/opentelemetry-instrumentation-example/src/main/scala/zio/telemetry/opentelemetry/instrumentation/example/config/AppConfig.scala -+++ b/opentelemetry-instrumentation-example/src/main/scala/zio/telemetry/opentelemetry/instrumentation/example/config/AppConfig.scala -@@ -1,3 +1,3 @@ - package zio.telemetry.opentelemetry.instrumentation.example.config - --case class AppConfig(server: ServerConfig, tracer: TracerConfig) -+case class AppConfig(server: ServerConfig) -diff --git a/opentelemetry-instrumentation-example/src/main/scala/zio/telemetry/opentelemetry/instrumentation/example/config/TracerConfig.scala b/opentelemetry-instrumentation-example/src/main/scala/zio/telemetry/opentelemetry/instrumentation/example/config/TracerConfig.scala -deleted file mode 100644 -index fd5d762..0000000 ---- a/opentelemetry-instrumentation-example/src/main/scala/zio/telemetry/opentelemetry/instrumentation/example/config/TracerConfig.scala -+++ /dev/null -@@ -1,3 +0,0 @@ --package zio.telemetry.opentelemetry.instrumentation.example.config -- --final case class TracerConfig(host: String) -diff --git a/opentelemetry-instrumentation-example/src/main/scala/zio/telemetry/opentelemetry/instrumentation/example/http/HttpServerApp.scala b/opentelemetry-instrumentation-example/src/main/scala/zio/telemetry/opentelemetry/instrumentation/example/http/HttpServerApp.scala -index ff8be88..6dcc5ba 100644 ---- a/opentelemetry-instrumentation-example/src/main/scala/zio/telemetry/opentelemetry/instrumentation/example/http/HttpServerApp.scala -+++ b/opentelemetry-instrumentation-example/src/main/scala/zio/telemetry/opentelemetry/instrumentation/example/http/HttpServerApp.scala -@@ -1,33 +1,14 @@ - package zio.telemetry.opentelemetry.instrumentation.example.http - --import io.opentelemetry.api.trace.SpanKind - import zhttp.http._ - import zio._ --import zio.telemetry.opentelemetry.context.IncomingContextCarrier - import zio.telemetry.opentelemetry.tracing.Tracing --import zio.telemetry.opentelemetry.tracing.propagation.TraceContextPropagator - - case class HttpServerApp(tracing: Tracing) { - -- import tracing.aspects._ -- -- def headersCarrier(initial: Headers): IncomingContextCarrier[Headers] = -- new IncomingContextCarrier[Headers] { -- override val kernel: Headers = initial -- -- override def getAllKeys(carrier: Headers): Iterable[String] = -- carrier.headers.headersAsList.map(_._1) -- -- override def getByKey(carrier: Headers, key: String): Option[String] = -- carrier.headers.headerValue(key) -- -- } -- - val routes: HttpApp[Any, Throwable] = -- Http.collectZIO { case request @ Method.GET -> _ / "health" => -- val carrier = headersCarrier(request.headers) -- -- health @@ extractSpan(TraceContextPropagator.default, carrier, "/health", SpanKind.INTERNAL) -+ Http.collectZIO { case Method.GET -> _ / "health" => -+ health - } - - def health: UIO[Response] = -diff --git a/project/Dependencies.scala b/project/Dependencies.scala -index 1f99c8a..8bc4910 100644 ---- a/project/Dependencies.scala -+++ b/project/Dependencies.scala -@@ -92,10 +92,7 @@ object Dependencies { - ) - - lazy val opentelemetryInstrumentationExample = example ++ Seq( -- Orgs.softwaremillSttpClient3 %% "zio" % ExampleVersions.sttp3, -- Orgs.opentelemetry % "opentelemetry-exporter-jaeger" % Versions.opentelemetry, -- Orgs.opentelemetry % "opentelemetry-sdk" % Versions.opentelemetry, -- Orgs.grpc % "grpc-netty-shaded" % ExampleVersions.grpcNetty -+ Orgs.softwaremillSttpClient3 %% "zio" % ExampleVersions.sttp3 - ) - - } diff --git a/opentelemetry-instrumentation-example/src/main/scala/zio/telemetry/opentelemetry/instrumentation/example/ClientApp.scala b/opentelemetry-instrumentation-example/src/main/scala/zio/telemetry/opentelemetry/instrumentation/example/ClientApp.scala index 3be78977..be17d994 100644 --- a/opentelemetry-instrumentation-example/src/main/scala/zio/telemetry/opentelemetry/instrumentation/example/ClientApp.scala +++ b/opentelemetry-instrumentation-example/src/main/scala/zio/telemetry/opentelemetry/instrumentation/example/ClientApp.scala @@ -5,11 +5,13 @@ import zio.config.magnolia.descriptor import zio.config.typesafe.TypesafeConfig import zio.telemetry.opentelemetry.instrumentation.example.config.AppConfig import zio._ +import zio.config.ReadError import zio.telemetry.opentelemetry.instrumentation.example.http.HttpClient object ClientApp extends ZIOAppDefault { - private val configLayer = TypesafeConfig.fromResourcePath(descriptor[AppConfig]) + private val configLayer: Layer[ReadError[String], AppConfig] = + TypesafeConfig.fromResourcePath(descriptor[AppConfig]) private val httpBackendLayer: TaskLayer[Backend] = ZLayer.scoped { diff --git a/opentelemetry-instrumentation-example/src/main/scala/zio/telemetry/opentelemetry/instrumentation/example/ServerApp.scala b/opentelemetry-instrumentation-example/src/main/scala/zio/telemetry/opentelemetry/instrumentation/example/ServerApp.scala index 119030b6..9044d07e 100644 --- a/opentelemetry-instrumentation-example/src/main/scala/zio/telemetry/opentelemetry/instrumentation/example/ServerApp.scala +++ b/opentelemetry-instrumentation-example/src/main/scala/zio/telemetry/opentelemetry/instrumentation/example/ServerApp.scala @@ -1,7 +1,9 @@ package zio.telemetry.opentelemetry.instrumentation.example import io.opentelemetry.api.GlobalOpenTelemetry +import io.opentelemetry.api.trace.Tracer import zio._ +import zio.config.ReadError import zio.config.typesafe.TypesafeConfig import zio.config.magnolia._ import zio.telemetry.opentelemetry.context.ContextStorage @@ -11,10 +13,13 @@ import zio.telemetry.opentelemetry.tracing.Tracing object ServerApp extends ZIOAppDefault { - private val configLayer = TypesafeConfig.fromResourcePath(descriptor[AppConfig]) + private val configLayer: Layer[ReadError[String], AppConfig] = + TypesafeConfig.fromResourcePath(descriptor[AppConfig]) - private val globalTracerLayer = - ZLayer.succeed(GlobalOpenTelemetry.getTracer("zio.telemetry.opentelemetry.instrumentation.example.ServerApp")) + private val globalTracerLayer: TaskLayer[Tracer] = + ZLayer.fromZIO( + ZIO.attempt(GlobalOpenTelemetry.getTracer("zio.telemetry.opentelemetry.instrumentation.example.ServerApp")) + ) override def run: Task[ExitCode] = ZIO diff --git a/opentelemetry/src/test/scala/zio/telemetry/opentelemetry/tracing/TracingTest.scala b/opentelemetry/src/test/scala/zio/telemetry/opentelemetry/tracing/TracingTest.scala index 04e57c6e..8a1c5957 100644 --- a/opentelemetry/src/test/scala/zio/telemetry/opentelemetry/tracing/TracingTest.scala +++ b/opentelemetry/src/test/scala/zio/telemetry/opentelemetry/tracing/TracingTest.scala @@ -11,7 +11,6 @@ import zio._ import zio.telemetry.opentelemetry.context.{ ContextStorage, IncomingContextCarrier, OutgoingContextCarrier } import zio.telemetry.opentelemetry.tracing.propagation.TraceContextPropagator import zio.test.Assertion._ -import zio.test.TestAspect import zio.test.{ assert, TestClock, ZIOSpecDefault } import scala.collection.mutable @@ -335,6 +334,6 @@ object TracingTest extends ZIOSpecDefault { } yield assert(released)(isFalse) } } - ).provideLayer(tracingMockLayer) @@ TestAspect.sequential + ).provideLayer(tracingMockLayer) } diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 1f99c8a1..8bc4910e 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -92,10 +92,7 @@ object Dependencies { ) lazy val opentelemetryInstrumentationExample = example ++ Seq( - Orgs.softwaremillSttpClient3 %% "zio" % ExampleVersions.sttp3, - Orgs.opentelemetry % "opentelemetry-exporter-jaeger" % Versions.opentelemetry, - Orgs.opentelemetry % "opentelemetry-sdk" % Versions.opentelemetry, - Orgs.grpc % "grpc-netty-shaded" % ExampleVersions.grpcNetty + Orgs.softwaremillSttpClient3 %% "zio" % ExampleVersions.sttp3 ) }