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

Draft: Experimental sdk-exporter-trace module #330

Closed
wants to merge 99 commits into from

Conversation

iRevive
Copy link
Contributor

@iRevive iRevive commented Oct 3, 2023

This PR is built on top of #325. It's mostly for showcase purposes.

The module can be published for the native platform.

The supported exporters:

  • http/json
  • http/protobuf

Here is the demo:

//> using scala 2.13.11
//> using lib "co.fs2::fs2-io::3.10-4b5f50b"
//> using lib "com.armanbilge::epollcat::0.1.6"
//> using lib "org.typelevel::otel4s-sdk-trace::0.3-f4e1e7f-20231003T171450Z-SNAPSHOT"
//> using lib "org.typelevel::otel4s-sdk-exporter-trace::0.3-f4e1e7f-20231003T171450Z-SNAPSHOT"

import cats.effect._
import cats.effect.std.Console
import cats.effect.std.Random
import cats.syntax.all._
import org.typelevel.otel4s.Attribute
import org.typelevel.otel4s.sdk.{Resource => InstrumentationResource}
import org.typelevel.otel4s.sdk.Attributes
import org.typelevel.otel4s.sdk.context.Context
import org.typelevel.otel4s.sdk.exporter.otlp.OtlpHttpSpanExporter
import org.typelevel.otel4s.sdk.instances._
import org.typelevel.otel4s.sdk.trace.SdkTracerProvider
import org.typelevel.otel4s.sdk.trace.exporter.BatchSpanProcessor
import org.typelevel.otel4s.sdk.trace.exporter.SpanExporter
import org.typelevel.otel4s.trace.Tracer

import scala.concurrent.duration._

trait Work[F[_]] {
  def doWork: F[Unit]
}

object Work {
  def apply[F[_] : Async : Tracer : Console]: Work[F] =
    new Work[F] {
      def doWork: F[Unit] =
        Tracer[F].span("Work.DoWork").use { span =>
          span.addEvent("Starting the work.") *>
            doWorkInternal(steps = 10) *>
            span.addEvent("Finished working.")
        }

      def doWorkInternal(steps: Int): F[Unit] = {
        val step = Tracer[F]
          .span("internal", Attribute("steps", steps.toLong))
          .surround {
            for {
              random <- Random.scalaUtilRandom
              delay <- random.nextIntBounded(1000)
              _ <- Async[F].sleep(delay.millis)
              _ <- Console[F].println("Doin' work")
            } yield ()
          }

        if (steps > 0) step *> doWorkInternal(steps - 1) else step
      }
    }
}

object TracingExample extends IOApp.Simple {

  def tracer: Resource[IO, Tracer[IO]] =
    Resource.eval(IOLocal(Context.root)).flatMap { implicit local =>
      OtlpHttpSpanExporter.builder[IO].build.flatMap { exporter =>
        BatchSpanProcessor.builder[IO](exporter).build.evalMap { processor =>
          Random.scalaUtilRandom[IO].flatMap { implicit random: Random[IO] =>
            val tracerProvider = SdkTracerProvider
              .builder[IO]
              .addResource(InstrumentationResource(Attributes(Attribute("service.name", "sdk-exporter-native.scala"))))
              .addSpanProcessor(processor)
              .build

            tracerProvider.get("my-tracer")
          }
        }
      }
    }

  def run: IO[Unit] =
    tracer.use { implicit tracer: Tracer[IO] =>
      Work[IO].doWork
    }
}

Run (you should have s2n-tls installed):

$  scala-cli run --platform native --native-version 0.4.15 sdk-exporter-native.scala 

Spans exported to Jaeger:
image

# Conflicts:
#	build.sbt
#	sdk/trace/src/main/scala/org/typelevel/otel4s/sdk/trace/SdkSpanBackend.scala
# Conflicts:
#	sdk/common/src/main/scala/org/typelevel/otel4s/sdk/context/Context.scala
# Conflicts:
#	sdk/trace/src/main/scala/org/typelevel/otel4s/sdk/trace/samplers/ParentBasedSampler.scala
#	sdk/trace/src/main/scala/org/typelevel/otel4s/sdk/trace/samplers/Sampler.scala
#	sdk/trace/src/main/scala/org/typelevel/otel4s/sdk/trace/samplers/SamplingResult.scala
# Conflicts:
#	sdk/trace/src/main/scala/org/typelevel/otel4s/sdk/trace/SdkContextKeys.scala
#	sdk/trace/src/main/scala/org/typelevel/otel4s/sdk/trace/SdkTraceScope.scala
#	sdk/trace/src/test/scala/org/typelevel/otel4s/sdk/trace/SdkTraceScopeSuite.scala
# Conflicts:
#	build.sbt
#	core/common/src/main/scala/org/typelevel/otel4s/instances/LocalInstances.scala
#	core/trace/src/main/scala/org/typelevel/otel4s/trace/Span.scala
#	sdk/trace/src/main/scala/org/typelevel/otel4s/sdk/trace/SdkSpanBuilder.scala
#	sdk/trace/src/main/scala/org/typelevel/otel4s/sdk/trace/TracerSharedState.scala
#	sdk/trace/src/main/scala/org/typelevel/otel4s/sdk/trace/samplers/ParentBasedSampler.scala
#	sdk/trace/src/main/scala/org/typelevel/otel4s/sdk/trace/samplers/Sampler.scala
#	sdk/trace/src/main/scala/org/typelevel/otel4s/sdk/trace/samplers/TraceIdRatioBasedSampler.scala
# Conflicts:
#	.github/workflows/ci.yml
#	build.sbt
#	examples/src/main/scala/TraceSdkExample.scala
#	project/plugins.sbt
#	sdk/common/src/main/scala/org/typelevel/otel4s/sdk/Resource.scala
#	sdk/common/src/test/scala/org/typelevel/otel4s/sdk/ResourceSuite.scala
#	sdk/trace/src/main/scala/org/typelevel/otel4s/sdk/trace/data/EventData.scala
#	sdk/trace/src/main/scala/org/typelevel/otel4s/sdk/trace/data/SpanData.scala
#	sdk/trace/src/main/scala/org/typelevel/otel4s/sdk/trace/exporter/SpanExporter.scala
#	sdk/trace/src/test/scala/org/typelevel/otel4s/sdk/trace/exporter/InMemorySpanExporter.scala
@iRevive
Copy link
Contributor Author

iRevive commented Jan 5, 2024

Closing in favor of #421.

@iRevive iRevive closed this Jan 5, 2024
@iRevive iRevive deleted the sdk-exporter-trace branch February 5, 2024 19:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant