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.

v2.0 restructures the bundle’s configuration to a nested, signal-grouped shape (traces: / metrics: / logs:) that aligns with the OpenTelemetry specification and the OTEL_* environment variable convention. Your existing v1.x flat config keeps working in v2.0 — every flat key emits a Symfony deprecation pointing at its new nested location. Flat keys are scheduled for removal in v3.0, giving you a full release cycle to migrate without any forced downtime.
The only breaking default change in v2.0 is logs.export.unprefixed_attributes flipping from false to true. If your dashboards filter on monolog.context.* or monolog.extra.* prefixed attributes, set unprefixed_attributes: false explicitly before upgrading. Everything else preserves v1.x behavior.

What changed

Config restructured

All flat top-level keys migrate under traces:, metrics: (unchanged), or logs:. The shape now mirrors the OTel signal hierarchy and the existing metrics: node that has been nested since v1.7.0.

Unprefixed attributes default

log_export_unprefixed_attributes defaulted to false in v1.x. v2.0 flips it to true, emitting Monolog context and extra fields as flat OTel attributes — matching Java, Python, .NET, and JS ecosystems.

Dependency floors raised

OpenTelemetry PHP package minimums are raised to match the tested baseline. Anyone on a modern Symfony project will already satisfy these floors from a normal composer update.

Dependency floors

Packagev1.x floorv2.0 floor
open-telemetry/api^1.0^1.9
open-telemetry/context^1.0^1.5
open-telemetry/sdk^1.0^1.14
open-telemetry/sem-conv^1.0^1.38
symfony/phpunit-bridge (dev)^6.4 || ^7.0 || ^8.0^7.2 || ^8.0
If you pin OpenTelemetry PHP packages explicitly in your own composer.json below these new floors, update them first:
composer require open-telemetry/sdk:^1.14 open-telemetry/sem-conv:^1.38

Migration steps

1

Upgrade to v2.0

Update the bundle via Composer. Your existing v1.x flat config will continue to work without any changes.
composer require traceway/opentelemetry-symfony:^2.0
2

Surface deprecations

Clear the cache and watch the Symfony deprecation log. Every flat key emits exactly one deprecation pointing at its new nested location.
bin/console cache:clear
In development, deprecations appear in the Symfony profiler’s “Logs” panel under the php channel. In CI, run with SYMFONY_DEPRECATIONS_HELPER=weak to surface them without failing.
3

Migrate keys to nested shape

Move keys one signal group at a time. Start with traces: — it has the most keys. Then move logs:. The metrics: node is unchanged and requires no migration.Use the flat → nested mapping table below as a reference. You can migrate incrementally: mix flat and nested keys across separate config files (e.g. config/packages/open_telemetry.yaml for nested and config/packages/dev/open_telemetry.yaml still flat), but avoid mixing them in the same block.
4

Decide on unprefixed_attributes

The new default for logs.export.unprefixed_attributes is true. Decide which behavior you want:
  • Accept the new default (true) — Monolog context and extra fields are emitted as flat OTel attributes. This matches the cross-ecosystem norm (Java logback, Python LoggingHandler, .NET, JS Winston) and is the recommended path.
  • Preserve v1.x behavior (false) — set unprefixed_attributes: false explicitly to keep the monolog.context.* / monolog.extra.* prefixed shape your existing dashboards may depend on.
open_telemetry:
    logs:
        export:
            unprefixed_attributes: false  # keep v1.x prefixed shape
5

Verify the final config

Dump the processed configuration to confirm the bundle sees the nested shape and all values are resolved correctly.
bin/console debug:config open_telemetry
The output should show the nested structure with no flat keys at the top level.

Flat → nested mapping

