Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/tracewayapp/opentelemetry-symfony-bundle/llms.txt

Use this file to discover all available pages before exploring further.

Once the bundle is registered and the OpenTelemetry environment variables are configured, every listed component is instrumented automatically — no code changes, annotations, or decorators needed. The bundle hooks into Symfony’s event system, Messenger middleware pipeline, and decorator pattern to wrap each integration with properly named spans, semantic-convention attributes, and context propagation.
All instrumentation is enabled by default. You can disable or tune individual integrations through config/packages/open_telemetry.yaml without touching application code.

HTTP Requests

Symfony’s HttpKernel events drive one span per HTTP request, including sub-requests.
DetailValue
Span kindSERVER (main requests) · INTERNAL (sub-requests)
Span nameHTTP METHOD initially, then updated to route template, e.g. GET /api/items/{id}
Attributeshttp.request.method, url.full, url.path, url.scheme, url.query, server.address, server.port, network.protocol.version, user_agent.original, client.address (opt-out), http.response.status_code, http.request.body.size, http.response.body.size
Error recordingExceptions are recorded on the span; status codes ≥ threshold (500 default) set STATUS_ERROR
Context extractionW3C traceparent/tracestate headers are extracted from the incoming request to continue a distributed trace
Relevant config keys:
open_telemetry:
    traces:
        excluded_paths: [/health, /_profiler, /_wdt]
        record_client_ip: true          # set false to comply with GDPR
        error_status_threshold: 500     # 400–599; responses below this threshold are not errors
Route parameters are substituted back to placeholders (e.g. /api/items/42/api/items/{id}) using longest-match replacement, so trace backends correctly group high-cardinality endpoints.

Console Commands

Every Symfony console command dispatch is wrapped in a SERVER span.
DetailValue
Span kindSERVER
Span nameCommand name (e.g. app:send-emails)
AttributesCommand name, arguments, exit code, exception details on failure
Relevant config keys:
open_telemetry:
    traces:
        console:
            enabled: true
            excluded_commands: [cache:clear, assets:install]

HttpClient (Outgoing Requests)

TraceableHttpClient decorates HttpClientInterface to add CLIENT spans and inject W3C propagation headers on every outgoing call.
DetailValue
Span kindCLIENT
Span nameMETHOD hostname (e.g. GET api.example.com)
Attributeshttp.request.method, url.full, url.path, url.scheme, server.address, server.port, http.response.status_code
Context injectiontraceparent / tracestate headers are injected into every outgoing request
Special behaviors:
  • OTLP endpoint auto-exclusion — any URL that starts with the value of OTEL_EXPORTER_OTLP_ENDPOINT is always skipped, preventing instrumentation loops where the exporter itself triggers a new span.
  • Re-entrance guard — if an outgoing HTTP call is triggered while another traced call is already in flight (e.g. the OTLP exporter uses this same client), the nested call is passed through without creating a span.
  • excluded_hosts — additional hostnames to skip, matched case-insensitively.
Relevant config keys:
open_telemetry:
    traces:
        http_client:
            enabled: true
            excluded_hosts: [internal-service.local]
Disabling the OTLP endpoint auto-exclusion is not possible through config — it is always enforced to prevent infinite export loops.

Messenger

The OpenTelemetryMiddleware creates spans on both the dispatch and consume sides, carrying trace context across async transport boundaries with TraceContextStamp.
DetailValue
Span kind (dispatch)PRODUCER
Span kind (consume)CONSUMER
Span nameShort message class name + operation, e.g. ProcessOrder publish / ProcessOrder process
Attributesmessaging.system=symfony_messenger, messaging.operation.type, messaging.message.class, messaging.destination.name (transport name on consume)
W3C propagationtraceparent/tracestate are serialised into a TraceContextStamp on dispatch and extracted on consume, linking async worker spans to their originating trace
root_spans mode — when enabled, consumed messages create root spans with no parent, so task-oriented backends (Traceway, Sentry) classify each job as an independent task rather than a child of the dispatch trace. Relevant config keys:
open_telemetry:
    traces:
        messenger:
            enabled: true
            root_spans: false     # true = standalone traces per consumed message

Scheduler

