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 Zipkin Laravel Package

open-telemetry/exporter-zipkin

OpenTelemetry Zipkin Exporter for PHP. Sends OpenTelemetry traces to a Zipkin collector for storage and visualization. Use with the OpenTelemetry PHP SDK to export spans over HTTP, enabling distributed tracing and diagnostics in your applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package via Composer:
    composer require open-telemetry/exporter-zipkin
    
  2. Configure the exporter in your Laravel service provider (e.g., AppServiceProvider):
    use OpenTelemetry\SDK\Trace\SpanProcessor\BatchSpanProcessor;
    use OpenTelemetry\Contrib\Zipkin\Exporter\ZipkinExporter;
    
    public function boot()
    {
        $zipkinExporter = new ZipkinExporter('http://your-zipkin-server:9411/api/v2/spans');
        $spanProcessor = new BatchSpanProcessor($zipkinExporter);
        \OpenTelemetry\API\Common\GlobalRegistry::getTraceProvider()->addSpanProcessor($spanProcessor);
    }
    
  3. Instrument a critical path (e.g., a route or job):
    use OpenTelemetry\API\Trace\TracerInterface;
    
    public function handle(TracerInterface $tracer)
    {
        $span = $tracer->spanBuilder('process-job')->startSpan();
        try {
            // Your job logic here
            $span->setAttribute('job.status', 'success');
        } finally {
            $span->end();
        }
    }
    

First Use Case: Tracing API Requests

Add middleware to auto-instrument HTTP requests:

use OpenTelemetry\API\Trace\TracerInterface;

