Skip to main content
Exporters are responsible for sending telemetry data to a backend. Each signal (traces, metrics, logs) can use a different exporter, letting you route data to different destinations independently. Exporters are defined in the exporters section of config/opentelemetry.php and referenced by key in the per-signal configuration.

OTLP exporter (default)

The OTLP exporter sends telemetry to any OpenTelemetry-compatible backend using the OpenTelemetry Protocol. It is the default exporter for all signals.

Endpoint and protocol

OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
Supported protocols:
ProtocolDescription
http/protobufHTTP with Protocol Buffers encoding (default)
http/jsonHTTP with JSON encoding
grpcgRPC

Per-signal overrides

You can override the protocol, endpoint headers, and timeout independently for each signal:
# Traces
OTEL_EXPORTER_OTLP_TRACES_PROTOCOL=grpc
OTEL_EXPORTER_OTLP_TRACES_HEADERS="Authorization=Bearer token"
OTEL_EXPORTER_OTLP_TRACES_TIMEOUT=10000

# Metrics
OTEL_EXPORTER_OTLP_METRICS_PROTOCOL=http/protobuf
OTEL_EXPORTER_OTLP_METRICS_HEADERS=""
OTEL_EXPORTER_OTLP_METRICS_TIMEOUT=10000

# Logs
OTEL_EXPORTER_OTLP_LOGS_PROTOCOL=http/protobuf
OTEL_EXPORTER_OTLP_LOGS_HEADERS=""
OTEL_EXPORTER_OTLP_LOGS_TIMEOUT=10000
When a per-signal override is not set, the global OTEL_EXPORTER_OTLP_PROTOCOL, OTEL_EXPORTER_OTLP_HEADERS, and OTEL_EXPORTER_OTLP_TIMEOUT values are used.

Full OTLP config block

'exporters' => [
    'otlp' => [
        'driver' => 'otlp',
        'endpoint' => env('OTEL_EXPORTER_OTLP_ENDPOINT', 'http://localhost:4318'),
        // Supported: "grpc", "http/protobuf", "http/json"
        'protocol' => env('OTEL_EXPORTER_OTLP_PROTOCOL', 'http/protobuf'),
        'max_retries' => (int) env('OTEL_EXPORTER_OTLP_MAX_RETRIES', 3),

        'traces_timeout' => (int) env('OTEL_EXPORTER_OTLP_TRACES_TIMEOUT', env('OTEL_EXPORTER_OTLP_TIMEOUT', 10000)),
        'traces_headers' => (string) env('OTEL_EXPORTER_OTLP_TRACES_HEADERS', env('OTEL_EXPORTER_OTLP_HEADERS', '')),
        'traces_protocol' => env('OTEL_EXPORTER_OTLP_TRACES_PROTOCOL'),

        'metrics_timeout' => (int) env('OTEL_EXPORTER_OTLP_METRICS_TIMEOUT', env('OTEL_EXPORTER_OTLP_TIMEOUT', 10000)),
        'metrics_headers' => (string) env('OTEL_EXPORTER_OTLP_METRICS_HEADERS', env('OTEL_EXPORTER_OTLP_HEADERS', '')),
        'metrics_protocol' => env('OTEL_EXPORTER_OTLP_METRICS_PROTOCOL'),
        // Supported: "Delta", "Cumulative"
        'metrics_temporality' => env('OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE'),

        'logs_timeout' => (int) env('OTEL_EXPORTER_OTLP_LOGS_TIMEOUT', env('OTEL_EXPORTER_OTLP_TIMEOUT', 10000)),
        'logs_headers' => (string) env('OTEL_EXPORTER_OTLP_LOGS_HEADERS', env('OTEL_EXPORTER_OTLP_HEADERS', '')),
        'logs_protocol' => env('OTEL_EXPORTER_OTLP_LOGS_PROTOCOL'),
    ],
],

Zipkin exporter (traces only)

The Zipkin exporter sends trace data to a Zipkin-compatible backend. It supports traces only — metrics and logs must use a different exporter. First, install the Zipkin exporter package:
composer require open-telemetry/exporter-zipkin
Then configure the exporter:
'exporters' => [
    'zipkin' => [
        'driver' => 'zipkin',
        'endpoint' => env('OTEL_EXPORTER_ZIPKIN_ENDPOINT', 'http://localhost:9411'),
        'timeout' => env('OTEL_EXPORTER_ZIPKIN_TIMEOUT', 10000),
        'max_retries' => (int) env('OTEL_EXPORTER_ZIPKIN_MAX_RETRIES', 3),
    ],
],
Set the traces exporter to use Zipkin:
OTEL_TRACES_EXPORTER=zipkin

Console exporter

The console exporter writes telemetry data to stdout. This is useful during local development and debugging to inspect what is being exported without running a backend.
Use the console exporter locally to verify your instrumentation is working before connecting a real backend:
OTEL_TRACES_EXPORTER=console
OTEL_METRICS_EXPORTER=console
OTEL_LOGS_EXPORTER=console

Memory exporter

The memory exporter stores telemetry in memory instead of sending it anywhere. It is primarily intended for automated tests, where you want to assert what telemetry was produced without connecting to an external backend.
OTEL_TRACES_EXPORTER=memory
OTEL_METRICS_EXPORTER=memory
OTEL_LOGS_EXPORTER=memory

Null exporter

The null exporter silently discards all telemetry. Use it to completely disable exports for a specific signal without disabling the SDK.
OTEL_TRACES_EXPORTER=null
OTEL_METRICS_EXPORTER=null
OTEL_LOGS_EXPORTER=null

Configuring different exporters per signal

Each signal references an exporter by its key in the exporters map. You can route signals to different exporters by defining multiple exporter entries and pointing each signal at the right one:
// config/opentelemetry.php

'traces' => [
    'exporter' => env('OTEL_TRACES_EXPORTER', 'zipkin'),
    // ...
],

'metrics' => [
    'exporter' => env('OTEL_METRICS_EXPORTER', 'otlp'),
],

'logs' => [
    'exporter' => env('OTEL_LOGS_EXPORTER', 'otlp'),
],

'exporters' => [
    'otlp' => [
        'driver' => 'otlp',
        'endpoint' => env('OTEL_EXPORTER_OTLP_ENDPOINT', 'http://localhost:4318'),
        'protocol' => env('OTEL_EXPORTER_OTLP_PROTOCOL', 'http/protobuf'),
        // ...
    ],
    'zipkin' => [
        'driver' => 'zipkin',
        'endpoint' => env('OTEL_EXPORTER_ZIPKIN_ENDPOINT', 'http://localhost:9411'),
        // ...
    ],
],
You can also define multiple OTLP exporters with different endpoints — for example, to send traces to one collector and metrics to another — by duplicating the otlp entry under a different key.

Build docs developers (and LLMs) love