envoyproxy/envoy
Tracing
Tracing produces per-request spans that propagate downstream → Envoy → upstream and feed an observability backend. Every HTTP request is potentially a span; the HCM decides whether to sample based on bootstrap config, route config, runtime, and downstream-supplied trace headers. Implementations live under source/extensions/tracers/.
Shipped tracers
| Tracer | Path | Backend |
|---|---|---|
datadog |
datadog/ |
Datadog APM. Vendored dd-trace-cpp. |
opentelemetry |
opentelemetry/ |
Any OTLP backend. Optional resource detectors and sampler plugins. |
zipkin |
zipkin/ |
Zipkin / Jaeger HTTP. |
skywalking |
skywalking/ |
Apache SkyWalking. |
xray |
xray/ |
AWS X-Ray. |
fluentd |
fluentd/ |
Forward via Fluentd in OTLP/JSON shape. |
dynamic_modules |
dynamic_modules/ |
Tracer implemented in a dynamic module. |
common/ |
common/ |
Helpers shared across HTTP-based tracers. |
Lifecycle
sequenceDiagram
participant HCM as HTTP conn manager
participant Tracer as Tracer (decision)
participant Span as Span (per-request)
participant Filter as Filter chain
participant Router as Router
participant Backend as Backend
HCM->>Tracer: startSpan(operation, headers, decision)
Tracer-->>Span: new span
HCM->>Filter: decode pipeline
Filter->>Span: setTag, log
Filter->>Router: forward
Router->>Span: inject context into upstream headers
Router-->>HCM: response
HCM->>Span: finish
Span->>Backend: reportSampling is decided in source/common/tracing/http_tracer_impl.cc. Inputs:
- Forced trace headers (
x-client-trace-id,x-envoy-force-trace). - The HCM-level
tracing.client_sampling,random_sampling,overall_sampling. - The upstream tracing decision (sampled bit on incoming
traceparent/b3/x-datadog-sampling-priority). - The route's
decorator/start_child_span/tracingoverrides.
Header propagation
Each tracer registers the headers it understands on injection:
- Datadog:
x-datadog-trace-id,x-datadog-parent-id,x-datadog-sampling-priority. - OpenTelemetry:
traceparent,tracestate(W3C). - Zipkin:
x-b3-traceid,x-b3-spanid,x-b3-sampled,b3. - SkyWalking:
sw8. - X-Ray:
x-amzn-trace-id.
Multiple tracers can be configured at once on a listener; the HCM picks the first that accepts the inbound headers.
Driver and Span interfaces
Tracing::Driver (envoy/tracing/tracer.h) is the per-tracer factory; Tracing::Span (envoy/tracing/trace_context.h) is the per-request handle. Each tracer subclasses both. The HCM owns the driver; spans are owned by the active stream.
Tags and decorators
The HCM auto-populates standard tags: response status, request method, URL components, downstream/upstream addresses. Filters can call span->setTag() to add their own (e.g. ext_authz adds the upstream principal). Route decorators (Decorator.operation) override the span name.
Custom tracer
- New directory under
source/extensions/tracers/<name>/. - Implement
Tracing::Driver,Tracing::Span, plus aServer::Configuration::TracerFactory. - Proto under
api/envoy/config/trace/v3/. - Register in
extensions_build_config.bzl.
The simplest reference is zipkin; opentelemetry is the most flexible (composable resource detectors and samplers).
See also
- HTTP connection manager — owns sampling and span lifetime.
- Access logging — adjacent observability.
- Wasm, Dynamic modules — pluggable tracing.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.