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.
composer require open-telemetry/sdk
.env:
OTEL_PHP_AUTOLOAD_ENABLED=true
OTEL_SERVICE_NAME="your-app-name"
OTEL_EXPORTER=otlp
OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4317"
require 'vendor/autoload.php';
// Tracing
$tracer = \OpenTelemetry\API\Globals::tracerProvider()->getTracer('your-service');
$span = $tracer->spanBuilder('example-span')->startSpan();
$span->end();
// Metrics
$meter = \OpenTelemetry\API\Globals::meterProvider()->getMeter('your-service');
$counter = $meter->createCounter('example-counter');
$counter->add(1, ['key' => 'value']);
\OpenTelemetry\API\Globals::tracerProvider()\OpenTelemetry\API\Globals::meterProvider()\OpenTelemetry\API\Globals::loggerProvider()\OpenTelemetry\SDK\Telemetry\Sdk// Create a tracer
$tracer = \OpenTelemetry\API\Globals::tracerProvider()->getTracer('your-service');
// Start a span
$span = $tracer->spanBuilder('operation-name')
->setAttribute('key', 'value')
->startSpan();
// Add events
$span->addEvent('event-name', ['details' => 'value']);
// End the span
$span->end();
// Create a meter
$meter = \OpenTelemetry\API\Globals::meterProvider()->getMeter('your-service');
// Counter
$counter = $meter->createCounter('requests');
$counter->add(1, ['method' => 'GET']);
// Histogram
$histogram = $meter->createHistogram('response_time');
$histogram->record(150, ['endpoint' => '/api']);
// Gauge
$gauge = $meter->createGauge('active_connections');
$gauge->record(42, ['type' => 'database']);
$logger = \OpenTelemetry\API\Globals::loggerProvider()->getLogger('your-service');
$logger->emit([
'body' => 'Log message',
'severityText' => 'INFO',
'severityNumber' => \OpenTelemetry\SemConv\Logs\SeverityNumber::INFO,
'attributes' => ['key' => 'value']
]);
use OpenTelemetry\Instrumentation\Guzzle\GuzzleInstrumentation;
$client = new \GuzzleHttp\Client();
$instrumentation = new GuzzleInstrumentation();
$instrumentation->instrument($client);
// app/Providers/AppServiceProvider.php
public function boot()
{
$this->app->makeWith(\OpenTelemetry\Instrumentation\Laravel\OpenTelemetryServiceProvider::class);
}
use OpenTelemetry\SDK\Trace\SpanProcessor\SpanProcessorInterface;
class CustomSpanProcessor implements SpanProcessorInterface
{
public function onStart(\OpenTelemetry\API\Trace\Span $span): void
{
// Custom logic on span start
}
public function onEnd(\OpenTelemetry\API\Trace\Span $span): void
{
// Custom logic on span end
}
}
// Register with SDK builder
$sdk = (new \OpenTelemetry\SDK\Telemetry\Sdk())
->setSpanProcessor(new CustomSpanProcessor());
# Tracing
OTEL_TRACES_SAMPLER=always_on
OTEL_TRACES_EXPORTER=otlp
OTEL_TRACES_EXPORTER_OTLP_ENDPOINT=http://collector:4318
# Metrics
OTEL_METRICS_EXPORTER=otlp
OTEL_METRICS_EXPORTER_OTLP_ENDPOINT=http://collector:4317
# Logging
OTEL_LOGS_EXPORTER=otlp
OTEL_LOGS_EXPORTER_OTLP_ENDPOINT=http://collector:4317
$sdk = (new \OpenTelemetry\SDK\Telemetry\Sdk())
->setTracerProvider(
(new \OpenTelemetry\SDK\Trace\TracerProvider())
->addSpanProcessor(new \OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor(
new \OpenTelemetry\SDK\Trace\Export\BatchSpanProcessor(
new \OpenTelemetry\SDK\Trace\Export\ConsoleSpanExporter()
)
))
)
->setMeterProvider(
(new \OpenTelemetry\SDK\Metrics\MeterProvider())
->registerObserver(new \OpenTelemetry\SDK\Metrics\Export\PeriodicExportingMetricObserver(
new \OpenTelemetry\SDK\Metrics\Export\ConsoleMetricExporter(),
5000 // 5 seconds
))
);
\OpenTelemetry\API\Globals::setTracerProvider($sdk->getTracerProvider());
\OpenTelemetry\API\Globals::setMeterProvider($sdk->getMeterProvider());
// Extract context from incoming request
$context = \OpenTelemetry\API\Trace\propagation\TraceContextPropagator::getInstance()
->extract(
\OpenTelemetry\API\Common\Instrumentation\GlobalInstrumentation::getContext(),
$_SERVER
);
// Inject context into outgoing request
$carrier = [];
\OpenTelemetry\API\Trace\propagation\TraceContextPropagator::getInstance()
->inject($context, $carrier);
// Enable auto-instrumentation for HTTP clients
\OpenTelemetry\Instrumentation\AutoInstrumentation::registerAutoInstrumentations([
\OpenTelemetry\Instrumentation\Guzzle\GuzzleInstrumentation::class,
\OpenTelemetry\Instrumentation\Symfony\HttpClient\SymfonyHttpClientInstrumentation::class,
]);
$sdk = (new \OpenTelemetry\SDK\Telemetry\Sdk())
->setResource(
\OpenTelemetry\SDK\Resource\ResourceInfo::createDefault()
->merge(
\OpenTelemetry\SDK\Resource\ResourceDetector::detect()
)
);
OTEL_PHP_AUTOLOAD_ENABLED and required variables.OTEL_PHP_AUTOLOAD_DEBUG=true to see autoloading attempts.\OpenTelemetry\API\Trace\propagation\TraceContextPropagator::getInstance();
OTEL_PROPAGATION_FORMAT=tracecontext for W3C Trace Context.OTEL_TRACES_SAMPLER=traceidratio
OTEL_TRACES_SAMPLER_ARG=0.1 # Sample 10% of traces
AlwaysRecordSampler for development:
$sampler = new \OpenTelemetry\SDK\Trace\Sampling\AlwaysRecordSampler();
$meterProvider = new \OpenTelemetry\SDK\Metrics\MeterProvider();
$meterProvider->registerObserver(
new \OpenTelemetry\SDK\Metrics\Export\PeriodicExportingMetricObserver(
new \OpenTelemetry\SDK\
How can I help you explore Laravel packages today?