PHP code example of icyboy / zipkin

1. Go to this page and download the library: Download icyboy/zipkin library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

icyboy / zipkin example snippets


use GuzzleHttp\Client;
use Zipkin\Annotations;
use Zipkin\Endpoint;
use Zipkin\Samplers\BinarySampler;
use Zipkin\Timestamp;
use Zipkin\TracingBuilder;
use Zipkin\Reporters\HttpLogging;
use Zipkin\Propagation\Map;
use Zipkin\Propagation\DefaultSamplingFlags;
use Symfony\Component\HttpFoundation\Request;

$request  = Request::createFromGlobals();

$endpoint = Endpoint::create('server_name', 'server_ipv4', 'server_ipv6', 'server_ipv4');
$client = new Client();

// Logger to stdout
$logger = new \Monolog\Logger('log');
$logger->pushHandler(new \Monolog\Handler\ErrorLogHandler());

$reporter = new HttpLogging($client, $logger, ["host"=>"zipkin_server_address"]);
$sampler = BinarySampler::createAsAlwaysSample();
$tracing = TracingBuilder::create()
    ->havingLocalEndpoint($endpoint)
    ->havingSampler($sampler)
    ->havingReporter($reporter)
    ->build();

/***** this for client *****/
/* Always sample traces */
//$defaultSamplingFlags = DefaultSamplingFlags::createAsSampled();
/* Creates the main span */
//$span = $tracer->newTrace($defaultSamplingFlags);
/* Creates the span for getting the users list */
//$childSpan = $tracer->newChild($span->getContext());
//$childSpan->start();
//$childSpan->setName('users:get_list');
//$headers = [];
/* Injects the context into the wire */
//$injector = $tracing->getPropagation()->getInjector(new Map());
//$injector($childSpan->getContext(), $headers);
/* HTTP Request to the backend */
//$httpClient = new Client();
//$request = new \GuzzleHttp\Psr7\Request('POST', 'localhost:9000', $headers);
//$response = $httpClient->send($request);


//get request header
$carrier  = array_map(function ($header) {
    return $header[0];
}, $request->headers->all());

/* Extracts the context from the HTTP headers */
//get X─B3─xxx from headers if existed or auto generate
$extractor    = $tracing->getPropagation()->getExtractor(new Map());
$traceContext = $extractor($carrier);

//create trace
$tracer       = $tracing->getTracer();
$span         = $tracer->newChild($traceContext);
$span->start();

//get request parameters
$content = $request->getContent();
$data = json_decode($content, true);
if (is_array($data)) {
    $output = $data;
} elseif (!empty($content)) {
    parse_str($content, $output);
}

if (!empty($output) && is_array($output)) {
    foreach ($output as $k => $v) {
        $value = is_array($v) ? json_encode($v) : $v;
        $span->tag($k, $value);
    }
}

//set name
$span->setName(sprintf("%s %s", $request->getMethod(), $request->server->get("REQUEST_URI")));

//set Annotation
$span->annotate(Annotations\SERVER_RECV, Timestamp\now());
$span->finish(Timestamp\now());

//push info to zipkin server befor close program
register_shutdown_function(function () use ($tracer) {
    $tracer->flush();
});

$span = $tracer->newTrace()->setName('encode')->start();

try {
  doSomethingExpensive();
} finally {
  $span->finish();
}

$span = $tracer->newChild($root->getContext())->setName('encode')->start();
try {
  doSomethingExpensive();
} finally {
  $span->finish();
}

$span->tag('http.status_code', '200');

// before you send a request, add metadata that describes the operation
$span = $tracer->newTrace()->setName('get')->setKind(Kind\CLIENT);
$span->tag('http.status_code', '200');
$span->tag(Tags\HTTP_PATH, '/api');
$span->setRemoteEndpoint(Remote::create('backend', 127 << 24 | 1, null, 8080);

// when the request is scheduled, start the span
$span->start();

// if you have callbacks for when data is on the wire, note those events
$span->annotate(Annotations\SERVER_SEND);
$span->annotate(Annotations\SERVER_RECV);

// when the response is complete, finish the span
$span->finish();

// start a new span representing a client request
$oneWaySend = $tracer->newChild($parent)->setKind(Kind\CLIENT);

// Add the trace context to the request, so it can be propagated in-band
$tracing->getPropagation()->getInjector(new RequestHeaders)
                     ->inject($oneWaySend->getContext(), $request);

// fire off the request asynchronously, totally dropping any response
$client->execute($request);

// start the client side and flush instead of finish
$oneWaySend->start()->flush();

// pull the context out of the incoming request
$extractor = $tracing->getPropagation()->getExtractor(new RequestHeaders);

// convert that context to a span which you can name and add tags to
$oneWayReceive = $tracer->newChild($extractor($request))
    ->setName('process-request')
    ->setKind(Kind\SERVER)
    ... add tags etc.

// start the server side and flush instead of finish
$oneWayReceive->start()->flush();

// you should not modify this span anymore as it is complete. However,
// you can create children to represent follow-up work.
$next = $tracer->newChild($oneWayReceive->getContext())->setName('step2')->start();

private function newTrace(Request $request) {
  $flags = SamplingFlags::createAsEmpty();
  if (strpos($request->getUri(), '/experimental') === 0) {
    $flags = DefaultSamplingFlags::createAsSampled();
  } else if (strpos($request->getUri(), '/static') === 0) {
    $flags = DefaultSamplingFlags::createAsSampled();
  }
  return $tracer->newTrace($flags);
}

// configure a function that injects a trace context into a request
$injector = $tracing->getPropagation()->getInjector(new RequestHeaders);

// before a request is sent, add the current span's context to it
$injector->inject($span->getContext(), $request);

// configure a function that extracts the trace context from a request
$extracted = $tracing->getPropagation()->extractor(new RequestHeaders);

$span = $tracer->newChild($extracted)->setKind(Kind\SERVER);

/**
  * This http clients composes an http client using PSR7
  */
class TraceClient implements ClientInterface
{
    public function request($method, $uri = '', array $options = [])
    {
        /* Gets the child Span of the current one */
        $span = $this->tracer->nextSpan();
        $span->setKind(Zipkin\Kind\CLIENT);
        $span->tag(Tags\HTTP_PATH, $uri);
        
        try {
            $response = $this->client->request($method, $uri, $options);
            $span->tag(Tags\HTTP_STATUS_CODE, $response->getStatusCode());
            
            return $response;
        catch (\Exception $e) {
            $span->tag(Tags\Error, $response->getReasonPhrase());        
            $span->tag(Tags\HTTP_STATUS_CODE, $e->getResponse->getStatusCode());
            
            throw $e;
        } finally {
            $span->finish();
        }
    }
}