OpenTelemetry Sampling [PHP]
What is sampling?
Sampling is a process that restricts the amount of traces that are generated by a system. In high-volume applications, collecting 100% of traces can be expensive and unnecessary. Sampling allows you to collect a representative subset of traces while reducing costs and performance overhead.
PHP sampling
OpenTelemetry PHP SDK provides head-based sampling capabilities where the sampling decision is made at the beginning of a trace. By default, the tracer provider uses a ParentBased sampler with the AlwaysOnSampler. A sampler can be set on the tracer provider when creating it.
Built-in samplers
AlwaysOnSampler
Samples every trace. Useful for development environments but be careful in production with significant traffic:
use OpenTelemetry\SDK\Trace\TracerProvider;
use OpenTelemetry\SDK\Trace\Sampler\AlwaysOnSampler;
$tracerProvider = new TracerProvider(
sampler: new AlwaysOnSampler()
);
AlwaysOffSampler
Samples no traces. Useful for completely disabling tracing:
use OpenTelemetry\SDK\Trace\Sampler\AlwaysOffSampler;
$tracerProvider = new TracerProvider(
sampler: new AlwaysOffSampler()
);
TraceIdRatioBased
Samples a fraction of spans based on the trace ID. The fraction should be between 0.0 and 1.0:
use OpenTelemetry\SDK\Trace\Sampler\TraceIdRatioBased;
// Sample 10% of traces
$tracerProvider = new TracerProvider(
sampler: new TraceIdRatioBased(0.1)
);
// Sample 50% of traces
$tracerProvider = new TracerProvider(
sampler: new TraceIdRatioBased(0.5)
);
ParentBased
A sampler decorator that behaves differently based on the parent of the span. If the span has no parent, the decorated sampler is used to make the sampling decision:
use OpenTelemetry\SDK\Trace\Sampler\ParentBased;
use OpenTelemetry\SDK\Trace\Sampler\TraceIdRatioBased;
use OpenTelemetry\SDK\Trace\Sampler\AlwaysOnSampler;
// ParentBased with TraceIdRatioBased root sampler
$tracerProvider = new TracerProvider(
sampler: new ParentBased(new TraceIdRatioBased(0.1))
);
// ParentBased with AlwaysOnSampler root sampler (default behavior)
$tracerProvider = new TracerProvider(
sampler: new ParentBased(new AlwaysOnSampler())
);
Configuration in PHP
Environment variables
You can configure sampling using environment variables:
# TraceIdRatio sampler with 50% sampling
export OTEL_TRACES_SAMPLER="traceidratio"
export OTEL_TRACES_SAMPLER_ARG="0.5"
# ParentBased with TraceIdRatio
export OTEL_TRACES_SAMPLER="parentbased_traceidratio"
export OTEL_TRACES_SAMPLER_ARG="0.1"
# Always sample
export OTEL_TRACES_SAMPLER="always_on"
# Never sample
export OTEL_TRACES_SAMPLER="always_off"
Programmatic configuration
<?php
use OpenTelemetry\SDK\Trace\TracerProvider;
use OpenTelemetry\SDK\Trace\SpanProcessor\BatchSpanProcessor;
use OpenTelemetry\SDK\Trace\Sampler\AlwaysOnSampler;
use OpenTelemetry\SDK\Trace\Sampler\ParentBased;
use OpenTelemetry\SDK\Trace\Sampler\TraceIdRatioBased;
use OpenTelemetry\SDK\Resource\ResourceInfo;
use OpenTelemetry\SDK\Common\Attribute\Attributes;
use OpenTelemetry\Contrib\Otlp\SpanExporter;
use OpenTelemetry\Contrib\Otlp\OtlpHttpTransportFactory;
use OpenTelemetry\SemConv\ResourceAttributes;
function setupTracing(): TracerProvider
{
// Create OTLP exporter
$transport = (new OtlpHttpTransportFactory())->create(
'https://api.uptrace.dev:4318/v1/traces',
'application/json',
['uptrace-dsn' => $_ENV['UPTRACE_DSN']]
);
$exporter = new SpanExporter($transport);
// Create resource
$resource = ResourceInfo::create(Attributes::create([
ResourceAttributes::SERVICE_NAME => 'my-service',
ResourceAttributes::SERVICE_VERSION => '1.0.0',
]));
// Configure sampler based on environment
$env = $_ENV['APP_ENV'] ?? 'development';
$sampler = match ($env) {
'development' => new AlwaysOnSampler(),
'production' => new ParentBased(new TraceIdRatioBased(0.1)), // 10% sampling
default => new ParentBased(new TraceIdRatioBased(0.25)), // 25% sampling
};
// Create tracer provider with correct parameter order
return new TracerProvider(
spanProcessors: [new BatchSpanProcessor($exporter)],
sampler: $sampler,
resource: $resource
);
}