open-telemetry/sdk
OpenTelemetry PHP SDK implementing the OpenTelemetry API to collect traces and metrics. Use with compatible exporters; supports manual setup, SDK Builder, and optional auto-loading/registration via OTEL_* environment configuration.
The OpenTelemetry PHP SDK aligns well with Laravel’s observability-first architecture, particularly for:
Span instrumentation) for microservices, queues, and HTTP clients.Meter) for performance monitoring (e.g., request latency, DB query counts).Logger) for structured logging with correlation IDs.Log facade).Key Fit Areas:
Globals::tracerProvider()/Globals::meterProvider(), enabling dependency injection.Laravel\Queue\Jobs).Illuminate\Http\Request/Response via TextMapPropagator.Span context for SQL queries).| Component | Feasibility | Notes |
|---|---|---|
| Laravel Core | High | Minimal boilerplate; autoloading via OTEL_PHP_AUTOLOAD_ENABLED. |
| Queues (Redis/Database) | High | Span context propagates across workers. |
| HTTP (API Routes) | High | Middleware for Span injection (e.g., OpenTelemetry\Context\Propagation). |
| Database (Eloquent) | Medium | Requires custom instrumentation (e.g., DB::listen). |
| Logging (Monolog) | High | PSR-3 logger integration via Logger API. |
| CLI Artisan Commands | High | Metrics/traces for background jobs. |
Performance Overhead:
AlwaysRecordSampler sparingly; configure batching (e.g., OtlpHttpExporter with export_interval).queue:work and schedule:run under load.Compatibility Gaps:
Event system lacks native OpenTelemetry support.Meter for custom metrics (e.g., event.dispatching).weaken for closures).Configuration Complexity:
OTEL_*) and OTEL_CONFIG_FILE may conflict with Laravel’s .env.config() binding for SDK config (e.g., config('opentelemetry.exporter')).Exporter Dependencies:
otlp/otlp-http) require additional setup (e.g., Jaeger/Zipkin backend).ConsoleExporter for debugging, then migrate to OTLP.Observability Goals:
TraceIdRatioBasedSampler) to reduce volume?Backend Integration:
auth()->user()->id) in spans?Laravel-Specific Needs:
Operational Tradeoffs:
OTEL_PHP_AUTOLOAD_ENABLED=false)?| Laravel Component | OpenTelemetry SDK Feature | Integration Method |
|---|---|---|
| HTTP Requests | Span, TextMapPropagator |
Middleware to inject/extract context from Request/Response. |
| Queues | Span propagation | Use OpenTelemetry\Context\Propagation::getCurrentContext() in HandleJobs. |
| Logging | Logger |
Replace Log::channel() with OpenTelemetry\SDK\Logs\Logger. |
| Database | Custom instrumentation | Wrap DB::listen() to create spans for queries. |
| CLI/Artisan | Meter |
Instrument Artisan::command() with metrics (e.g., meter->createCounter()). |
| Events | Meter (no native support) |
Use Event::listen() to emit custom metrics (e.g., event_dispatched_total). |
Phase 1: Instrumentation (Low Risk)
composer require open-telemetry/sdk open-telemetry/otlp
.env:
OTEL_PHP_AUTOLOAD_ENABLED=true
OTEL_SERVICE_NAME="laravel-app"
OTEL_EXPORTER_OTLP_ENDPOINT="http://collector:4318"
ConsoleExporter (debug mode).Phase 2: Core Integration (Medium Risk)
use OpenTelemetry\Context\Propagation;
use OpenTelemetry\API\Globals;
public function handle($request, Closure $next) {
$carrier = new ArrayCarrier();
Propagation::inject($carrier, Globals::getTextMapPropagator());
$request->headers->add($carrier);
return $next($request);
}
Illuminate\Queue\Jobs\Job to propagate context:
public function handle() {
$context = Propagation::extract(
new ArrayCarrier($this->payload['headers']),
Globals::getTextMapPropagator()
);
Propagation::setCurrentContext($context);
// ... job logic
}
Phase 3: Advanced Use Cases (High Risk)
DB::listen():
DB::listen(function ($query) {
$span = Globals::tracerProvider()->getTracer('db')->startSpan($query->sql);
// ... attach attributes
});
$meter = Globals::meterProvider()->getMeter('business');
$updates = $meter->createCounter('user_updates');
$updates->add(1, ['user_id' => auth()->id()]);
| Compatibility Check | Status | Notes |
|---|---|---|
| Laravel 10.x / PHP 8.2+ | ✅ Fully Supported | Target PHP 8.2+ for weaken and ArrayObject changes. |
| Laravel Queues (Redis/SQS) | ✅ Supported | Span context propagates via payload headers. |
| Monolog (Laravel’s default logger) | ✅ Supported | Use OpenTelemetry\SDK\Logs\Logger as a Monolog handler. |
| Symfony HTTP Client | ✅ Supported | Auto-instrumented via HttpClientDiscovery. |
| Guzzle 7.x | ✅ Supported | Requires guzzlehttp/guzzle:^7.0. |
| Legacy PHP (<8.1) | ⚠️ Partial | May need polyfills for weaken/match expressions. |
Logger for structured logs with correlation IDs (requires backend support).Avoid:
ConsoleExporter + OtlpExporter) during testing.How can I help you explore Laravel packages today?