Search by

traceway / opentelemetry-symfony

graphene

Pure-PHP OpenTelemetry instrumentation for Symfony: HTTP, Console, Messenger, Scheduler, Mailer, Doctrine DBAL, Cache and Twig tracing, outgoing HTTP through Symfony HttpClient, Guzzle and PSR-18 clients, opt-in metrics, and Monolog log correlation and export. Stable semantic conventions, no C exten

Package info

github.com/tracewayapp/opentelemetry-symfony-bundle

Type:symfony-bundle

pkg:composer/traceway/opentelemetry-symfony

Statistics

Installs: 61 993

Dependents: 0

Suggesters: 0

Stars: 86

Open Issues: 0

v4.1.0 2026-10-18 08:03 UTC

README

Traceway Logo

OpenTelemetry Symfony Bundle

CI codecov Packagist Version Packagist Downloads PHP Version Symfony Version License Discord

Pure-PHP OpenTelemetry instrumentation for Symfony. Automatic tracing for HTTP, Console, Messenger, Mailer, Scheduler, Doctrine DBAL, Cache, and Twig, and for outgoing HTTP through Symfony HttpClient, Guzzle and PSR-18 clients — 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 HTTP clients and the log handler, a worker soak test in CI that fails on any leaked memory or duplicated span

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.

Prefer configuring the SDK via the bundle instead of raw env vars (works with DotEnv and Symfony Secrets)? See the open_telemetry.sdk section in docs/configuration.md.

Verify the wiring:

bin/console traceway:doctor

What Gets Traced

HTTP requests (with route templates), Console commands, outgoing HTTP through Symfony HttpClient, any PSR-18 client and Guzzle, Messenger, Scheduler, Mailer, Doctrine DBAL, Cache, and Twig — plus Monolog trace_id/span_id correlation and opt-in OTel log export. Each subsystem is individually toggleable. See docs/index.md for the per-component span breakdown.

Semantic Conventions

Audited against the current OTel semantic conventions: every stable MUST/Required/Conditionally-Required rule is implemented, Recommended attributes are emitted wherever the data exists, and all deviations are deliberate and spec-permitted. See docs/semantic-conventions.md for the conformance statement, deviations, and known limitations.

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, HTTP client (Symfony HttpClient, Guzzle and PSR-18), and Mailer — alongside a MeterRegistryInterface for custom counters/histograms/gauges. 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. 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 to v4.0 Stable-only database attribute names
Upgrade to v3.0 Semantic-conventions conformance changes
Upgrade from v1.x Flat → nested config migration
Changelog Release history
Security Supported versions, private vulnerability reporting

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.

License

MIT