PHPackages                             traceway/opentelemetry-symfony - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. traceway/opentelemetry-symfony

ActiveSymfony-bundle[Database &amp; ORM](/categories/database)

traceway/opentelemetry-symfony
==============================

Pure-PHP OpenTelemetry instrumentation for Symfony — automatic HTTP, HttpClient, Messenger, and Doctrine DBAL tracing with response propagation, a lightweight Tracing helper, route templates, and semantic conventions. No C extension required.

v1.1.0(1mo ago)31↓100%MITPHPPHP &gt;=8.1CI passing

Since Mar 14Pushed 1mo agoCompare

[ Source](https://github.com/tracewayapp/opentelemetry-symfony-bundle)[ Packagist](https://packagist.org/packages/traceway/opentelemetry-symfony)[ Docs](https://github.com/tracewayapp/opentelemetry-symfony-bundle)[ RSS](/packages/traceway-opentelemetry-symfony/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (4)Dependencies (17)Versions (5)Used By (0)

OpenTelemetry Symfony Bundle
============================

[](#opentelemetry-symfony-bundle)

[![CI](https://github.com/tracewayapp/opentelemetry-symfony-bundle/actions/workflows/ci.yml/badge.svg)](https://github.com/tracewayapp/opentelemetry-symfony-bundle/actions/workflows/ci.yml)[![codecov](https://camo.githubusercontent.com/578e9ab0ca4d7c6d0b5a25073184b143400f1f8c16acc42f275412cf36aa5c1f/68747470733a2f2f636f6465636f762e696f2f67682f74726163657761796170702f6f70656e74656c656d657472792d73796d666f6e792d62756e646c652f67726170682f62616467652e737667)](https://codecov.io/gh/tracewayapp/opentelemetry-symfony-bundle)[![Packagist Version](https://camo.githubusercontent.com/aebf2e633114969dc5b25a55556150c1f2ec1a81e483648e5eedde16e336c12d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f74726163657761792f6f70656e74656c656d657472792d73796d666f6e792e737667)](https://packagist.org/packages/traceway/opentelemetry-symfony)[![Packagist Downloads](https://camo.githubusercontent.com/440fb495cfbe28a94beae249d1036421f87f938080648c1cf2b63b16cd08172c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f74726163657761792f6f70656e74656c656d657472792d73796d666f6e792e737667)](https://packagist.org/packages/traceway/opentelemetry-symfony)[![PHP Version](https://camo.githubusercontent.com/04744bae0a61d2ffe29c26f07a9612eae20445fc6feaeb77b3af1f0e9be6447c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253345253344382e312d3838393242462e737667)](https://php.net)[![Symfony Version](https://camo.githubusercontent.com/df69560fe6c25fd0268689a4bbba1950f74df1ee59a1b5d6f744f96d63043647/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f73796d666f6e792d253345253344362e342d3030303030302e737667)](https://symfony.com)[![License](https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667)](LICENSE)

Pure-PHP OpenTelemetry instrumentation for Symfony, **no C extension required**. Automatic HTTP, HttpClient, Messenger, and Doctrine DBAL tracing with a lightweight `Tracing` helper, route templates, response propagation, and full semantic conventions.

Works with any OpenTelemetry-compatible backend: [Traceway](https://tracewayapp.com), [Jaeger](https://www.jaegertracing.io/), [Zipkin](https://zipkin.io/), [Datadog](https://www.datadoghq.com/), [Sentry](https://sentry.io/), [Grafana Tempo](https://grafana.com/oss/tempo/), [Honeycomb](https://www.honeycomb.io/), and more.

Quick Start
-----------

[](#quick-start)

```
composer require traceway/opentelemetry-symfony
```

Set the environment variables for your OTel backend:

```
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/protobuf
```

That's it. Every HTTP request, outgoing HttpClient call, and Messenger job is now traced automatically.

Features
--------

[](#features)

- **Automatic HTTP tracing** — SERVER spans for every request with route templates (`GET /api/items/{id}`), body size attributes, semantic conventions, sub-request support, and exception recording
- **HttpClient instrumentation** — CLIENT spans for every outgoing HTTP request with W3C Trace Context propagation into downstream services
- **Response propagation** — injects trace context into response headers (Server-Timing, traceresponse) for browser-side correlation
- **Symfony Messenger instrumentation** — automatic CONSUMER spans for dispatched/consumed messages with W3C Trace Context propagation across transports
- **Doctrine DBAL instrumentation** — CLIENT spans for every database query with `db.system.name`, `db.operation.name`, `db.namespace`, `db.query.text`, and `server.address`/`server.port`
- **`Tracing` helper** — one-liner span creation for manual instrumentation (cache, HTTP calls, etc.)
- **Fully configurable** — exclude paths, toggle features, set error thresholds, control root span behavior, toggle SQL recording
- **No C extension required** — works on any PHP 8.1+ hosting, unlike the official `ext-opentelemetry` based package

Requirements
------------

[](#requirements)

- PHP &gt;= 8.1
- Symfony &gt;= 6.4
- OpenTelemetry PHP SDK &gt;= 1.0
- Doctrine DBAL &gt;= 4.0 *(optional, for database tracing)*

Installation
------------

[](#installation)

```
composer require traceway/opentelemetry-symfony
```

If your application doesn't use Symfony Flex, enable the bundle manually in `config/bundles.php`:

```
return [
    // ...
    Traceway\OpenTelemetryBundle\OpenTelemetryBundle::class => ['all' => true],
];
```

Configuration
-------------

[](#configuration)

Create `config/packages/open_telemetry.yaml` (all options are optional — the bundle works out of the box with zero configuration):

```
open_telemetry:
    # Enable automatic HTTP trace instrumentation (default: true)
    traces_enabled: true

    # Instrumentation library name reported to your OTel backend (default: 'opentelemetry-symfony')
    tracer_name: 'opentelemetry-symfony'

    # URL path prefixes to exclude from tracing
    excluded_paths:
        - /health
        - /_profiler
        - /_wdt

    # Record client IP on spans — disable for GDPR compliance (default: true)
    record_client_ip: true

    # HTTP status codes >= this value are marked as errors (default: 500, range: 400-599)
    error_status_threshold: 500

    # Instrument Symfony HttpClient: CLIENT spans for outgoing requests (default: true)
    http_client_enabled: true

    # Instrument Symfony Messenger (default: true)
    messenger_enabled: true

    # Create root spans for consumed messages instead of linking to the
    # dispatching trace (default: false)
    messenger_root_spans: false

    # Instrument Doctrine DBAL: CLIENT spans for database queries (default: true)
    # Requires doctrine/dbal ^4.0
    doctrine_enabled: true

    # Record SQL on spans (default: true)
    # Prepared statements use ? placeholders; query()/exec() record raw SQL
    doctrine_record_statements: true
```

### Environment Variables

[](#environment-variables)

The OpenTelemetry PHP SDK is configured via standard `OTEL_*` environment variables. Set these in your `.env`, server config, or Docker environment:

VariableExampleDescription`OTEL_PHP_AUTOLOAD_ENABLED``true`Enable SDK auto-initialization`OTEL_SERVICE_NAME``my-symfony-app`Service name shown in your backend`OTEL_TRACES_EXPORTER``otlp`Exporter type (`otlp`, `zipkin`, `console`, `none`)`OTEL_EXPORTER_OTLP_ENDPOINT``http://localhost:4318`Your collector/backend endpoint`OTEL_EXPORTER_OTLP_PROTOCOL``http/protobuf`Protocol (`http/protobuf`, `http/json`, `grpc`)See the [OpenTelemetry SDK docs](https://opentelemetry.io/docs/languages/php/exporters/) for all available options.

Usage
-----

[](#usage)

### Automatic HTTP Tracing

[](#automatic-http-tracing)

Once installed, every HTTP request automatically gets a SERVER span with:

- Route template naming (`GET /api/users/{id}` instead of `GET /api/users/42`)
- Request/response attributes following [OTel semantic conventions](https://opentelemetry.io/docs/specs/semconv/http/)
- Query string attribute (`url.query`)
- Body size attributes (`http.request.body.size`, `http.response.body.size`)
- Client IP recording (`client.address`)
- Bundle version tracking (`service.version`)
- Response propagation (Server-Timing headers for browser-side tracing)
- Exception recording with stack traces
- Sub-request support (INTERNAL spans)
- W3C Trace Context propagation from incoming headers

### Automatic HttpClient Tracing

[](#automatic-httpclient-tracing)

When `symfony/http-client` is installed, every outgoing HTTP request automatically gets a CLIENT span with:

- Span name: `GET api.example.com`
- Request attributes (`http.request.method`, `url.full`, `server.address`, `server.port`)
- Response status code and error detection
- W3C Trace Context propagation into outgoing request headers (so downstream services are linked in the same trace)

Works with all Symfony HttpClient instances, including scoped clients.

### Automatic Messenger Tracing

[](#automatic-messenger-tracing)

When `symfony/messenger` is installed, the bundle automatically:

- **On dispatch:** injects W3C Trace Context into the message envelope so it survives serialization across transports
- **On consume:** creates a CONSUMER span with messaging attributes (`messaging.system`, `messaging.operation.type`, `messaging.message.class`)

#### Root Spans for Background Jobs

[](#root-spans-for-background-jobs)

By default, consumed messages are linked as children of the dispatching trace. If your backend treats root spans as independent tasks/jobs (e.g. Traceway Tasks, Sentry Crons), enable root spans:

```
open_telemetry:
    messenger_root_spans: true
```

Each consumed message will then start its own trace, appearing as a standalone task in your backend.

### Automatic Doctrine DBAL Tracing

[](#automatic-doctrine-dbal-tracing)

When `doctrine/dbal` (^4.0) is installed, every database query automatically gets a CLIENT span with:

- Span name: the SQL template (e.g. `SELECT * FROM users WHERE id = ?`), truncated at 120 chars
- Database attributes following [OTel database semantic conventions](https://opentelemetry.io/docs/specs/semconv/database/) (`db.system.name`, `db.operation.name`, `db.namespace`, `db.query.text`)
- Server attributes (`server.address`, `server.port`)
- Exception recording on query failure
- Transaction spans (`BEGIN`, `COMMIT`, `ROLLBACK`)

SQL is recorded by default as `db.query.text`. Prepared statements use `?` placeholders (e.g. `SELECT * FROM users WHERE id = ?`), so parameter values are not recorded. However, `query()`/`exec()` calls record raw SQL which may contain literal values. Disable SQL recording if raw SQL may contain sensitive data (span name falls back to `{OPERATION} {dbName}`):

```
open_telemetry:
    doctrine_record_statements: false
```

The bundle auto-detects the database system (MySQL, PostgreSQL, SQLite, SQL Server, Oracle) from the Doctrine DBAL driver.

### Manual Instrumentation with `Tracing`

[](#manual-instrumentation-with-tracing)

Inject `TracingInterface` into any service for one-liner span creation:

```
use Traceway\OpenTelemetryBundle\TracingInterface;
use OpenTelemetry\API\Trace\SpanKind;

class OrderService
{
    public function __construct(
        private readonly TracingInterface $tracing,
    ) {}

    public function processOrder(int $orderId): void
    {
        // Simple span
        $this->tracing->trace('order.validate', function () use ($orderId) {
            // validation logic...
        });

        // Span with attributes and kind
        $result = $this->tracing->trace('db.query', fn () => $this->db->query('SELECT ...'), [
            'db.system.name' => 'mysql',
            'db.query.text' => 'SELECT * FROM orders WHERE id = ?',
        ], SpanKind::KIND_CLIENT);

        // Nested spans — parent-child linking is automatic
        $this->tracing->trace('order.fulfill', function () {
            $this->tracing->trace('inventory.reserve', fn () => $this->reserve());
            $this->tracing->trace('payment.charge', fn () => $this->charge());
            $this->tracing->trace('email.send', fn () => $this->notify());
        });
    }
}
```

The `trace()` method:

- Creates and activates a span
- Runs the callback
- Sets `OK` status on success, or records the exception and sets `ERROR` on failure
- Ends the span and detaches the scope
- Returns the callback's return value

Mocking in Tests
----------------

[](#mocking-in-tests)

The bundle provides `TracingInterface` so you can easily mock tracing in your application tests:

```
$tracing = $this->createStub(TracingInterface::class);
$tracing->method('trace')->willReturnCallback(fn ($name, $cb) => $cb());
```

Contributing
------------

[](#contributing)

```
git clone https://github.com/tracewayapp/opentelemetry-symfony-bundle.git
cd opentelemetry-symfony-bundle
composer install
vendor/bin/phpunit
vendor/bin/phpstan analyse
```

License
-------

[](#license)

This bundle is released under the [MIT License](LICENSE).

###  Health Score

40

—

FairBetter than 87% of packages

Maintenance96

Actively maintained with recent releases

Popularity5

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity45

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

4

Last Release

52d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/8160951a0cd8e658add59bc36c59497d410ac3a82ab800aa6cd40b54f188f287?d=identicon)[graphene](/maintainers/graphene)

---

Top Contributors

[![jstojiljkovic](https://avatars.githubusercontent.com/u/22980168?v=4)](https://github.com/jstojiljkovic "jstojiljkovic (7 commits)")

---

Tags

instrumentationobservabilityopentelemetryotelphpsymfonysymfony-bundletracingsymfonydoctrinetracingopentelemetryotelobservabilityinstrumentation

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/traceway-opentelemetry-symfony/health.svg)

```
[![Health](https://phpackages.com/badges/traceway-opentelemetry-symfony/health.svg)](https://phpackages.com/packages/traceway-opentelemetry-symfony)
```

###  Alternatives

[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.3M152](/packages/sulu-sulu)[open-telemetry/opentelemetry-auto-symfony

OpenTelemetry auto-instrumentation for Symfony

551.2M1](/packages/open-telemetry-opentelemetry-auto-symfony)[a2lix/translation-form-bundle

Translate your doctrine objects easily with some helpers

3376.9M38](/packages/a2lix-translation-form-bundle)[friendsofopentelemetry/opentelemetry-bundle

Traces, metrics, and logs instrumentation within your Symfony application

638.6k](/packages/friendsofopentelemetry-opentelemetry-bundle)[prezent/doctrine-translatable-bundle

Integrate the doctrine-translatable extension in Symfony

14698.4k5](/packages/prezent-doctrine-translatable-bundle)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