Every v1.x flat key and its v2.0 nested equivalent:
Legacy key (v1.x)New nested location (v2.0)
traces_enabledtraces.enabled
tracer_nametraces.tracer_name
excluded_pathstraces.excluded_paths
record_client_iptraces.record_client_ip
error_status_thresholdtraces.error_status_threshold
console_enabledtraces.console.enabled
console_excluded_commandstraces.console.excluded_commands
http_client_enabledtraces.http_client.enabled
http_client_excluded_hoststraces.http_client.excluded_hosts
messenger_enabledtraces.messenger.enabled
messenger_root_spanstraces.messenger.root_spans
doctrine_enabledtraces.doctrine.enabled
doctrine_record_statementstraces.doctrine.record_statements
cache_enabledtraces.cache.enabled
cache_excluded_poolstraces.cache.excluded_pools
twig_enabledtraces.twig.enabled
twig_excluded_templatestraces.twig.excluded_templates
scheduler_enabledtraces.scheduler.enabled
mailer_enabledtraces.mailer.enabled
mailer_record_subjecttraces.mailer.record_subject
monolog_enabledlogs.correlation.enabled
log_export_enabledlogs.export.enabled
log_export_levellogs.export.level
log_export_capture_code_attributeslogs.export.capture_code_attributes
log_export_unprefixed_attributeslogs.export.unprefixed_attributes (default flipped to true)
metrics: is unchanged — it was already nested and requires no migration.

Before / after

open_telemetry:
    traces_enabled: true
    tracer_name: 'opentelemetry-symfony'
    excluded_paths: [/health, /_profiler, /_wdt]
    record_client_ip: true
    error_status_threshold: 500
    console_enabled: true
    console_excluded_commands: [cache:clear]
    http_client_enabled: true
    http_client_excluded_hosts: []
    messenger_enabled: true
    messenger_root_spans: false
    doctrine_enabled: true
    doctrine_record_statements: true
    cache_enabled: true
    cache_excluded_pools: [cache.system]
    twig_enabled: true
    twig_excluded_templates: ['@WebProfiler/']
    scheduler_enabled: true
    mailer_enabled: true
    mailer_record_subject: false
    monolog_enabled: true
    log_export_enabled: false
    log_export_level: debug
    log_export_capture_code_attributes: false
    log_export_unprefixed_attributes: false
    metrics:
        enabled: false

Default change: logs.export.unprefixed_attributes

This is the only behavioral change in v2.0 that can silently affect running applications.
Monolog context and extra fields were emitted as namespaced OTel attributes:
monolog.context.order_id = "abc-123"
monolog.extra.memory_usage = 4096
Dashboard queries and alert rules filtering on monolog.context.* relied on this shape.
The same fields are emitted as flat OTel attributes:
order_id = "abc-123"
memory_usage = 4096
This matches Java logback, Python LoggingHandler, .NET OpenTelemetryLogger, and JS Winston — all of which emit user log fields flat without a namespace prefix.
To preserve the v1.x prefixed shape after upgrading, set the flag explicitly:
open_telemetry:
    logs:
        export:
            unprefixed_attributes: false

Conflict detection

Setting both a legacy flat key and its nested equivalent in the same configuration block causes the bundle to throw InvalidConfigurationException at container compile time:
open_telemetry:
    doctrine_enabled: false           # legacy flat key
    traces:
        doctrine: { enabled: true }   # nested equivalent — conflict!
InvalidConfigurationException:
Cannot set both legacy "open_telemetry.doctrine_enabled" and nested
"open_telemetry.traces.doctrine.enabled" in the same configuration
block. Use the nested form only.
Conflict detection only fires when both forms appear in the same file or configuration block. Across separate files (for example, config/packages/open_telemetry.yaml and config/packages/dev/open_telemetry.yaml), Symfony merges the blocks independently before the bundle sees them. In that case, standard Symfony merge semantics apply (typically the later file wins). Avoid splitting flat and nested forms for the same key across files.

Timeline

VersionStatus
v2.0Flat keys still accepted; each emits a Symfony deprecation pointing at the nested equivalent
v3.0Flat keys removed entirely — migrate before then

Build docs developers (and LLMs) love