How otel4s context works with the otel4s Java agent

Use Use the otel4s Java agent for the setup steps. Use Keep otel4s context in sync with OpenTelemetry Java for the non-agent setup path.

This page explains how otel4s-opentelemetry-javaagent works with otel4s context propagation and why some deployment shapes are risky. otel4s-opentelemetry-javaagent is a custom distribution of the upstream OpenTelemetry Java agent: it keeps the same automatic instrumentation behavior and also adds Cats Effect and otel4s integrations.

The standard Java agent and otel4s solve different context problems

OpenTelemetry Java and otel4s both track the current trace context, but they do not use the same mechanism by default.

That difference matters whenever Java code and otel4s code both need to observe the same current span.

Examples:

Without extra integration, those paths do not automatically share context.

Why otel4s-opentelemetry-javaagent exists

The standard OpenTelemetry Java agent already configures the global SDK and instruments many service boundaries. That solves SDK bootstrap and automatic tracing, but it does not by itself make Cats Effect fiber-local context and Java ThreadLocal context behave as one system.

This custom distribution exists to bridge that gap for JVM applications that use Cats Effect and otel4s.

At a high level, it combines:

That is why the how-to for this agent uses OtelJava.global[IO] rather than OtelJava.autoConfigured[IO](): the agent already owns SDK creation.

When this path fits

Use otel4s-opentelemetry-javaagent when:

Prefer the regular JVM setup pages when:

Where IOLocal and ThreadLocal meet

Cats Effect propagates request-scoped state across fibers. OpenTelemetry Java expects request-scoped state to be readable from the current thread.

The agent-specific integration works by making those two views line up closely enough for mixed Java and otel4s code to see the same current context during normal application execution. In practice, that means otel4s can keep using Cats Effect-local context while Java libraries and agent instrumentation can still read the current context through the usual OpenTelemetry Java APIs. The important result is not that the two mechanisms become identical. It is that otel4s code and Java code can agree on the current tracing context in the supported setup.

Mechanism at a glance

The agent-specific integration uses a few pieces together:

These are implementation details of an experimental integration. They explain why the setup can make mixed Java and otel4s code observe the same current context in the supported deployment shape.

Why the agent how-to requires OtelJava.global

With the agent path, there is already one process-wide SDK instance.

If application code also calls OtelJava.autoConfigured[IO](), it creates a second SDK instance that is isolated from the one managed by the agent. That leads to split telemetry pipelines and broken assumptions about shared state.

So the agent path uses:

This is why the Java agent how-to and the plain JVM setup how-to are separate tasks.

Why multi-application containers are risky

The agent integration relies on shared JVM-level state to connect Java context handling and Cats Effect context tracking.

That is workable for the common case of one application in one JVM. It becomes much harder to reason about when multiple applications share the same JVM process, such as:

In those environments, applications can interfere with one another's assumptions about context setup. That is why the agent how-to keeps the limitation explicit instead of treating it as an edge case.