Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Exporter Otlp Laravel Package

open-telemetry/exporter-otlp

OpenTelemetry OTLP exporter for PHP. Send traces to an OpenTelemetry Collector via HTTP (JSON/protobuf) or gRPC (with transport-grpc). Requires a protobuf runtime; for production, install the protobuf PECL extension for best performance.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the package via Composer:

    composer require open-telemetry/exporter-otlp
    

    Require the autoloader in your Laravel app (handled automatically by Composer).

  2. First Use Case: Basic Tracing Initialize the OTLP exporter in your bootstrap/app.php or a service provider:

    use OpenTelemetry\SDK\Trace\SpanProcessor\BatchSpanProcessor;
    use OpenTelemetry\SDK\Trace\TracerProvider;
    use OpenTelemetry\SDK\Resource\ResourceInfo;
    use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationLibrary;
    use OpenTelemetry\Exporter\OTLP\OtlpHttp\OtlpHttpSpanExporter;
    
    $exporter = new OtlpHttpSpanExporter(
        'http://your-collector:4318/v1/traces', // OTLP endpoint
        OtlpHttpSpanExporter::SECURE // or OtlpHttpSpanExporter::INSECURE for local testing
    );
    
    $provider = new TracerProvider();
    $provider->addSpanProcessor(new BatchSpanProcessor($exporter));
    $provider->register();
    
  3. Verify with a Test Span Create a simple route to test:

    use OpenTelemetry\API\Globals;
    use OpenTelemetry\API\Trace\TracerInterface;
    
    Route::get('/test-trace', function () {
        $tracer = Globals::tracerProvider()->getTracer('laravel.test');
        $span = $tracer->spanBuilder('test-span')->startSpan();
        $span->end();
        return 'Trace sent!';
    });
    
  4. Check Collector Verify traces appear in your OTLP collector (e.g., Jaeger, Zipkin, or OTLP-compatible backend).


Implementation Patterns

Common Workflows

1. Instrumenting HTTP Requests

Use middleware to automatically trace incoming requests:

namespace App\Http\Middleware;

use Closure;
use OpenTelemetry\API\Globals;
use OpenTelemetry\API\Trace\TracerInterface;

class TraceMiddleware
{
    public function handle($request, Closure $next)
    {
        $tracer = Globals::tracerProvider()->getTracer('laravel.http');
        $span = $tracer->spanBuilder('HTTP ' . $request->method())
            ->setAttribute('http.url', $request->fullUrl())
            ->startSpan();

        try {
            $response = $next($request);
            $span->setAttribute('http.status_code', $response->getStatusCode());
            return $response;
        } finally {
            $span->end();
        }
    }
}

Register in app/Http/Kernel.php:

protected $middleware = [
    \App\Http\Middleware\TraceMiddleware::class,
];

2. Database Query Tracing

Wrap database queries with spans:

use OpenTelemetry\API\Globals;
use Illuminate\Support\Facades\DB;

DB::listen(function ($query) {
    $tracer = Globals::tracerProvider()->getTracer('laravel.db');
    $span = $tracer->spanBuilder('SQL Query')
        ->setAttribute('db.type', 'mysql')
        ->setAttribute('db.query', $query->sql)
        ->startSpan();

    try {
        $result = $query->run();
        $span->setAttribute('db.duration_ms', $query->time * 1000);
        return $result;
    } finally {
        $span->end();
    }
});

3. Context Propagation

Propagate spans across service boundaries (e.g., HTTP clients):

use OpenTelemetry\API\Globals;
use Illuminate\Support\Facades\Http;

$response = Http::withOptions([
    'headers' => [
        'traceparent' => Globals::propagation()->getBaggageHeader(),
    ],
])->get('https://external-service.com/api');

4. Resource Attributes

Set static resource attributes (e.g., service name, version) in bootstrap/app.php:

