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

Symfony Open Tracing Laravel Package

adtechpotok/symfony-open-tracing

Symfony OpenTracing integration for Symfony apps. Adds tracing support with minimal setup, helping you instrument requests and services, propagate trace context, and export spans to compatible backends for distributed tracing and performance diagnostics.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup for Laravel

Since this package is Symfony-focused but can be adapted for Laravel (via Symfony components or bridges like symfony/http-foundation), start by:

  1. Installation

    composer require adtechpotok/symfony-open-tracing
    

    Note: Laravel lacks native Symfony integration, so use a bridge like symfony/http-client or symfony/process for compatibility.

  2. Basic Tracing Initialization

    use Adtechpotok\OpenTracing\Tracer;
    use OpenTracing\Tracer as OpenTracingTracer;
    
    // Initialize a tracer (mock example; replace with Jaeger/Zipkin later)
    $tracer = new Tracer();
    OpenTracingTracer::setGlobalTracer($tracer);
    
  3. First Use Case: HTTP Request Tracing

    use OpenTracing\Span;
    use OpenTracing\Scope;
    
    $span = OpenTracingTracer::global()->buildSpan('http_request')->start();
    $scope = $span->activate();
    
    try {
        $response = Http::get('https://api.example.com', [
            'headers' => ['X-Trace-ID' => $span->context()->toTraceId()]
        ]);
    } finally {
        $span->finish();
        $scope->close();
    }
    

Key Files to Review


Implementation Patterns

1. Middleware for Automatic Tracing

Leverage Laravel middleware to inject spans into incoming/outgoing requests:

use OpenTracing\Tracer as OpenTracingTracer;

class TracingMiddleware
{
    public function handle($request, Closure $next)
    {
        $span = OpenTracingTracer::global()->buildSpan('http_incoming')
            ->withTag('http.method', $request->method())
            ->withTag('http.path', $request->path())
            ->start();

        try {
            $response = $next($request);
            $span->setTag('http.status_code', $response->status());
        } finally {
            $span->finish();
        }

        return $response;
    }
}

Register in app/Http/Kernel.php:

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

2. Service-Level Tracing

Wrap business logic in spans:

use OpenTracing\Tracer as OpenTracingTracer;

class UserService
{
    public function createUser(array $data)
    {
        $span = OpenTracingTracer::global()->buildSpan('user_service.create')
            ->withTag('user.data', json_encode($data))
            ->start();

        try {
            // Business logic here
            return User::create($data);
        } finally {
            $span->finish();
        }
    }
}

3. Database Query Tracing

Use Laravel’s query log to create spans:

use Illuminate\Support\Facades\DB;
use OpenTracing\Tracer as OpenTracingTracer;

DB::listen(function ($query) {
    $span = OpenTracingTracer::global()->buildSpan('db_query')
        ->withTag('db.type', $query->bindings)
        ->withTag('db.sql', $query->sql)
        ->start();

    try {
        // Execute query (handled by DB listener)
    } finally {
        $span->finish();
    }
});

4. Distributed Tracing with HTTP Clients

Propagate trace context across services:

use OpenTracing\Propagation\TextMapAdapter;
use OpenTracing\Tracer as OpenTracingTracer;

$span = OpenTracingTracer::global()->buildSpan('external_api_call')->start();
$carrier = new TextMapCarrier();
OpenTracingTracer::global()->inject(
    $span->context(),
    \OpenTracing\FORMAT_HTTP_HEADERS,
    $carrier
);

$response = Http::withHeaders($carrier->toArray())->get('https://external-api.com');

Gotchas and Tips

1. Laravel-Symfony Integration Quirks

  • No Native Symfony Components: This package assumes Symfony’s HttpFoundation or Process. For Laravel:
    • Use symfony/http-client for HTTP tracing.
    • Mock Request/Response objects if needed (e.g., via symfony/http-foundation).
  • Dependency Injection: Laravel’s container doesn’t natively support Symfony’s ContainerInterface. Bind the tracer manually:
    $app->singleton(OpenTracingTracer::class, function () {
        return new Tracer(); // Or your Jaeger/Zipkin tracer
    });
    

2. Debugging

  • Missing Spans: Ensure OpenTracingTracer::setGlobalTracer() is called before any spans are created.
  • Context Propagation: Verify headers like uber-trace-id or x-b3-traceid are correctly injected/extracted.
  • Log Tracer Errors:
    OpenTracingTracer::global()->setSpanReporter(new \OpenTracing\Reporter\LoggingReporter());
    

3. Performance Pitfalls

  • Span Overhead: Avoid nesting spans too deeply (e.g., per-loop iteration). Batch operations instead.
  • Global Tracer: Setting the global tracer too late (e.g., after routes are loaded) may miss initial requests.

4. Extension Points

  • Custom Span Decorators: Extend Span to add Laravel-specific tags:
    $span->setTag('laravel.route', route()->currentRouteName());
    
  • Reporter Integration: Replace the default reporter with Jaeger/Zipkin:
    use Jaeger\Reporter\RemoteReporter;
    
    $reporter = new RemoteReporter('http://jaeger:14268/api/traces');
    OpenTracingTracer::global()->registerSpanReporter($reporter);
    
  • Context Filters: Use SpanContext to filter sensitive data (e.g., passwords) from traces.

5. Testing

  • Mock the Tracer: In tests, use a no-op tracer:
    OpenTracingTracer::setGlobalTracer(new \OpenTracing\NoopTracer());
    
  • Assert Span Lifecycle:
    $this->assertTrue($span->isFinished());
    $this->assertEquals('http_request', $span->operationName());
    

6. Configuration

  • No Built-in Config: Define tracer settings in config/tracing.php:
    return [
        'service_name' => env('APP_NAME'),
        'sampler' => 'const', // 'const', 'probabilistic', or custom
        'reporter' => [
            'type' => 'jaeger', // or 'zipkin', 'logging'
            'endpoint' => env('TRACING_ENDPOINT'),
        ],
    ];
    
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.
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager