traceway / opentelemetry-symfony
Pure-PHP OpenTelemetry instrumentation for Symfony — automatic HTTP, Console, HttpClient, Messenger, Doctrine DBAL, Cache, Twig tracing and Monolog log-trace correlation with response propagation, a lightweight Tracing helper, route templates, and semantic conventions. No C extension required (ext-p
Package info
github.com/tracewayapp/opentelemetry-symfony-bundle
Type:symfony-bundle
pkg:composer/traceway/opentelemetry-symfony
Requires
- php: >=8.1
- open-telemetry/api: ^1.9
- open-telemetry/context: ^1.5
- open-telemetry/sdk: ^1.14
- open-telemetry/sem-conv: ^1.38
- symfony/config: ^6.4 || ^7.0 || ^8.0
- symfony/console: ^6.4 || ^7.0 || ^8.0
- symfony/dependency-injection: ^6.4 || ^7.0 || ^8.0
- symfony/event-dispatcher: ^6.4 || ^7.0 || ^8.0
- symfony/http-foundation: ^6.4 || ^7.0 || ^8.0
- symfony/http-kernel: ^6.4 || ^7.0 || ^8.0
- symfony/yaml: ^6.4 || ^7.0 || ^8.0
Requires (Dev)
- doctrine/dbal: ^4.0
- monolog/monolog: ^3.0
- open-telemetry/contrib-aws: ^1.2
- phpstan/phpstan: ^2.0
- phpunit/phpunit: ^10.0 || ^11.0 || ^13.0
- symfony/cache: ^6.4 || ^7.0 || ^8.0
- symfony/framework-bundle: ^6.4 || ^7.0 || ^8.0
- symfony/http-client: ^6.4 || ^7.0 || ^8.0
- symfony/mailer: ^6.4 || ^7.0 || ^8.0
- symfony/messenger: ^6.4 || ^7.0 || ^8.0
- symfony/monolog-bundle: ^3.10 || ^4.0
- symfony/phpunit-bridge: ^7.2 || ^8.0
- symfony/scheduler: ^6.4 || ^7.0 || ^8.0
- twig/twig: ^3.0 || ^4.0
Suggests
- ext-protobuf: Significantly faster protobuf serialization for OTLP export (use with OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf)
- doctrine/dbal: Required for automatic Doctrine DBAL query tracing (^3.6 || ^4.0)
- monolog/monolog: Required for log-trace correlation and OTel log export (trace_id/span_id injection + OTLP log shipping)
- open-telemetry/contrib-aws: Required for native AWS X-Ray support (open_telemetry.propagator: xray and open_telemetry.id_generator: xray)
- open-telemetry/exporter-otlp: Required to export traces via OTLP (the most common protocol for OpenTelemetry backends)
- php-http/guzzle7-adapter: HTTP transport for the OTLP exporter (or use any PSR-18 client)
- symfony/cache: Required for automatic cache pool tracing (get/delete/invalidateTags)
- symfony/http-client: Required for automatic HttpClient outgoing request tracing
- symfony/mailer: Required for automatic Mailer instrumentation (PRODUCER spans around MailerInterface::send and CLIENT spans around the transport)
- symfony/messenger: Required for automatic Messenger job/task tracing
- symfony/monolog-bundle: Required when log_export_enabled is true — wires OtelLogHandler into Monolog's handler stack
- symfony/scheduler: Required for automatic Scheduler tracing (CONSUMER spans around RecurringMessage execution, with trigger metadata)
- twig/twig: Required for automatic Twig template rendering tracing
Conflicts
- open-telemetry/api: <1.0
- open-telemetry/sdk: <1.0
- v2.2.0
- v2.1.0
- dev-master / 2.0.x-dev
- v2.0.0
- v1.9.0
- v1.8.0
- v1.7.0
- v1.6.1
- v1.6.0
- v1.5.0
- v1.4.4
- v1.4.3
- v1.4.2
- v1.4.1
- v1.4.0
- v1.3.2
- v1.3.1
- v1.3.0
- v1.2.1
- v1.2.0
- v1.1.0
- v1.0.2
- v1.0.1
- v1.0.0
- dev-feat/traceway-doctor
- dev-ci/catch-php-deprecations
- dev-feat/v2-nested-config
- dev-feat/v2.0
- dev-feat/phpunit-13
- dev-feat/mailer-metrics
- dev-feat/scheduler-instrumentation
- dev-feat/mailer-instrumentation
- dev-feat/log-export-attribute-prefix
- dev-fix/reset-and-cleanup-consistency
- dev-refactor/drop-redundant-channel-attribute
- dev-feat/log-export-code-attributes
- dev-bug/async-response-bug
- dev-feat/dbal-operation-target-span-name
- dev-test/improve-coverage
- dev-feat/log-export
- dev-bug/support-namespacedpoolinterface
- dev-feat/dbal-3-support
- dev-bug/messenger-orphaned-spans
- dev-feat/traceway
- dev-test-lockable
- dev-dist-trace-id
This package is not auto-updated.
Last update: 2026-06-01 13:20:00 UTC
README
OpenTelemetry Symfony Bundle
Pure-PHP OpenTelemetry instrumentation for Symfony. Automatic tracing for HTTP, Console, HttpClient, Messenger, Mailer, Scheduler, Doctrine DBAL, Cache, and Twig — plus Monolog log-trace correlation, OTel log export, and opt-in metrics. No C extension required.
Works with any OpenTelemetry-compatible backend: Traceway, Jaeger, Zipkin, Datadog, Grafana Tempo, Honeycomb, AWS X-Ray, and more.
- Pure PHP — installs on every managed Symfony host
- Production-ready — stable since v1.0, PHPStan level 10 with no baseline, Symfony 6.4 LTS through 8.x
- Correct under load — Messenger context propagates across async boundaries, DBAL 3 and 4 CI-tested, re-entrance guards on HttpClient and the log handler
Installation
composer require traceway/opentelemetry-symfony
Symfony Flex registers the bundle automatically. Without Flex, add it to config/bundles.php:
return [ // ... Traceway\OpenTelemetryBundle\OpenTelemetryBundle::class => ['all' => true], ];
Quick Start
OTEL_PHP_AUTOLOAD_ENABLED=true OTEL_SERVICE_NAME=my-symfony-app OTEL_TRACES_EXPORTER=otlp OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 OTEL_EXPORTER_OTLP_PROTOCOL=http/json
That's it. Every HTTP request, console command, outgoing call, Messenger job, DB query, cache operation, and Twig render is now traced.
It is also possible to use Symfony's DotEnv component in combination with the open_telemetry.sdk bundle configuration section for OTEL_PHP_AUTOLOAD_ENABLED, OTEL_RESOURCE_ATTRIBUTES and OTEL_EXPORTER_OTLP_HEADERS to set the relevant SDK configuration, see docs/configuration.md for more details. Using configuration setting open_telemetry.sdk.autoload_enabled registers the OpenTelemetry SDK without needing to set OTEL_PHP_AUTOLOAD_ENABLED before Composer's autoload is loaded. Furthermore, using open_telemetry.sdk.resource_attributes allows OTEL_RESOURCE_ATTRIBUTES to be set more conveniently and also supports the use of Symfony Secrets and the same applies with open_telemetry.sdk.exporter_otlp_headers for OTEL_EXPORTER_OTLP_HEADERS.
Verify the wiring:
bin/console traceway:doctor
What Gets Traced
| Component | Span Kind | What's captured |
|---|---|---|
| HTTP requests | SERVER | Route templates (GET /api/items/{id}), status codes, body sizes, client IP, exceptions, sub-requests |
| Console commands | SERVER | Command name, arguments, exit code, exceptions |
| HttpClient | CLIENT | Outgoing requests with W3C context propagation, OTLP endpoint auto-excluded, re-entrance guard |
| Messenger | PRODUCER/CONSUMER | Message class, transport, W3C context propagation across async boundaries |
| Scheduler | CONSUMER | Schedule name, trigger, next-run, cancellation marker. Requires symfony/scheduler |
| Mailer | PRODUCER + CLIENT | Two-span split on MailerInterface::send and the transport. Recipient count, message-id, X-Transport routing |
| Doctrine DBAL | CLIENT | Parameterised SQL, transactions, db system/namespace auto-detection. DBAL 3.6+ and 4.x CI-tested |
| Cache | INTERNAL | get (hit/miss), delete, invalidateTags with pool name. Requires symfony/cache |
| Twig | INTERNAL | Template name, nested includes. Requires twig/twig |
| Monolog | — | Inject trace_id + span_id into every log record. Opt-in OTel Logs API export with per-channel scope |
Also: Server-Timing response headers, full OTel semantic conventions.
Configuration
All options are optional — the bundle works out of the box. A minimal config/packages/open_telemetry.yaml:
open_telemetry: traces: excluded_paths: [/health, /_profiler, /_wdt] metrics: enabled: true logs: correlation: enabled: true
See docs/configuration.md for the full reference and environment variables.
Manual Instrumentation
Inject TracingInterface for one-liner span creation:
use Traceway\OpenTelemetryBundle\TracingInterface; class OrderService { public function __construct(private readonly TracingInterface $tracing) {} public function process(int $orderId): void { $this->tracing->trace('order.validate', fn () => $this->validate($orderId)); $this->tracing->trace('order.fulfill', function () { $this->tracing->trace('inventory.reserve', fn () => $this->reserve()); $this->tracing->trace('payment.charge', fn () => $this->charge()); }); } }
Mock in tests with $this->createStub(TracingInterface::class) and have trace() invoke the callback directly.
Metrics
Opt-in OpenTelemetry metrics — Messenger, Doctrine DBAL, HTTP server/client, and Mailer — alongside a MeterRegistryInterface for custom counters/histograms. See docs/metrics.md.
Doctor
bin/console traceway:doctor runs diagnostic checks against the bundle's wiring, SDK environment variables, and OTLP endpoint reachability — text or JSON, scriptable in CI.
Runtime
✓ ext-opentelemetry not loaded (no conflict risk)
SDK configuration
✓ OTEL_SERVICE_NAME = "my-symfony-app"
✓ OTEL_TRACES_EXPORTER = otlp
Connectivity
✓ OTLP endpoint reachable (HTTP 404, 7ms)
Results: 9 ok, 0 warning, 0 error, 3 skipped, 0 info
See docs/doctor.md for flags, JSON envelope schema, and custom checks.
Documentation
| Configuration | Full config reference and environment variables |
| Metrics | Instrument list, manual metrics, exemplars |
| AWS X-Ray | Native propagator / id_generator keys |
| Doctor | traceway:doctor flags, JSON output, custom checks |
| Performance | Overhead, sampling, exporter choice |
| Upgrade from v1.x | Flat → nested config migration |
| Changelog | Release history |
Contributing
git clone https://github.com/tracewayapp/opentelemetry-symfony-bundle.git
cd opentelemetry-symfony-bundle
composer install
vendor/bin/phpunit
vendor/bin/phpstan analyse
See CONTRIBUTING.md. Join the conversation on Discord.