$resource = ResourceInfo::create([
    'service.name' => 'laravel-app',
    'service.version' => '1.0.0',
    'deployment.environment' => app()->environment(),
]);
$provider = new TracerProvider();
$provider->setResource($resource);

Integration Tips

Laravel-Specific

  • Service Container Binding Bind the tracer provider to Laravel’s container for easy access:

    $app->singleton(TracerProvider::class, function () {
        return new TracerProvider();
    });
    

    Then inject TracerProvider into controllers/services:

    use OpenTelemetry\SDK\Trace\TracerProvider;
    
    public function __construct(private TracerProvider $tracerProvider) {}
    
  • Queue Job Tracing Trace async jobs by wrapping handle():

    use OpenTelemetry\API\Globals;
    
    public function handle()
    {
        $tracer = Globals::tracerProvider()->getTracer('laravel.queue');
        $span = $tracer->spanBuilder('Job: ' . static::class)->startSpan();
    
        try {
            // Job logic
        } finally {
            $span->end();
        }
    }
    
  • Artisan Commands Trace CLI commands:

    use OpenTelemetry\API\Globals;
    use Symfony\Component\Console\Command\Command;
    
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $tracer = Globals::tracerProvider()->getTracer('laravel.artisan');
        $span = $tracer->spanBuilder($this->getName())->startSpan();
    
        try {
            parent::execute($input, $output);
        } finally {
            $span->end();
        }
    }
    

Gotchas and Tips

Pitfalls

  1. Exporter Configuration

    • Timeouts: OTLP HTTP exporter has a default timeout of 10 seconds. Adjust if your collector is slow:
      $exporter = new OtlpHttpSpanExporter(
          'http://collector:4318',
          OtlpHttpSpanExporter::SECURE,
          30 // timeout in seconds
      );
      
    • Retry Logic: The exporter does not retry failed requests by default. For resilience, wrap it:
      use OpenTelemetry\Exporter\OTLP\OtlpHttp\OtlpHttpSpanExporter;
      use GuzzleHttp\Client;
      
      $client = new Client(['timeout' => 5]);
      $exporter = new OtlpHttpSpanExporter('http://collector:4318', OtlpHttpSpanExporter::SECURE, 0, $client);
      
  2. Span Limits

    • Batch processors buffer spans in memory. For high-throughput apps, monitor memory usage or reduce batch size:
      $processor = new BatchSpanProcessor($exporter, 500, 5); // Max 500 spans, flush every 5 seconds
      
  3. Context Leaks

    • Avoid leaking spans across requests (e.g., in middleware). Use Span::end() in finally blocks.
  4. OTLP Collector Compatibility

    • Ensure your collector supports the OTLP protocol version (e.g., v1 vs. v0.17.0). Mismatches may cause silent failures.

Debugging

  1. Enable Logging Configure the exporter to log errors:

    $exporter = new OtlpHttpSpanExporter(
        'http://collector:4318',
        OtlpHttpSpanExporter::SECURE,
        0,
        null,
        ['logger' => new \Monolog\Logger('otlp')]
    );
    
  2. Validate Traces Locally Use testcontainers or Docker to spin up a temporary OTLP collector (e.g., Jaeger) for testing:

    docker run -d --name jaeger \
        -e COLLECTOR_OTLP_ENABLED=true \
        -p 16686:16686 -p 4317:4317 -p 4318:4318 jaegertracing/all-in-one:latest
    
  3. Check Headers Verify traceparent headers are propagated in HTTP requests:

    dd(Http::get('https://example.com')->headers());
    

Extension Points

  1. Custom Span Processors Extend SpanProcessor to filter or modify spans:
    use OpenTelemetry\SDK\Trace\SpanProcessor\SpanProcessorInterface;
    
    class FilterSpanProcessor implements SpanProcessorInterface
    {
        public function onStart(\OpenTelemetry\SDK\Trace\Span $span) {}
        public function onEnd(\OpenTele
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport