OpenTelemetry tracing #
Authority: pinned Jetstream V2 commit
f29815c391fc2644f8a3dd36b899fb3697dd1ea6, specifically
internal/obs/tracing.go, internal/obs/observe.go, and its pinned
OpenTelemetry Go SDK v1.44.0.
Stream uses the sibling otel-zig SDK and OTLP exporter. No endpoint means a
no-op global provider. Setting either endpoint below installs a batched
provider, merges detected process/resource attributes with service.name and
service.version, and flushes it within the ordinary graceful-shutdown budget.
Both modes install the same process-wide W3C TraceContext plus Baggage composite
propagator as upstream, so an absent exporter does not discard incoming context.
| Environment | Behavior |
|---|---|
OTEL_EXPORTER_OTLP_ENDPOINT |
generic base URL; /v1/traces is appended |
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT |
trace URL used verbatim; takes precedence |
OTEL_EXPORTER_OTLP_HEADERS, OTEL_EXPORTER_OTLP_TRACES_HEADERS |
comma-separated HTTP headers; trace-specific replaces generic |
OTEL_EXPORTER_OTLP_COMPRESSION, OTEL_EXPORTER_OTLP_TRACES_COMPRESSION |
exact value gzip enables gzip |
OTEL_EXPORTER_OTLP_INSECURE, OTEL_EXPORTER_OTLP_TRACES_INSECURE |
true selects HTTP; every other non-empty value selects HTTPS |
OTEL_EXPORTER_OTLP_TIMEOUT, OTEL_EXPORTER_OTLP_TRACES_TIMEOUT |
request timeout in milliseconds |
OTEL_EXPORTER_OTLP_CERTIFICATE, OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE |
PEM certificate-authority bundle; trace-specific replaces generic |
OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE |
PEM client certificate; used only with the matching client key |
OTEL_EXPORTER_OTLP_CLIENT_KEY, OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY |
PEM client private key; used only with the matching client certificate |
OTEL_BSP_SCHEDULE_DELAY |
maximum batching delay in milliseconds |
OTEL_BSP_MAX_QUEUE_SIZE |
bounded completed-span queue |
OTEL_BSP_MAX_EXPORT_BATCH_SIZE |
maximum spans per request |
OTEL_BSP_EXPORT_TIMEOUT |
maximum milliseconds for one complete export, including requests, retry backoff, and server throttling |
OTEL_TRACES_SAMPLER |
always_on, always_off, traceidratio, or their three parentbased_ forms |
OTEL_TRACES_SAMPLER_ARG |
ratio in the inclusive range 0 through 1 |
Pinned upstream constructs otlptracehttp directly, so it always sends
OTLP/HTTP protobuf; OTEL_EXPORTER_OTLP_PROTOCOL and its trace-specific form do
not select JSON there and do not select JSON in Stream.
The executable accepts --otel-service-name; OTEL_SERVICE_NAME supplies its
default and jetstream is the fallback. CLI values take precedence.
Production span boundaries #
Stream carries one explicit trace context across the same asynchronous and durability boundaries as pinned upstream. The implemented span names are:
| Scope | Spans |
|---|---|
jetstream/ingest/orchestrator |
Run, runBootstrap, finishBootstrap, runMerge, merge-runner run, processSourceSegment, runDiscovery, runSteadyState, runDeleteCompaction, RunImport |
jetstream/ingest/backfill |
Run, handleRepo (including retry and live resync, with did) |
jetstream/ingest/live |
processBatch |
jetstream/ingest |
commitAsyncFlush, rotateIfFull, flushAndRotateLocked, rotateLocked (with active_idx) |
jetstream/xrpcapi |
getBlock (with segment.idx, block.index, block.compressed_size, and result) |
Spans end at the operation boundary, record returned errors, and mark
successful operations OK. Repository downloads remain children of the
backfill run; handleRepo begins only after a CAR has been accepted, matching
upstream's materialization boundary. Writer spans occur per block or rotation,
never per event.
Offline receipt #
The runtime/observability.zig contract starts a loopback HTTP
collector, installs the production provider, records a sampled span, and then
performs bounded shutdown. The collector asserts the protobuf content type,
endpoint path, configured header, instrumentation scope, span name,
service.name, and service.version from the received request body. Separate
tests cover no-op behavior and environment precedence/fallbacks. This receipt
requires no external network. The no-endpoint receipt also inspects the global
propagator fields, while otel-zig exercises traceparent, tracestate, and
W3C baggage injection/extraction with upstream's strict invalid-header behavior.
The exporter receipt drives 503 and 429 responses before a successful 202,
checks integer Retry-After, and verifies both the request timeout and the BSP
export timeout cancel their respective I/O boundaries. Retry defaults match
upstream: 5-second initial interval, 1.5 multiplier with jitter, 30-second cap,
60-second retry budget, and only 429/502/503/504 responses are retried.
The pinned otel-zig receipt generates an ephemeral CA, server certificate,
and client certificate and drives two local HTTPS collectors. One verifies
the native Zig transport trusts only the configured CA. The other requires a
verified client certificate, first rejects a client without it, and then
accepts the OTLP exporter through its dynamically loaded libcurl transport.
Stream's parser receipt separately
covers trace-specific precedence and upstream's behavior of ignoring an
incomplete client certificate/key pair.
runtime/tracing_integration_test.zig then drives the production archive in
both asynchronous and synchronous modes. An OTLP collector requires the
exported parent processBatch plus commitAsyncFlush, rotateIfFull,
rotateLocked, and flushAndRotateLocked children and both canonical scopes.
The xrpcapi.zig receipt seals a JSS segment, serves its compressed block,
then exercises a malformed request. Its collector requires both exported
spans, canonical XRPC scope and attributes, ok/bad_request results, and the
recorded failure event.
The production Debian image installs libcurl4 for the client-authenticated
path. Custom-CA-only and ordinary HTTPS exports use Zig's native TLS client and
do not load libcurl.