OpenTracing-PHP

repository·master·Indexed 19 days ago

https://github.com/opentracing/opentracing-php

A PHP implementation of the OpenTracing API providing a vendor-agnostic interface for distributed tracing. It enables developers to instrument applications with spans and traces, manage context propagation via HTTP headers, and send data to various backend collectors.

Tokens
1.9K
Snippets
9
Records
10
Agent score
18%

What's inside OpenTracing-PHP

  1. How Active Spans and Scope Manager work

    master

    For most use cases, it is recommended to use Tracer::startActiveSpan.

    Key Concepts:

    • Scope Manager: An underlying abstraction that tracks the currently active span.
    • Automatic Parenting: Starting an active span automatically uses the currently active span as its parent. If no parent is active, the new span becomes the root span.
    • Automatic Finishing: When using startActiveSpan, the span is automatically finished when you call $scope->close().
    • Asynchronous Note: Unless you are using asynchronous code that tracks multiple spans simultaneously (like cURL Multi Exec), use startActiveSpan everywhere.

    To prevent a span from automatically finishing when the scope is closed, pass 'finish_span_on_close' => false in the options array.

    // At dispatcher level
    $scope = $tracer->startActiveSpan('request');
    ...
    $scope->close();
    
    // At controller level
    $scope = $tracer->startActiveSpan('controller');
    ...
    $scope->close();
    
    // At RPC calls level
    $scope = $tracer->startActiveSpan('http');
    file_get_contents('http://php.net');
    $scope->close();
  2. Flush spans to the backend

    master

    Because PHP is request-scoped, tracers may need a way to send collected span data to a backend without blocking the main request. Use the flush() method to trigger this. It is common to call this in a shutdown function.

    use OpenTracing\GlobalTracer;
    
    $application->run();
    
    register_shutdown_function(function() {
        /* Flush the tracer to the backend */
        $tracer = GlobalTracer::get();
        $tracer->flush();
    });
  3. Create a span from an existing request (Context Propagation)

    master

    When receiving a request that already contains tracing information (e.g., via HTTP headers), extract the span context and use it as a parent for a new span.

    use OpenTracing\Formats;
    use OpenTracing\GlobalTracer;
    
    // extract the span context
    $spanContext = GlobalTracer::get()->extract(
        Formats\HTTP_HEADERS,
        getallheaders()
    );
    
    function doSomething() {
        // start a new span called 'my_span' and make it a child of the $spanContext
        $span = GlobalTracer::get()->startSpan('my_span', ['child_of' => $spanContext]);
    
        // add some logs to the span
        $span->log([
            'event' => 'soft error',
            'type' => 'cache timeout',
            'waiter.millis' => 1500,
        ]);
    
        // finish the span
        $span->finish();
    }
  4. Inject span context into HTTP headers (Serialization)

    master

    To propagate tracing context to an outgoing request (e.g., via Guzzle), use the inject method to serialize the span context into a format like HTTP_HEADERS.

    use GuzzleHttp\
    Client;
    use OpenTracing\Formats;
    
    $tracer = GlobalTracer::get();
    
    // Assume $spanContext was extracted from an incoming request
    $spanContext = $tracer->extract(Formats\HTTP_HEADERS, getallheaders());
    
    try {
        $span = $tracer->startSpan('my_span', ['child_of' => $spanContext]);
        $client = new Client;
        $headers = [];
    
        $tracer->inject(
            $span->getContext(),
            Formats\HTTP_HEADERS,
            $headers
        );
    
        $request = new \GuzzleHttp\Psr7\Request('GET', 'http://myservice', $headers);
        $client->send($request);
    } catch (\Exception $e) {
        // handle error
    }
  5. Manually assign a parent to a child span

    master

    If you are not using the active span management, you can manually link a child span to a parent span using the child_of option.

    $parent = GlobalTracer::get()->startSpan('parent');
    
    $child = GlobalTracer::get()->startSpan('child', [
        'child_of' => $parent
    ]);
    
    ...
    $child->finish();
    
    ...
    $parent->finish();
  6. Configure StartSpanOptions

    master

    When calling startSpan or startActiveSpan, you can pass an array or a SpanOptions object containing the following keys:

    • start_time: (float, int, or \DateTime) A timestamp with arbitrary precision.
    • child_of: (OpenTracing\SpanContext or OpenTracing\Span) The parent context.
    • references: (array of OpenTracing\Reference) Additional causal references.
    • tags: (array) String keys and scalar values representing OpenTracing tags.
    • finish_span_on_close: (boolean) Determines if the span finishes when the scope is closed.
    $span = $tracer->startActiveSpan('my_span', [
        'child_of' => $spanContext,
        'tags' => ['foo' => 'bar'],
        'start_time' => time(),
    ]);
  7. Reference: Propagation Formats

    master

    Tracers implement specific formats to allow span context to move across process boundaries. The following constants are used:

    • Tracer::FORMAT_TEXT_MAP: Represents the span context as a key-value map. No assumptions are made about the source semantics.
    • Tracer::FORMAT_HTTP_HEADERS: Represents the span context as HTTP header lines in an array (e.g., ['Span-Id: abc123', 'Trace-Id: def456']).
    • Tracer::FORMAT_BINARY: A proprietary binary format handled according to the specific Tracer's implementation.