Skip to content

Commit

Permalink
Add minimal documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
iRevive committed Dec 31, 2024
1 parent 5ad342c commit 44ddc9a
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 3 deletions.
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,7 @@ lazy val oteljava = project
`oteljava-metrics` % "compile->compile;test->test",
`oteljava-metrics-testkit` % Test,
`oteljava-trace` % "compile->compile;test->test",
`oteljava-trace-testkit` % Test,
`oteljava-trace-testkit` % Test
)
.settings(
name := "otel4s-oteljava",
Expand Down
1 change: 1 addition & 0 deletions docs/oteljava/directory.conf
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ laika.title = OtelJava
laika.navigationOrder = [
overview.md
metrics-jvm-runtime.md
tracing-context-propagation.md
tracing-java-interop.md
testkit.md
]
85 changes: 85 additions & 0 deletions docs/oteljava/tracing-context-propagation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Tracing | Context propagation

[OpenTelemetry Java SDK][opentelemetry-java] and otel4s rely on different context manipulation approaches,
which aren't interoperable out of the box.
Java SDK utilizes ThreadLocal variables to share tracing information,
otel4s, on the other hand, uses [Local][cats-mtl-local].

Cats Effect 3.6.0 introduced a new method of fiber context tracking,
which can be integrated almost seamlessly with the OpenTelemetry Java SDK.

## Getting started

@:select(build-tool)

@:choice(sbt)

Add settings to the `build.sbt`:

```scala
libraryDependencies ++= Seq(
"org.typelevel" %% "otel4s-oteljava" % "@VERSION@", // <1>
"org.typelevel" %% "otel4s-oteljava-context-storage" % "@VERSION@", // <2>
)
javaOptions += "-Dcats.effect.trackFiberContext=true" // <3>
```

@:choice(scala-cli)

Add directives to the `*.scala` file:

```scala
//> using dep "org.typelevel::otel4s-oteljava:@VERSION@" // <1>
//> using dep "org.typelevel::otel4s-oteljava-context-storage:@VERSION@" // <2>
//> using `java-opt` "-Dcats.effect.trackFiberContext=true" // <3>
```

@:@

1. Add the `otel4s-oteljava` library
2. Add the `otel4s-oteljava-context-storage` library
3. Enable Cats Effect fiber context tracking

## Configuration

You need to use `IOLocalContextStorage.localProvider[IO]` to provide the global context storage, backed by `IOLocal`:
```scala mdoc:silent
import cats.effect.IO
import io.opentelemetry.api.trace.{Span => JSpan}
import org.typelevel.otel4s.context.LocalProvider
import org.typelevel.otel4s.oteljava.IOLocalContextStorage
import org.typelevel.otel4s.oteljava.OtelJava
import org.typelevel.otel4s.oteljava.context.Context
import org.typelevel.otel4s.trace.Tracer

def program(tracer: Tracer[IO]): IO[Unit] =
tracer.span("test").use { span => // start 'test' span using otel4s
val jSpanContext = JSpan.current().getSpanContext // get a span from a ThreadLocal var
IO.println(s"jctx: ${jSpanContext}") >> IO.println(s"otel4s: ${span.context}")
}

def run: IO[Unit] = {
implicit val provider: LocalProvider[IO, Context] =
IOLocalContextStorage.localProvider[IO]

OtelJava.autoConfigured[IO]().use { otelJava =>
otelJava.tracerProvider.tracer("com.service").get.flatMap { tracer =>
program(tracer)
}
}
}
```

According to the output, the context is the same:
```
jctx : SpanContext{traceId=58b8ed50a558ca53fcc64a0d80b5e662, spanId=fc25fe2c9fb41905, ...}
otel4s: SpanContext{traceId=58b8ed50a558ca53fcc64a0d80b5e662, spanId=fc25fe2c9fb41905, ...}
```

## Limitations

The `IOLocalContextStorageProvider` doesn't work with [OpenTelemetry Java Agent][opentelemetry-java-agent].

[opentelemetry-java]: https://github.com/open-telemetry/opentelemetry-java
[opentelemetry-java-agent]: https://opentelemetry.io/docs/zero-code/java/agent/
[cats-mtl-local]: https://typelevel.org/cats-mtl/mtl-classes/local.html
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,11 @@ object IOLocalContextStorage {
)
)
}
case _ =>
case other =>
F.raiseError(
new IllegalStateException(
"IOLocalContextStorage is not configured for use as the ContextStorageProvider"
s"IOLocalContextStorage is not configured for use as the ContextStorageProvider. " +
s"The current storage: ${other.getClass.getName}."
)
)
}
Expand Down

0 comments on commit 44ddc9a

Please sign in to comment.