Open-Source Wikis

/

Envoy

/

Features

/

Tracing

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: report

Sampling 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 / tracing overrides.

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

  1. New directory under source/extensions/tracers/<name>/.
  2. Implement Tracing::Driver, Tracing::Span, plus a Server::Configuration::TracerFactory.
  3. Proto under api/envoy/config/trace/v3/.
  4. Register in extensions_build_config.bzl.

The simplest reference is zipkin; opentelemetry is the most flexible (composable resource detectors and samplers).

See also

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Tracing – Envoy wiki | Factory