Install the package
Require the package via Composer:Laravel’s package auto-discovery registers
composer require keepsuit/laravel-opentelemetry
LaravelOpenTelemetryServiceProvider automatically. You do not need to add anything to config/app.php.Publish the configuration file
Publish the This creates
config/opentelemetry.php file to your application:php artisan vendor:publish --provider="Keepsuit\LaravelOpenTelemetry\LaravelOpenTelemetryServiceProvider" --tag="opentelemetry-config"
config/opentelemetry.php with all available options and their defaults.Set your service name
Add If not set, the value of
OTEL_SERVICE_NAME to your .env file. This name appears in your observability backend to identify the service that produced the telemetry..env
OTEL_SERVICE_NAME=my-laravel-app
APP_NAME is used (slugified).Configure the exporter endpoint
Point the OTLP exporter at your collector or backend:The default endpoint is
.env
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
http://localhost:4318, which is the standard OTLP/HTTP port for an OpenTelemetry Collector running locally. Replace this with your backend’s ingestion URL (Jaeger, Grafana Tempo, Honeycomb, Datadog, etc.).For local development without a collector, set
OTEL_TRACES_EXPORTER=console to print spans to stdout instead.Optional packages
Install these packages to unlock additional exporters and propagators:composer require open-telemetry/extension-propagator-b3
.env:
.env
OTEL_PROPAGATORS=b3
.env
OTEL_EXPORTER_OTLP_PROTOCOL=grpc
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
Laravel Scout instrumentation requires the
ext-opentelemetry PHP extension. Install it via PECL: pecl install opentelemetry. All other instrumentations work without the extension.Published configuration file
View config/opentelemetry.php
View config/opentelemetry.php
config/opentelemetry.php
<?php
use Illuminate\Support\Str;
use Keepsuit\LaravelOpenTelemetry\Instrumentation;
use Keepsuit\LaravelOpenTelemetry\Support\ResourceAttributesParser;
use Keepsuit\LaravelOpenTelemetry\TailSampling;
use Keepsuit\LaravelOpenTelemetry\WorkerMode;
use OpenTelemetry\SDK\Common\Configuration\Variables;
return [
/**
* When set to true, Opentelemetry SDK will be disabled
*/
'disabled' => env(Variables::OTEL_SDK_DISABLED, false),
/**
* Service name
*/
'service_name' => env(Variables::OTEL_SERVICE_NAME, Str::slug((string) env('APP_NAME', 'laravel-app'))),
/**
* Service instance id
* Should be unique for each instance of your service.
* If not set, a random id will be generated on each request.
*/
'service_instance_id' => env('OTEL_SERVICE_INSTANCE_ID'),
/**
* Additional resource attributes
* Key-value pairs of resource attributes to add to all telemetry data.
* By default, reads and parses OTEL_RESOURCE_ATTRIBUTES environment variable
* (which should be in the format 'key1=value1,key2=value2').
*/
'resource_attributes' => ResourceAttributesParser::parse((string) env(Variables::OTEL_RESOURCE_ATTRIBUTES, '')),
/**
* Include authenticated user context on traces and logs.
*/
'user_context' => env('OTEL_USER_CONTEXT', true),
/**
* Comma separated list of propagators to use.
* Supports any otel propagator, for example: "tracecontext", "baggage", "b3", "b3multi", "none"
*/
'propagators' => env(Variables::OTEL_PROPAGATORS, 'tracecontext'),
/**
* OpenTelemetry Meter configuration
*/
'metrics' => [
/**
* Metrics exporter
* Supported drivers: "otlp", "console", "memory", "null"
*/
'exporter' => env(Variables::OTEL_METRICS_EXPORTER, 'otlp'),
],
/**
* OpenTelemetry Traces configuration
*/
'traces' => [
/**
* Traces exporter
* Supported drivers: "otlp", "zipkin", "console", "memory", "null"
*/
'exporter' => env(Variables::OTEL_TRACES_EXPORTER, 'otlp'),
/**
* Traces sampler
*/
'sampler' => [
/**
* Wraps the sampler in a parent based sampler
*/
'parent' => env('OTEL_TRACES_SAMPLER_PARENT', true),
/**
* Sampler type
* Supported values: "always_on", "always_off", "traceidratio"
*/
'type' => env('OTEL_TRACES_SAMPLER_TYPE', 'always_on'),
'args' => [
/**
* Sampling ratio for traceidratio sampler
*/
'ratio' => env('OTEL_TRACES_SAMPLER_TRACEIDRATIO_RATIO', 0.05),
],
'tail_sampling' => [
'enabled' => env('OTEL_TRACES_TAIL_SAMPLING_ENABLED', false),
// Maximum time to wait for the end of the trace before making a sampling decision (ms)
'decision_wait' => (int) env('OTEL_TRACES_TAIL_SAMPLING_DECISION_WAIT', 5000),
'rules' => [
TailSampling\Rules\ErrorsRule::class => env('OTEL_TRACES_TAIL_SAMPLING_RULE_KEEP_ERRORS', true),
TailSampling\Rules\SlowTraceRule::class => [
'enabled' => env('OTEL_TRACES_TAIL_SAMPLING_RULE_SLOW_TRACES', true),
'threshold_ms' => (int) env('OTEL_TRACES_TAIL_SAMPLING_SLOW_TRACES_THRESHOLD_MS', 2000),
],
],
],
],
/**
* Traces span processors.
* Processors classes must implement OpenTelemetry\SDK\Trace\SpanProcessorInterface
*/
'processors' => [],
],
/**
* OpenTelemetry logs configuration
*/
'logs' => [
/**
* Logs exporter
* Supported drivers: "otlp", "console", "memory", "null"
*/
'exporter' => env(Variables::OTEL_LOGS_EXPORTER, 'otlp'),
/**
* Inject active trace id in log context
*/
'inject_trace_id' => true,
/**
* Context field name for trace id
*/
'trace_id_field' => 'trace_id',
/**
* Logs record processors.
* Processors classes must implement OpenTelemetry\SDK\Logs\LogRecordProcessorInterface
*/
'processors' => [],
],
/**
* OpenTelemetry exporters
*
* Supported drivers: "otlp", "zipkin" (only traces), "console", "memory", "null"
*/
'exporters' => [
'otlp' => [
'driver' => 'otlp',
'endpoint' => env(Variables::OTEL_EXPORTER_OTLP_ENDPOINT, 'http://localhost:4318'),
/**
* Supported protocols: "grpc", "http/protobuf", "http/json"
*/
'protocol' => env(Variables::OTEL_EXPORTER_OTLP_PROTOCOL, 'http/protobuf'),
'max_retries' => (int) env('OTEL_EXPORTER_OTLP_MAX_RETRIES', 3),
'traces_timeout' => (int) env(Variables::OTEL_EXPORTER_OTLP_TRACES_TIMEOUT, env(Variables::OTEL_EXPORTER_OTLP_TIMEOUT, 10000)),
'traces_headers' => (string) env(Variables::OTEL_EXPORTER_OTLP_TRACES_HEADERS, env(Variables::OTEL_EXPORTER_OTLP_HEADERS, '')),
'traces_protocol' => env(Variables::OTEL_EXPORTER_OTLP_TRACES_PROTOCOL),
'metrics_timeout' => (int) env(Variables::OTEL_EXPORTER_OTLP_METRICS_TIMEOUT, env(Variables::OTEL_EXPORTER_OTLP_TIMEOUT, 10000)),
'metrics_headers' => (string) env(Variables::OTEL_EXPORTER_OTLP_METRICS_HEADERS, env(Variables::OTEL_EXPORTER_OTLP_HEADERS, '')),
'metrics_protocol' => env(Variables::OTEL_EXPORTER_OTLP_METRICS_PROTOCOL),
'metrics_temporality' => env(Variables::OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE),
'logs_timeout' => (int) env(Variables::OTEL_EXPORTER_OTLP_LOGS_TIMEOUT, env(Variables::OTEL_EXPORTER_OTLP_TIMEOUT, 10000)),
'logs_headers' => (string) env(Variables::OTEL_EXPORTER_OTLP_LOGS_HEADERS, env(Variables::OTEL_EXPORTER_OTLP_HEADERS, '')),
'logs_protocol' => env(Variables::OTEL_EXPORTER_OTLP_LOGS_PROTOCOL),
],
'zipkin' => [
'driver' => 'zipkin',
'endpoint' => env(Variables::OTEL_EXPORTER_ZIPKIN_ENDPOINT, 'http://localhost:9411'),
'timeout' => env(Variables::OTEL_EXPORTER_ZIPKIN_TIMEOUT, 10000),
'max_retries' => (int) env('OTEL_EXPORTER_ZIPKIN_MAX_RETRIES', 3),
],
],
/**
* List of instrumentation used for application tracing
*/
'instrumentation' => [
Instrumentation\HttpServerInstrumentation::class => [
'enabled' => env('OTEL_INSTRUMENTATION_HTTP_SERVER', true),
'excluded_paths' => [],
'excluded_methods' => [],
'allowed_headers' => [],
'sensitive_headers' => [],
'sensitive_query_parameters' => [],
],
Instrumentation\HttpClientInstrumentation::class => [
'enabled' => env('OTEL_INSTRUMENTATION_HTTP_CLIENT', true),
'manual' => false,
'allowed_headers' => [],
'sensitive_headers' => [],
'sensitive_query_parameters' => [],
],
Instrumentation\QueryInstrumentation::class => env('OTEL_INSTRUMENTATION_QUERY', true),
Instrumentation\RedisInstrumentation::class => env('OTEL_INSTRUMENTATION_REDIS', true),
Instrumentation\QueueInstrumentation::class => env('OTEL_INSTRUMENTATION_QUEUE', true),
Instrumentation\CacheInstrumentation::class => env('OTEL_INSTRUMENTATION_CACHE', true),
Instrumentation\EventInstrumentation::class => [
'enabled' => env('OTEL_INSTRUMENTATION_EVENT', true),
'excluded' => [],
],
Instrumentation\ViewInstrumentation::class => env('OTEL_INSTRUMENTATION_VIEW', true),
Instrumentation\LivewireInstrumentation::class => env('OTEL_INSTRUMENTATION_LIVEWIRE', true),
Instrumentation\ConsoleInstrumentation::class => [
'enabled' => env('OTEL_INSTRUMENTATION_CONSOLE', true),
'commands' => [],
],
Instrumentation\ScoutInstrumentation::class => env('OTEL_INSTRUMENTATION_SCOUT', true),
],
/**
* Worker mode detection configuration
*
* Detects worker modes (e.g., Octane, Horizon, Queue) and optimizes OpenTelemetry
* behavior for long-running processes.
*/
'worker_mode' => [
/**
* Flush after each iteration (e.g. http request, queue job).
* If false, flushes are batched and executed periodically and on shutdown.
*/
'flush_after_each_iteration' => env('OTEL_WORKER_MODE_FLUSH_AFTER_EACH_ITERATION', false),
/**
* Metrics collection interval in seconds.
*/
'metrics_collect_interval' => (int) env('OTEL_WORKER_MODE_COLLECT_INTERVAL', 60),
/**
* Detectors to use for worker mode detection
*/
'detectors' => [
WorkerMode\Detectors\OctaneWorkerModeDetector::class,
WorkerMode\Detectors\QueueWorkerModeDetector::class,
],
],
];
