mix-plus / opentracing
PHP的OpenTracing API
Requires
- php: ^7.1 || ^8.0
Requires (Dev)
- phpstan/phpstan: ~0.12
- phpunit/phpunit: ^7.0 || ^9.0
- squizlabs/php_codesniffer: 3.*
This package is not auto-updated.
Last update: 2024-10-03 15:39:56 UTC
README
PHP库,用于OpenTracing的API。
必读
为了理解这个库,首先需要熟悉OpenTracing项目和规范。
安装
可以通过Composer安装OpenTracing-PHP
composer require opentracing/opentracing
用法
在使用此库时,实际上只需要关注几个关键抽象:Tracer::startActiveSpan
和Tracer::startSpan
方法、Span
接口、Scope
接口以及在引导时绑定Tracer
。以下是一些代码片段,展示了重要的使用案例
单例初始化
最简单的起点是设置全局tracer。尽可能早地做
use OpenTracing\GlobalTracer; GlobalTracer::set(new MyTracerImplementation());
根据现有的请求创建Span
要启动一个新的Span
,可以使用startSpan
方法。
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 the span $span->finish(); }
通过创建“根span”来启动新的跟踪
总是可以创建一个没有父span或其他因果引用的“根”Span
。
$span = $tracer->startSpan('my_first_span'); ... $span->finish();
活动Span和范围管理器
对于大多数使用场景,建议使用Tracer::startActiveSpan
函数来创建新的span。
以下是在PHP代码中线性、两层深的span树使用活动span的示例
// 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('https://php.ac.cn'); $scope->close();
当使用Tracer::startActiveSpan
函数时,底层的tracer使用一个名为范围管理器的抽象来跟踪当前活动的span。
启动活动span将始终使用当前活动的span作为父span。如果没有可用的父span,则新创建的span被认为是跟踪的根span。
除非您正在使用跟踪多个span的异步代码,例如在使用cURL Multi Exec或MySQLi Polling时,否则建议您在应用程序的每个地方都使用Tracer::startActiveSpan
。
当您调用$scope->close()
时,当前活动span会自动完成,如前面的示例所示。
如果您不希望在调用$scope->close()
时自动关闭span,则必须在startActiveSpan
的$options
参数中指定'finish_span_on_close'=> false,
。
手动指定父span创建子span
$parent = GlobalTracer::get()->startSpan('parent'); $child = GlobalTracer::get()->startSpan('child', [ 'child_of' => $parent ]); ... $child->finish(); ... $parent->finish();
使用自动活动span管理创建子span
每个新的span都将使用活动span作为父span,并将其放在适当的位置。
$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->close(); ... $parent->close();
序列化到传输线
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) { ... } ...
从传输线反序列化
当使用http头进行上下文传播时,您可以使用Request
或$_SERVER
变量。
use OpenTracing\GlobalTracer; use OpenTracing\Formats; $tracer = GlobalTracer::get(); $spanContext = $tracer->extract(Formats\HTTP_HEADERS, getallheaders()); $tracer->startSpan('my_span', [ 'child_of' => $spanContext, ]);
清除Span
PHP作为一种请求范围的语言,没有简单的方法在不阻塞主请求线程/进程的情况下将收集到的span数据传递给后台进程。OpenTracing API对此没有假设,但对于PHP来说,这可能会对tracer实现造成问题。这就是为什么PHP API包含一个flush
方法,允许触发将span发送到进程外。
use OpenTracing\GlobalTracer; $application->run(); register_shutdown_function(function() { /* Flush the tracer to the backend */ $tracer = GlobalTracer::get(); $tracer->flush(); });
这是可选的,tracer可以决定立即将已完成的span发送到后端。flush调用可以对这些tracer实现为NO-OP。
使用StartSpanOptions
传递选项可以通过数组或SpanOptions包装器对象实现。以下键是有效的
start_time
是一个浮点数、整数或\DateTime
,表示具有任意精度的时间戳。child_of
是类型为OpenTracing\SpanContext
或OpenTracing\Span
的对象。references
是一个OpenTracing\Reference
数组。tags
是一个带有字符串键和标量值的数组,代表 OpenTracing 标签。finish_span_on_close
是一个布尔值,用于确定当作用域关闭时是否应该完成跨度。
$span = $tracer->startActiveSpan('my_span', [ 'child_of' => $spanContext, 'tags' => ['foo' => 'bar'], 'start_time' => time(), ]);
传播格式
传播格式应在所有跟踪器中一致实现。如果您想实现自己的格式,则不要重用现有常量。如果请求的格式不被跟踪器处理,跟踪器将抛出异常。
-
Tracer::FORMAT_TEXT_MAP
应将跨度上下文表示为键值映射。没有关于上下文来源和发送到哪里的语义假设。 -
Tracer::FORMAT_HTTP_HEADERS
应将跨度上下文表示为数组列表中的 HTTP 头行。对于两个上下文详细信息 "Span-Id" 和 "Trace-Id",结果将是['Span-Id: abc123', 'Trace-Id: def456']
。这个定义可以直接传递给curl
和file_get_contents
。 -
Tracer::FORMAT_BINARY
对数据格式没有假设,除了它属于专有格式且每个跟踪器可以按自己的方式处理。
模拟实现
OpenTracing PHP 附带一个模拟实现,它有三个目的
- 帮助完善 API。
- 作为参考实现。
- 增强了无供应商单元测试,因为它允许开发者检查跟踪对象以便对他们进行断言。
编码风格
OpenTracing PHP 遵循 PSR-2 编码标准和 PSR-4 自动加载标准。
许可证
所有开源贡献均受 Apache-2.0 许可证 的约束。