Installation:
composer require cyberclick/otel-bundle
Register the bundle in config/bundles.php:
Cyberclick\OtelBundle\CyberclickOtelBundle::class => ['all' => true],
Configure Environment Variables (.env):
OTEL_SERVICE_NAME=myapp
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318
First Use Case:
http.method, http.route, and http.status_code attributes.Automatic Instrumentation:
trace_id and span_id in Monolog.Explicit Instrumentation:
HttpClient to trace outgoing requests:
# config/services.yaml
Cyberclick\OtelBundle\HttpClient\TracingHttpClient:
decorates: http_client
arguments:
$client: '@.inner'
$tracer: '@cyberclick_otel.tracer'
doctrine:
dbal:
connections:
default:
middlewares:
- 'Cyberclick\OtelBundle\Doctrine\TracingMiddleware'
framework:
messenger:
buses:
command.bus:
middleware:
- cyberclick_otel.messenger.tracing_middleware
Manual Span Management:
MessageTracerInterface for RabbitMQ consumers:
public function consume(string $queueName, string $body): void
{
$this->tracer->start($queueName, $body);
try {
// Process message
$this->tracer->end('OK');
} catch (\Throwable $e) {
$this->tracer->registerError($e);
$this->tracer->end('KO');
}
}
Custom Attributes: Implement SpanAttributeExtractorInterface to add application-specific attributes (e.g., tenant ID, user ID) to spans:
use Cyberclick\OtelBundle\SpanAttributeExtractorInterface;
use Symfony\Component\HttpFoundation\Request;
final class MyAppSpanAttributeExtractor implements SpanAttributeExtractorInterface
{
public function fromRequest(Request $request): array
{
return ['tenant.id' => $request->get('tenantId')];
}
public function fromMessageBody(?string $body): array
{
return ['tenant.id' => json_decode($body)?->tenant_id];
}
}
Register it in services.yaml:
Actel\Shared\Infrastructure\OpenTelemetry\MyAppSpanAttributeExtractor: ~
Cyberclick\OtelBundle\SpanAttributeExtractorInterface:
alias: Actel\Shared\Infrastructure\OpenTelemetry\MyAppSpanAttributeExtractor
Service IDs: Leverage provided services like cyberclick_otel.tracer or cyberclick_otel.messenger.tracing_middleware directly in your code.
Namespace Changes:
cyberclick-tech/otel-bundle, update all use statements and service references from CyberclickTech\OtelBundle to Cyberclick\OtelBundle.composer.json to use cyberclick/otel-bundle.Symfony Version Compatibility:
Doctrine Middleware:
EntityManagerFactory, manually inject and set the TracingMiddleware in the DBAL\Configuration:
$dbalConfig->setMiddlewares([$tracingMiddleware]);
Log Correlation:
trace_id and span_id processors. The bundle automatically injects these, but verify your Monolog setup includes the Cyberclick\OtelBundle\Monolog\TraceIdProcessor.Missing Spans:
OTEL_EXPORTER_OTLP_ENDPOINT is correctly set and the OpenTelemetry Collector is running.var/log/dev.log) or the Collector's logs.Doctrine Tracing:
TracingMiddleware is properly added to your DBAL connection or EntityManagerFactory.HTTP Client Tracing:
TracingHttpClient decorator is correctly configured in services.yaml and the target client (e.g., http_client or a scoped client like http_client.catastro) matches the decorator's name.Environment-Specific Config:
OTEL_EXPORTER_OTLP_ENDPOINT values for development, staging, and production. Example:
# .env.dev
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
# .env.prod
OTEL_EXPORTER_OTLP_ENDPOINT=https://otel-collector.prod.example.com:4318
Span Naming Conventions:
SpanAttributeExtractorInterface:
public function fromRequest(Request $request): array
{
return [
'http.route' => 'custom.route.name',
// other attributes...
];
}
Performance Impact:
OTEL_TRACES_SAMPLER environment variable).Testing:
cyberclick_otel.tracer service in unit tests to avoid real tracing calls:
$this->container->set('cyberclick_otel.tracer', $this->createMock(TracerInterface::class));
Extension Points:
SpanAttributeExtractorInterface or creating custom middleware for unsupported components (e.g., Symfony UX, API Platform).How can I help you explore Laravel packages today?