Symfony bundle for OpenTelemetry instrumentation. Provides automatic tracing for HTTP requests, outgoing HTTP calls, console commands, Doctrine queries, and Symfony Messenger messages, plus log-trace correlation via Monolog.
composer require cyberclick/otel-bundleRegister the bundle in config/bundles.php:
Cyberclick\OtelBundle\CyberclickOtelBundle::class => ['all' => true],Set the required environment variables:
OTEL_SERVICE_NAME=myapp
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318Optional:
OTEL_DB_INSTANCE=mydb # Database name shown in DB spans (defaults to empty)- HTTP tracing: Creates spans for every incoming HTTP request with
http.method,http.route,http.host,http.status_code - Console tracing: Creates spans for console commands with exit codes
- Log correlation: Injects
trace_idandspan_idinto Monolog log records via a processor
The following features require explicit configuration in your app's services:
Traces outgoing HTTP calls made via Symfony HttpClient. You choose which clients to instrument by decorating them in your services config:
# Trace ALL outgoing HTTP calls
Cyberclick\OtelBundle\HttpClient\TracingHttpClient:
decorates: http_client
arguments:
$client: '@.inner'
$tracer: '@cyberclick_otel.tracer'# Trace only a specific scoped client
Cyberclick\OtelBundle\HttpClient\TracingHttpClient:
decorates: http_client.catastro
arguments:
$client: '@.inner'
$tracer: '@cyberclick_otel.tracer'Spans are created with http.method, http.url, http.host, http.status_code.
Creates spans for every SQL query with db.system, db.name, db.statement, db.operation.
If you use Doctrine's standard configuration, add the middleware to your DBAL connection:
doctrine:
dbal:
connections:
default:
middlewares:
- 'Cyberclick\OtelBundle\Doctrine\TracingMiddleware'If you use a custom EntityManagerFactory, inject the middleware and pass it to setMiddlewares():
use Cyberclick\OtelBundle\Doctrine\TracingMiddleware;
use Doctrine\DBAL\Driver\Middleware;
public static function create(array $parameters, ?Middleware $tracingMiddleware = null): EntityManager
{
$dbalConfig = new \Doctrine\DBAL\Configuration();
if ($tracingMiddleware !== null) {
$dbalConfig->setMiddlewares([$tracingMiddleware]);
}
// ...
}# services.yaml
App\EntityManagerFactory:
arguments:
$tracingMiddleware: '@Cyberclick\OtelBundle\Doctrine\TracingMiddleware'Traces Symfony Messenger message handling:
framework:
messenger:
buses:
command.bus:
middleware:
- cyberclick_otel.messenger.tracing_middlewareMessageTracerInterface provides manual span management for RabbitMQ consumers with automatic forceFlush() for long-running processes:
use Cyberclick\OtelBundle\Tracing\MessageTracerInterface;
final class MyConsumer
{
public function __construct(private MessageTracerInterface $tracer) {}
public function consume(string $queueName, string $body): void
{
$this->tracer->start($queueName, $body);
$this->tracer->recordSpan('my_event', $body, 'domain_event', 'consume');
try {
// process message...
$this->tracer->stopSpan('my_event');
$this->tracer->end('OK');
} catch (\Throwable $e) {
$this->tracer->registerError($e);
$this->tracer->stopSpan('my_event');
$this->tracer->end('KO');
}
}
}To add application-specific attributes to HTTP and message spans (e.g., tenant ID, user ID), implement SpanAttributeExtractorInterface:
use Cyberclick\OtelBundle\SpanAttributeExtractorInterface;
use Symfony\Component\HttpFoundation\Request;
final class MyAppSpanAttributeExtractor implements SpanAttributeExtractorInterface
{
/**
* Attributes added to the root HTTP span (called during kernel.controller).
*/
public function fromRequest(Request $request): array
{
return [
'enduser.id' => $request->attributes->get('authenticated_uid'),
'tenant.id' => $request->get('tenantId'),
];
}
/**
* Attributes added to RabbitMQ consumer spans.
*/
public function fromMessageBody(?string $body): array
{
$data = json_decode($body ?? '{}');
return [
'tenant.id' => $data?->data?->attributes?->tenant_id ?? null,
];
}
}Register it in your services config to override the default (no-op) extractor:
Actel\Shared\Infrastructure\OpenTelemetry\MyAppSpanAttributeExtractor: ~
Cyberclick\OtelBundle\SpanAttributeExtractorInterface:
alias: Actel\Shared\Infrastructure\OpenTelemetry\MyAppSpanAttributeExtractor| Service | Description |
|---|---|
cyberclick_otel.tracer_provider |
TracerProvider instance |
cyberclick_otel.tracer |
TracerInterface instance |
cyberclick_otel.messenger.tracing_middleware |
Messenger middleware |
Cyberclick\OtelBundle\Tracing\MessageTracerInterface |
Message tracer for consumers |
Cyberclick\OtelBundle\Doctrine\TracingMiddleware |
Doctrine DBAL middleware |
Cyberclick\OtelBundle\HttpClient\TracingHttpClient |
HTTP client decorator (manual registration) |
- PHP >= 8.2
- Symfony 6.4 or 7.x
- OpenTelemetry PHP SDK