moolex/opentracing

PHP 的 OpenTracing API

0.9.171115 2018-08-23 03:47 UTC

This package is auto-updated.

Last update: 2024-09-17 20:25:22 UTC


README

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

PHP 的 OpenTracing API 库。

必读

为了理解这个库,首先必须熟悉 OpenTracing 项目 和更具体的 规范

安装

可以通过 Composer 安装 OpenTracing-PHP

composer require opentracing/opentracing

使用

当使用这个库时,你实际上只需要关注几个关键抽象:`Tracer::startSpan` 方法,`Span` 接口,以及在引导时绑定 `Tracer`。以下是一些重要用例的代码片段

单例初始化

最简单的起点是设置全局tracer。尽早做:

    use OpenTracing\GlobalTracer;
    use AnOpenTracingImplementation\MyTracer;
    
    GlobalTracer::set(new MyTracer());

根据现有的请求创建 Span

要启动一个新的 `Span`,可以使用 `StartSpanFromContext` 方法。

    use OpenTracing\Formats;
    use OpenTracing\GlobalTracer;

    ...

    $spanContext = GlobalTracer::get()->extract(
        Formats\HTTP_HEADERS,
        $request->getHeaders()
    );
    
    function doSomething(SpanContext $spanContext, ...) {
        ...
        
        $span = GlobalTracer::get()->startSpan('my_span', [
        	'child_of' => $spanContext,
        ]);
        
        ...
        
        $span->log([
            'event' => 'soft error',
            'type' => 'cache timeout',
            'waiter.millis' => 1500,
        ])
        
        $span->finish();
    }

通过创建 "root span" 启动一个空的 trace

总是可以创建一个没有父级或其他因果引用的 "root" `Span`。

    $span = $tracer->startSpan('my_span');
    ...
    $span->finish();

根据现有的(父级)Span 创建(子)Span

    function xyz(Span $parentSpan, ...) {
        ...
        $span = GlobalTracer::get()->startSpan(
        	'my_span',
        	[
        		'child_of' => $parentSpan,
        	]
        );
        
        $span->finish();
        ...
    }

序列化到线路上

    use OpenTracing\GlobalTracer;
    use OpenTracing\Formats;
    
    ...
    
    $tracer = GlobalTracer::get(); 
    
    $spanContext = $tracer->extract(
        Formats\HTTP_HEADERS,
        $request->getHeaders()
    );
    
    try {
        $span = $tracer->startSpan('my_span', ['child_of' => $spanContext]);

        $client = new GuzzleHttp\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) {
        ...
    }
    ...        

从线路上反序列化

当使用 HTTP 头部进行上下文传播时,可以使用 `Request` 或 `$_SERVER` 变量

    use OpenTracing\GlobalTracer;
    use OpenTracing\Formats;
    
    $request = Request::createFromGlobals();
    $tracer = GlobalTracer::get();
    $spanContext = $tracer->extract(Formats\HTTP_HEADERS, $request->getHeaders());
    $tracer->startSpan('my_span', [
        'child_of' => $spanContext,
    ]); 

刷新 Span

PHP 作为请求作用域的语言没有简单的方法在阻塞主请求线程/进程的情况下将收集到的 Span 数据传递给后台进程。OpenTracing API 对此没有假设,但对于 PHP 这可能导致 Tracer 实现出现问题。这就是为什么 PHP API 包含一个 `flush` 方法,允许触发一个将 Span 发送到进程外的方法。

use OpenTracing\GlobalTracer;

// Do application work, buffer spans in memory
$application->run();

fastcgi_finish_request();

$tracer = GlobalTracer::get();
$tracer->flush(); // release buffer to backend

这是可选的,tracer 可以决定立即将完成的 Span 发送到后端。flush 调用可以对这些 tracer 实现为 NO-OP。

使用 Span 选项

传递选项可以使用数组或 SpanOptions 包装对象。以下键是有效的

  • start_time 是一个浮点数、整数或代表任意精度时间戳的 \DateTime
  • child_of 是类型为 OpenTracing\SpanContextOpenTracing\Span 的对象。
  • referencesOpenTracing\Reference 的数组。
  • tags 是键为字符串、值为标量的数组,代表 OpenTracing 标签。
$span = $tracer->createSpan('my_span', [
    'child_of' => $spanContext,
    'tags' => ['foo' => 'bar'],
    'start_time' => time(),
]);

传播格式

传播格式应该在所有 tracer 中一致实现。如果你想要实现自己的格式,那么不要重用现有的常量。如果请求的格式没有被 tracers 处理,它们将抛出异常。

  • Tracer::FORMAT_TEXT_MAP 应该表示 span context 作为键值映射。没有关于上下文来自哪里和发送到哪里的语义假设。

  • Tracer::FORMAT_HTTP_HEADERS 应该表示 span context 作为数组列表中的 HTTP 头部行。对于两个上下文详细信息 "Span-Id" 和 "Trace-Id",结果将是 ['Span-Id: abc123', 'Trace-Id: def456']。这个定义可以直接传递给 curlfile_get_contents

  • Tracer::FORMAT_BINARY 对数据格式没有假设,除了它是专有的,每个 tracer 可以按自己的方式处理它。

编码风格

OpenTracing PHP 遵循 PSR-2 编码规范和 PSR-4 自动加载规范。