Skip to content

OpenTelemetry tracing

reflex serve emits OpenTelemetry GenAI-semantic-convention spans for every /act call. Point Phoenix, Datadog, Honeycomb, New Relic, or any OTLP-compatible backend at it.

Terminal window
pip install 'reflex-vla[tracing]'

Without the [tracing] extra, tracing no-ops silently. Server emits nothing and costs nothing.

Terminal window
# Terminal 1 — Phoenix UI on :6006, OTLP gRPC collector on :4317
pip install arize-phoenix
phoenix serve
# Terminal 2 — Reflex pointing at it
reflex serve ./my-export/ --otel-endpoint localhost:4317 --otel-sample 1.0

Hit /act and open http://localhost:6006 — every request shows up as an act span.

FlagDefaultPurpose
--otel-endpoint$OTEL_EXPORTER_OTLP_ENDPOINT or localhost:4317OTLP gRPC endpoint
--otel-sample1.0Fraction of traces to sample. Parent-based — child spans inherit the root’s decision.
  • Dev / staging: --otel-sample 1.0
  • Production, low traffic (under 100 RPS): --otel-sample 1.0 is fine — BatchSpanProcessor decouples export from the hot path
  • Production, high traffic (over 1000 RPS): --otel-sample 0.1 per OTel GenAI SemConv recommendation

You can also set OTEL_EXPORTER_OTLP_ENDPOINT as an env var.

Every /act call produces one root span named act.

AttributeTypeValue
gen_ai.operation.namestring"act"
gen_ai.request.modelstringExport directory path (post policy-versioning, this becomes the routing slot)

Robotics extensions (Reflex-specific, proposed upstream Phase 2)

Section titled “Robotics extensions (Reflex-specific, proposed upstream Phase 2)”
AttributeTypeValue
gen_ai.action.embodimentstringEmbodiment preset name or "custom"
gen_ai.action.chunk_sizeintNumber of actions returned in this chunk
gen_ai.action.denoise_stepsintDiffusion denoise iterations (when adaptive-denoise is active)

Reflex-specific (prefix intentional; not for upstream)

Section titled “Reflex-specific (prefix intentional; not for upstream)”
AttributeTypeValue
reflex.instructionstringFirst 512 chars of the instruction text (truncated — never raw bytes)
reflex.state_dimintLength of the proprio-state vector
reflex.image_bytesintSize of the posted image in bytes (size only — never the image data)
reflex.rtc.episode_idstringEpisode identifier when RTC adapter is active
reflex.rtc.episode_resetboolTrue on the first span of a new episode
reflex.inference_modestring"decomposed", "monolithic", "native", etc.
reflex.action_chunk_lenintSame as gen_ai.action.chunk_size; kept for backward compat
error.typestringPopulated only when the server returned an error

Reflex explicitly does not attribute:

  • Raw image bytes (could contain faces, text, identifiers on screens)
  • API keys or auth headers
  • Raw state vectors when they exceed 512 dims (use reflex.state_dim for size only)

Instructions are truncated to 512 chars. If your instructions carry secrets, filter them client-side before calling /act.

“Tracing skipped — pip install reflex-vla[tracing] to enable” — the [tracing] extra isn’t installed.

Spans appear in Phoenix but not in Datadog — Datadog Agent probably has receivers.otlp disabled. Enable OTLP gRPC on :4317 in datadog.yaml.

--otel-sample 0.1 but I see every trace — parent-based sampling inherits from incoming parent context. If an upstream client is propagating a sampled trace context (W3C traceparent), Reflex honors it.

Export slowing down /actBatchSpanProcessor is async; export failures shouldn’t bubble to request latency. If you see correlation, drop sampling or check collector health.