The Scheduler integration instruments symfony/scheduler tasks via dedicated events, suppressing the parallel Messenger span that would otherwise be created for the same message.
DetailValue
Span kindCONSUMER
AttributesSchedule name, trigger description, next-run timestamp, cancellation marker
Relevant config keys:
open_telemetry:
    traces:
        scheduler:
            enabled: true    # automatically suppresses duplicate Messenger spans for scheduled tasks
Requires symfony/scheduler. When scheduler.enabled: true, the Messenger middleware is automatically told to skip envelopes carrying ScheduledStamp so the richer scheduler span owns the observability without duplicate spans appearing.

Mailer

Mailer instrumentation uses a two-span split: one span at MailerInterface::send and a child span at the transport layer, giving you both the logical send and the actual transport call.
DetailValue
Span kindsPRODUCER (logical send) + CLIENT (transport)
AttributesRecipient count, message-id, X-Transport routing header, subject (opt-in)
Relevant config keys:
open_telemetry:
    traces:
        mailer:
            enabled: true
            record_subject: false    # subjects may contain PII — disabled by default

Doctrine DBAL

Every Connection::query(), Connection::exec(), prepared Statement::execute(), and transaction control call is wrapped in a CLIENT span. DBAL 3.6+ and 4.x are both CI-tested.
DetailValue
Span kindCLIENT
Attributesdb.system.name, db.namespace, server.address, server.port, db.operation.name (leading SQL keyword), db.collection.name (primary table when extractable)
SQL text (the full query string) is never recorded in span attributes by default. Set record_statements: false to hide even parameterised SQL from span names if required.
Relevant config keys:
open_telemetry:
    traces:
        doctrine:
            enabled: true
            record_statements: true    # false = hide SQL from span names entirely

Cache

Cache pool operations are instrumented as INTERNAL spans, capturing hit/miss outcomes. Requires symfony/cache.
DetailValue
Span kindINTERNAL
Operationsget (with hit/miss flag), delete, invalidateTags
AttributesPool name, cache key, hit/miss result
Relevant config keys:
open_telemetry:
    traces:
        cache:
            enabled: true
            excluded_pools: [cache.system, cache.validator, cache.serializer]

Twig

Template rendering is captured as INTERNAL spans, including nested {% include %} and {% embed %} calls. Requires twig/twig.
DetailValue
Span kindINTERNAL
AttributesTemplate name
Relevant config keys:
open_telemetry:
    traces:
        twig:
            enabled: true
            excluded_templates: ['@WebProfiler/', '@Debug/']

Monolog Log-Trace Correlation

The bundle automatically wires log-trace correlation through TraceContextProcessor, a standard Monolog ProcessorInterface that injects the active trace_id and span_id into the extra array of every log record. If no span is active (e.g. a log emitted outside a request), the record is passed through unchanged.
DetailValue
Span kind— (not a span; injects into log records)
Fields injectedextra.trace_id, extra.span_id
BehaviorInjected on every Monolog record during an active span; no-op otherwise
These values are forwarded by any existing Monolog handler (file, Elasticsearch, Datadog, etc.) — no OTel export infrastructure is required for correlation. Relevant config keys:
open_telemetry:
    logs:
        correlation:
            enabled: true    # default — inject trace_id/span_id into every log record
        export:
            enabled: false   # opt-in: forward records to OTel Logs API backend
OTel log export (forwarding Monolog records to an OpenTelemetry-compatible log backend via OTEL_LOGS_EXPORTER) is separate from correlation and is disabled by default. See the Logs page for the full export configuration.

Server-Timing Response Headers

The bundle automatically injects a Server-Timing response header on every traced HTTP request, reporting the trace ID so browser DevTools can correlate network timings with backend traces — no extra configuration required.

OTel Semantic Conventions

All attribute names follow the OpenTelemetry Semantic Conventionshttp.*, url.*, server.*, db.*, messaging.*, code.*. This means spans are immediately interpretable by any OTel-compatible backend without custom mapping.
To disable a specific instrumentation, set its enabled key to false. For example, to turn off HttpClient tracing:
open_telemetry:
    traces:
        http_client:
            enabled: false
Each component can be individually enabled or disabled without affecting the others.

Build docs developers (and LLMs) love