PHP SDK
Full observability for PHP services — HTTP, databases, errors, and exceptions captured automatically via OpenTelemetry
Installation
Requires PHP 8.1+.
Minimum Setup
Two fields are required: apiKey and serviceName. Everything else has defaults.
Built on OpenTelemetry
The PHP SDK uses open-telemetry/sdk under the hood to export telemetry to the Obtrace ingest endpoint. The OTel tracer is used for span creation and trace context propagation. Laravel middleware and Symfony event subscribers use the OTel tracer for request instrumentation.
What's Captured Automatically
After creating an ObtraceClient, the SDK configures OpenTelemetry and registers error handlers, HTTP instrumentation, and a shutdown function. You don't need to write any extra code for this:
| What | How | Needs code? |
|---|---|---|
| PHP errors | set_error_handler intercepts errors with level mapping: E_NOTICE -> info, E_WARNING -> warn, E_ERROR -> error | No |
| Uncaught exceptions | set_exception_handler catches unhandled exceptions and logs them at fatal level | No |
| Outbound HTTP (cURL) | curl_exec calls are instrumented via OTel with spans containing method, URL, status, and duration, plus traceparent header injection | No |
| Outbound HTTP (Guzzle) | Guzzle middleware is auto-registered via OTel when Guzzle is detected, creating spans and injecting trace headers | No |
| PDO database queries | PDO operations are instrumented with spans when the OTel PDO instrumentation is installed | No |
| Laravel auto-detection | Laravel requests, database queries, and queue jobs are instrumented when using the ServiceProvider | No |
| Shutdown flush | register_shutdown_function flushes buffered telemetry when the PHP process exits | No |
Opting Out of Auto HTTP Instrumentation
Opting Out of Auto Error/Exception Capture
Optional: Custom Telemetry
The automatic error, exception, and HTTP capture covers basic observability. For business-specific events, use the SDK methods directly.
Logging
Use $client->log() for structured events. Logs are best for state transitions, errors, and audit trails.
Levels: trace, debug, info, warn, error, fatal.
Metrics
Use $client->metric() for numerical measurements you want to track over time.
The unit parameter follows OTLP conventions: "ms" for milliseconds, "By" for bytes, "1" for dimensionless values.
Tracing / Spans
Use $client->span() for operations with duration. Spans appear in the trace waterfall and are best for database queries, HTTP calls, and queue processing.
Framework Integration
Laravel (ServiceProvider)
The SDK includes a Laravel ServiceProvider for zero-config setup. Add your credentials to config/services.php:
Register the ServiceProvider in bootstrap/providers.php (Laravel 11+):
The ServiceProvider registers ObtraceClient as a singleton, adds request instrumentation middleware to the global middleware stack, and wires up shutdown flushing. The middleware emits a span and metric for every HTTP request.
Use the client anywhere via DI:
Laravel (Manual)
If you prefer manual setup over the ServiceProvider:
Register in bootstrap/app.php or app/Http/Kernel.php:
Symfony
Register as a service and create an event subscriber:
CLI / Queue Workers
For long-running processes, flush periodically:
Configuration Reference
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
apiKey | string | Yes | Obtrace API key | |
serviceName | string | Yes | Stable name for this service | |
tenantId | ?string | No | from key | Tenant identifier |
projectId | ?string | No | from key | Project identifier |
appId | ?string | No | Application identifier within the project | |
env | string | No | "production" | Deployment environment |
serviceVersion | ?string | No | Version string for this deployment | |
autoCaptureErrors | bool | No | true | Register error/exception handlers automatically |
autoInstrumentHttp | bool | No | true | Instrument cURL and Guzzle outbound HTTP calls |
validateSemanticMetrics | bool | No | false | Warn on non-standard metric names |
debug | bool | No | false | Enable verbose logging to stderr |
maxQueueSize | int | No | 2048 | Maximum buffered items before dropping |
flushIntervalMs | int | No | 5000 | Auto-flush interval in milliseconds |
Validation Checklist
After deploying, verify:
serviceName,env, andserviceVersionare stable across deployments and match what you see in the Obtrace UI- At least one real request path emits both a log and a span
- No
401or403errors appear in stderr whendebugistrue - The shutdown function is firing (check that telemetry arrives even without explicit
flush()calls in short-lived scripts) - Outbound cURL/Guzzle calls show auto-generated spans
- Long-running workers call
flush()periodically rather than relying solely on the shutdown hook - Metrics use OTLP-standard units (
ms,By,1) not custom strings