| title | Observability | |
|---|---|---|
| sdk | java | |
| spec_sections |
|
|
| kind | guide | |
| since | 1.0.0 |
ARCP propagates trace_id end-to-end across every envelope. The
arcp-otel module wraps any transport in an OpenTelemetry decorator that
creates a span per envelope send/receive.
// build.gradle.kts
implementation("dev.arcp:arcp-otel:1.0.0")
implementation("io.opentelemetry:opentelemetry-api:1.40.0")
runtimeOnly("io.opentelemetry:opentelemetry-sdk:1.40.0")
runtimeOnly("io.opentelemetry:opentelemetry-exporter-otlp:1.40.0")Wrap the transport before passing it to the client or runtime:
OpenTelemetry otel = GlobalOpenTelemetry.get(); // or SDK-configured instance
// Client side:
Transport base = WebSocketTransport.connect(serverUri);
Transport traced = OtelTransport.wrap(base, otel);
ArcpClient client = ArcpClient.builder(traced).build();
// Runtime side:
Transport rBase = pair[0];
Transport rTraced = OtelTransport.wrap(rBase, otel);
runtime.accept(rTraced);| Span | Created on | Parent |
|---|---|---|
arcp.send |
Every Transport.send(frame) call |
Current active context |
arcp.receive |
Every Transport.receive() call |
Extracted trace_id from envelope |
OtelTransport:
- On send — injects the current span context into the envelope's
trace_idfield before serializing. - On receive — extracts
trace_idfrom the deserialized envelope and activates a child span.
The trace_id envelope field carries an ARCP
TraceId.
It is optional in the spec; the OTel wrapper populates it on every send.
Propagation is end-to-end:
- Client → runtime: the client's active OTel trace context travels in
trace_id. - Runtime → client: events carry the same
trace_idset at job start. - Delegated sub-agent jobs inherit the parent's
trace_id.
Point the OTel SDK exporter at any compatible backend (Jaeger, Tempo, Honeycomb, Grafana Cloud...):
SdkTracerProvider provider = SdkTracerProvider.builder()
.addSpanProcessor(BatchSpanProcessor.builder(
OtlpGrpcSpanExporter.builder()
.setEndpoint("http://localhost:4317")
.build())
.build())
.build();
OpenTelemetrySdk otel = OpenTelemetrySdk.builder()
.setTracerProvider(provider)
.buildAndRegisterGlobal();examples/tracing/ — full end-to-end trace
with Jaeger via the OTLP exporter. Run with:
./gradlew :examples:tracing:run