Code Monkey home page Code Monkey logo

opentracing-php's Introduction

OpenTracing API for PHP

Build Status OpenTracing Badge Total Downloads Minimum PHP Version License Join the chat at https://gitter.im/opentracing/opentracing-php

PHP library for the OpenTracing's API.

Required Reading

In order to understand the library, one must first be familiar with the OpenTracing project and specification more specifically.

Installation

OpenTracing-PHP can be installed via Composer:

composer require opentracing/opentracing

Usage

When consuming this library one really only need to worry about a couple of key abstractions: the Tracer::startActiveSpan and Tracer::startSpan method, the Span interface, and binding a Tracer at bootstrap time. Here are code snippets demonstrating some important use cases:

Singleton initialization

The simplest starting point is to set the global tracer. As early as possible, do:

use OpenTracing\GlobalTracer;

GlobalTracer::set(new MyTracerImplementation());

Creating a Span given an existing Request

To start a new Span, you can use the startActiveSpan method.

use OpenTracing\Formats;
use OpenTracing\GlobalTracer;

...

$spanContext = GlobalTracer::get()->extract(
    Formats\HTTP_HEADERS,
    getallheaders()
);

function doSomething() {
    ...

    $span = GlobalTracer::get()->startActiveSpan('my_span', ['child_of' => $spanContext]);

    ...

    $span->log([
        'event' => 'soft error',
        'type' => 'cache timeout',
        'waiter.millis' => 1500,
    ])

    $span->finish();
}

Starting an empty trace by creating a "root span"

It's always possible to create a "root" Span with no parent or other causal reference.

$span = $tracer->startActiveSpan('my_first_span');
...
$span->finish();

Active Spans and Scope Manager

When using the Tracer::startActiveSpan function the underlying tracer uses an abstraction called scope manager to keep track of the currently active span.

Starting an active span will always use the currently active span as a parent. If no parent is available, then the newly created span is considered to be the root span of the trace.

Unless you are using asynchronuous code that tracks multiple spans at the same time, such as when using cURL Multi Exec or MySQLi Polling you are better of just using Tracer::startActiveSpan everywhere in your application.

The currently active span gets automatically closed and deactivated from the scope when you call $span->finish() as you can see in the previous example.

If you don't want a span to automatically close when Span::finish() is called then you must pass the option 'close_span_on_finish'=> false, to the $options argument of startActiveSpan.

An example of a linear, two level deep span tree using active spans looks like this in PHP code:

$root = $tracer->startActiveSpan('php');

    $controller = $tracer->startActiveSpan('controller');

        $http = $tracer->startActiveSpan('http');
        file_get_contents('http://php.net');
        $http->finish();

    $controller->finish();
$root->finish();

Creating a child span assigning parent manually

$parent = GlobalTracer::get()->startSpan('parent');

$child = GlobalTracer::get()->startSpan('child', [
    'child_of' => $parent
]);

...

$child->finish();

...

$parent->finish();

Creating a child span using automatic active span management

Every new span will take the active span as parent and it will take its spot.

$parent = GlobalTracer::get()->startActiveSpan('parent');

...

/*
 * Since the parent span has been created by using startActiveSpan we don't need
 * to pass a reference for this child span
 */
$child = GlobalTracer::get()->startActiveSpan('my_second_span');

...

$child->finish();

...

$parent->finish();

Serializing to the wire

use GuzzleHttp\Client;
use OpenTracing\Formats;

...

$tracer = GlobalTracer::get();

$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) {
    ...
}
...

Deserializing from the wire

When using http header for context propagation you can use either the Request or the $_SERVER variable:

use OpenTracing\GlobalTracer;
use OpenTracing\Formats;

$tracer = GlobalTracer::get();
$spanContext = $tracer->extract(Formats\HTTP_HEADERS, getallheaders());
$tracer->startSpan('my_span', [
    'child_of' => $spanContext,
]);

Flushing Spans

PHP as a request scoped language has no simple means to pass the collected spans data to a background process without blocking the main request thread/process. The OpenTracing API makes no assumptions about this, but for PHP that might cause problems for Tracer implementations. This is why the PHP API contains a flush method that allows to trigger a span sending out of process.

use OpenTracing\GlobalTracer;

$application->run();

register_shutdown_function(function() use ($tracer) {
    /* Flush the tracer to the backend */
    $tracer = GlobalTracer::get();
    $tracer->flush();
});

This is optional, tracers can decide to immediately send finished spans to a backend. The flush call can be implemented as a NO-OP for these tracers.

Using Span Options

Passing options to the pass can be done using either an array or the SpanOptions wrapper object. The following keys are valid:

  • start_time is a float, int or \DateTime representing a timestamp with arbitrary precision.
  • child_of is an object of type OpenTracing\SpanContext or OpenTracing\Span.
  • references is an array of OpenTracing\Reference.
  • tags is an array with string keys and scalar values that represent OpenTracing tags.
$span = $tracer->startActiveSpan('my_span', [
    'child_of' => $spanContext,
    'tags' => ['foo' => 'bar'],
    'start_time' => time(),
]);

Propagation Formats

The propagation formats should be implemented consistently across all tracers. If you want to implement your own format, then don't reuse the existing constants. Tracers will throw an exception if the requested format is not handled by them.

  • Tracer::FORMAT_TEXT_MAP should represents the span context as a key value map. There is no assumption about the semantics where the context is coming from and sent to.

  • Tracer::FORMAT_HTTP_HEADERS should represent the span context as HTTP header lines in an array list. For two context details "Span-Id" and "Trace-Id", the result would be ['Span-Id: abc123', 'Trace-Id: def456']. This definition can be passed directly to curl and file_get_contents.

  • Tracer::FORMAT_BINARY makes no assumptions about the data format other than it is proprietary and each Tracer can handle it as it wants.

Coding Style

OpenTracing PHP follows the PSR-2 coding standard and the PSR-4 autoloading standard.

opentracing-php's People

Contributors

beberlei avatar felixfbecker avatar gitter-badger avatar jcchavezs avatar reimertz avatar tpl0ch avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.