class TraceMiddleware
{
    public function handle($request, Closure $next, TracerInterface $tracer)
    {
        $span = $tracer->spanBuilder('http.request')->startSpan();
        $span->setAttribute('http.method', $request->method());
        $span->setAttribute('http.path', $request->path());

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

Implementation Patterns

Workflow: Distributed Tracing in Laravel

  1. Instrument Entry Points:

    • Use middleware for HTTP routes.
    • Wrap queue jobs, commands, and event listeners in spans.
    $tracer = \OpenTelemetry\API\Common\GlobalRegistry::getTraceProvider()->getTracer('my-app');
    $span = $tracer->spanBuilder('event.processed')->startSpan();
    
  2. Propagate Context:

    • Attach trace context to outbound HTTP requests (e.g., via W3C Trace Context headers).
    use OpenTelemetry\API\Trace\Propagation\TextMapPropagator;
    
    $propagator = new TextMapPropagator();
    $carrier = [];
    $propagator->inject($carrier, $span->getSpanContext());
    Http::withHeaders($carrier)->get('https://external-api.com');
    
  3. Batch Exports: Configure the BatchSpanProcessor for optimal performance:

    $exporter = new ZipkinExporter('http://zipkin:9411/api/v2/spans', [
        'batch_size' => 50,          // Flush after 50 spans
        'flush_interval' => 5000,    // Flush every 5 seconds
        'timeout' => 1000,           // Timeout in milliseconds
    ]);
    
  4. Laravel-Specific Attributes: Enrich spans with Laravel metadata:

    $span->setAttribute('laravel.route', route()->currentRouteName());
    $span->setAttribute('laravel.user.id', auth()->id());
    

Integration Tips

  • Queue Jobs: Use the handle() method of jobs to wrap execution in spans.
    public function handle()
    {
        $tracer = app(TracerInterface::class);
        $span = $tracer->spanBuilder('job.process')->startSpan();
        try {
            // Job logic
        } finally {
            $span->end();
        }
    }
    
  • Database Queries: Instrument Eloquent queries with query() hooks.
    \DB::listen(function ($query) {
        $tracer = app(TracerInterface::class);
        $span = $tracer->spanBuilder('db.query')->startSpan();
        $span->setAttribute('db.query', $query->sql);
        // ... end span after query completes
    });
    
  • HTTP Clients: Use Http::macro() to auto-instrument Guzzle requests.
    Http::macro('withTrace', function ($url, $span) {
        $propagator = new TextMapPropagator();
        $carrier = [];
        $propagator->inject($carrier, $span->getSpanContext());
        return Http::withHeaders($carrier)->get($url);
    });
    

Gotchas and Tips

Pitfalls

  1. Non-String Attributes: Zipkin expects all tags/attributes to be strings. Non-string values (e.g., null, int, array) may cause serialization errors. Fix: Cast attributes explicitly:

    $span->setAttribute('user.id', (string) auth()->id());
    
  2. Timeouts and Retries: The exporter uses HTTP under the hood. If your Zipkin server is unreachable, spans may accumulate in memory. Fix: Configure a reasonable timeout and flush_interval:

    $exporter = new ZipkinExporter('http://zipkin:9411/api/v2/spans', [
        'timeout' => 2000,  // 2 seconds
        'flush_interval' => 2000,
    ]);
    
  3. PHP Version Mismatch: The package drops support for PHP <8.1. Ensure your Laravel app is upgraded. Fix: Update composer.json to require PHP 8.1+:

    "require": {
        "php": "^8.1"
    }
    
  4. Span Context Propagation: If traces appear disconnected across services, check:

    • Headers are correctly injected/extracted.
    • The TextMapPropagator is used consistently. Debug: Log the traceparent header:
    \Log::debug('Trace Context:', ['traceparent' => $carrier['traceparent'] ?? 'missing']);
    
  5. Zipkin Server Compatibility: Ensure your Zipkin server supports the v2 API (used by this exporter). Older servers may reject requests. Fix: Use a modern collector like Jaeger or Grafana Tempo.

Debugging Tips

  • Check Exported Spans: Use the Zipkin UI to verify traces are being received:
    http://your-zipkin-server:9411/
    
  • Log Exporter Errors: Wrap the exporter in a custom class to log failures:
    class LoggingZipkinExporter implements Exporter
    {
        private $exporter;
    
        public function __construct(ZipkinExporter $exporter)
        {
            $this->exporter = $exporter;
        }
    
        public function export(array $spans)
        {
            try {
                return $this->exporter->export($spans);
            } catch (\Exception $e) {
                \Log::error('Zipkin export failed', ['error' => $e->getMessage()]);
                throw $e;
            }
        }
    }
    
  • Validate Span Data: Use the OpenTelemetry PHP SDK’s SpanProcessor to validate spans before export:
    $processor = new class implements SpanProcessor {
        public function onStart(Span $span) {}
        public function onEnd(Span $span) {
            if (empty($span->getName())) {
                \Log::warning('Span without name', ['span_id' => $span->getSpanContext()->getSpanId()]);
            }
        }
    };
    

Extension Points

  1. Custom Span Attributes: Add Laravel-specific attributes via a trait or helper:

    trait Traceable
    {
        protected function startSpan(string $name): Span
        {
            $span = app(TracerInterface::class)->spanBuilder($name)->startSpan();
            $span->setAttribute('laravel.instance', config('app.name'));
            return $span;
        }
    }
    
  2. Dynamic Endpoint Configuration: Use Laravel’s config() to manage the Zipkin endpoint:

    $exporter = new ZipkinExporter(config('telemetry.zipkin.endpoint'));
    
  3. Sampling: Implement custom sampling logic to reduce trace volume:

    $provider = new TraceProvider([
        'sampler' => new AlwaysOnSampler(), // or custom sampler
        'span_processor' => new BatchSpanProcessor($exporter),
    ]);
    
  4. Async Transport: For high-throughput apps, use an async HTTP client (e.g., `php-http/async-client-implementation

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.
datacore/hub-sdk
alengo/sulu-http-cache-bundle
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
imbo/imbo-coding-standard
visualbuilder/filament-lottie
servicioslineaonce/starter-kit
atomcoder/laravel-reorderable
irajul/filament-shadcn-theme
agtp/agtp-php
agtp/mod-php
centraldesktop/protobuf-php
trappistes/laravel-custom-fields
splash/sonata-admin
splash/metadata