openzipkin / zipkin
PHP 的 Zipkin 仪表化
Requires
- php: ^7.4 || ^8.0
- ext-curl: *
- psr/http-message: ~1.0 || ~2.0
- psr/log: ^1.0 || ^2.0 || ^3.0
Requires (Dev)
- ext-mysqli: *
- jcchavezs/httptest: ~0.2
- middlewares/fast-route: ^2.0
- middlewares/request-handler: ^2.0
- nyholm/psr7: ^1.4
- phpspec/prophecy-phpunit: ^2.0
- phpstan/phpstan: ^0.12.26
- phpunit/phpunit: ~9
- psr/http-client: ^1.0
- psr/http-server-middleware: ^1.0
- squizlabs/php_codesniffer: 3.*
Suggests
- ext-mysqli: Allows to use mysqli instrumentation.
- psr/http-client: Allows to instrument HTTP clients following PSR18.
- psr/http-server-middleware: Allows to instrument HTTP servers via middlewares following PSR15.
- dev-master
- 3.2.0
- 3.1.0
- 3.0.0
- 3.0.0-rc.2
- 3.0.0-rc.1
- v2.x-dev
- 2.0.2
- 2.0.1
- 2.0.0
- 2.0.0-beta1
- v1.x-dev
- 1.3.6
- 1.3.5
- 1.3.4
- 1.3.3
- 1.3.2
- 1.3.1
- 1.3.0
- 1.2.4
- 1.2.3
- 1.2.2
- 1.2.1
- 1.2.0
- 1.1.1
- 1.1.0
- 1.0.2
- 1.0.1
- 1.0.0
- 1.0.0-beta7
- 1.0.0-beta6
- 1.0.0-beta5
- 1.0.0-beta4
- 1.0.0-beta3
- 1.0.0-beta2
- 1.0.0-beta1
- dev-fixes_coverage
- dev-fixes_coveralls
- dev-adds_instrumentation_mysqli
- dev-php8_1
- dev-uses_unknown_servicename_2
- dev-uses_unknown_servicename
- dev-aggregated_reporting
- dev-ci_coveralls
- dev-php_8
- dev-tweaks_coverage
- dev-github_actions
- dev-php8
- dev-adds_header_license
- dev-adds_laravel
This package is auto-updated.
Last update: 2024-08-28 23:32:51 UTC
README
Zipkin PHP 是 Zipkin 的官方 PHP 跟踪实现,由 OpenZipkin 社区支持。
安装
composer require openzipkin/zipkin
设置
use Zipkin\Annotation; use Zipkin\Endpoint; use Zipkin\Samplers\BinarySampler; use Zipkin\TracingBuilder; use Zipkin\Reporters\Http; // First we create the endpoint that describes our service $endpoint = Endpoint::create('my_service'); $reporter = new Http(['endpoint_url' => 'http://myzipkin:9411/api/v2/spans']); $sampler = BinarySampler::createAsAlwaysSample(); $tracing = TracingBuilder::create() ->havingLocalEndpoint($endpoint) ->havingSampler($sampler) ->havingReporter($reporter) ->build(); $tracer = $tracing->getTracer(); ... $tracer->flush();
注意 要获取更完整的客户端/服务器端示例,请查看 此存储库。
跟踪
跟踪器创建并连接跨度,以模拟可能分布式工作的延迟。它可以采用采样来减少过程开销或将发送到 Zipkin 的数据量减少。
跟踪器返回的跨度在完成后向 Zipkin 报告数据,或在不采样的情况下不执行任何操作。在启动跨度后,您可以注释感兴趣的事件或添加包含详细信息和查找键的标签。
跨度具有上下文,包括放置在表示分布式操作的树中正确位置的跟踪标识符。
本地跟踪
在跟踪本地代码时,只需在跨度内运行即可。
$span = $tracer->newTrace(); $span->setName('encode'); $span->start(); try { doSomethingExpensive(); } finally { $span->finish(); }
在上面的示例中,跨度是跟踪的根。在许多情况下,您将是现有跟踪的一部分。在这种情况下,请调用 newChild
而不是 newTrace
。
$span = $tracer->newChild($root->getContext()); $span->setName('encode'); $span->start(); try { doSomethingExpensive(); } finally { $span->finish(); }
自定义跨度
一旦您有一个跨度,您就可以向它添加标签,这些标签可以用作查找键或详细信息。例如,您可能添加一个包含您的运行时版本的标签。
$span->tag('http.status_code', '200');
RPC 跟踪
RPC 跟踪通常由拦截器自动执行。在幕后,它们添加与它们在 RPC 操作中作用相关的标签和事件。
以下是一个客户端跨度示例
// before you send a request, add metadata that describes the operation $span = $tracer->newTrace(); $span->setName('get'); $span->setKind(Kind\CLIENT); $span->tag('http.status_code', '200'); $span->tag(Tags\HTTP_PATH, '/api'); $span->setRemoteEndpoint(Endpoint::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(Annotation\WIRE_SEND); $span->annotate(Annotation\WIRE_RECV); // when the response is complete, finish the span $span->finish();
采样
采样可以用来减少收集和报告的过程中的数据量。当跨度未采样时,它不会增加开销(空操作)。
采样是一个 upfront 决定,这意味着在跟踪中的第一个操作中做出报告数据的决定,并且该决定会向下传递。
默认情况下,有一个全局采样器,将单个比率应用于所有跟踪操作。 Sampler
是如何表示的,它默认为跟踪每个请求。
自定义采样
您可能希望根据操作的性质应用不同的策略。例如,您可能不希望跟踪对静态资源(如图像)的请求,或者您可能希望跟踪对新 API 的所有请求。
大多数用户将使用框架拦截器来自动化此类策略。以下是它们可能如何内部工作的示例。
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); }
传播
传播是必需的,以确保源自同一根的活动被收集在一起并放入相同的跟踪中。最常用的传播方法是将跟踪上下文从发送 RPC 请求的客户机复制到接收它的服务器。
例如,当一个下游 Http 调用被发起时,它的跟踪上下文会随请求一起发送,并以请求头的形式编码。
Client Span Server Span
┌──────────────────┐ ┌──────────────────┐
│ │ │ │
│ TraceContext │ Http Request Headers │ TraceContext │
│ ┌──────────────┐ │ ┌───────────────────┐ │ ┌──────────────┐ │
│ │ TraceId │ │ │ X-B3-TraceId │ │ │ TraceId │ │
│ │ │ │ │ │ │ │ │ │
│ │ ParentSpanId │ │ Extract │ X-B3-ParentSpanId │ Inject │ │ ParentSpanId │ │
│ │ ├─┼─────────>│ ├────────┼>│ │ │
│ │ SpanId │ │ │ X-B3-SpanId │ │ │ SpanId │ │
│ │ │ │ │ │ │ │ │ │
│ │ Sampled │ │ │ X-B3-Sampled │ │ │ Sampled │ │
│ └──────────────┘ │ └───────────────────┘ │ └──────────────┘ │
│ │ │ │
└──────────────────┘ └──────────────────┘
上面的名称来自 B3 Propagation,它是 Brave 的内置功能,并在许多语言和框架中都有实现。
大多数用户将使用框架拦截器来自动化传播。以下是它们可能如何内部工作的示例。
以下是客户端传播可能的样子
// 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($span->getContext(), $request);
以下是服务器端传播可能的样子
// configure a function that extracts the trace context from a request $extractor = $tracing->getPropagation()->getExtractor(new RequestHeaders); $extracted = $extractor($request); $span = $tracer->newChild($extracted); $span->setKind(Kind\SERVER);
如果您没有使用框架或无法访问 Request 对象,您可以从 $_SERVER 变量中提取上下文。
$extractor = $tracing->getPropagation()->getExtractor(new ServerHeaders); $extracted = $extractor($_SERVER);
提取传播上下文
Extractor
从传入的请求或消息中读取跟踪标识符和采样状态。载体通常是请求对象或头部。
SamplingFlags|TraceContext
通常仅在$tracer->newChild(extracted)
中使用,除非你在客户端和服务器之间共享跨度ID。
实现传播
Extractor
将输出一个包含以下之一的SamplingFlags|TraceContext
:
- 如果存在跟踪和跨度ID,则为
TraceContext
。 - 如果没有标识符,则为
SamplingFlags
。
当前跨度
Zipkin支持“当前跨度”概念,表示正在进行的操作。Tracer::currentSpan()
可用于向跨度添加自定义标签,而Tracer::nextSpan()
可用于创建任何正在进行的活动的子跨度。
当前跨度的常见用例是用于监控RPC客户端。例如
/** * 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, (string) $response->getStatusCode()); return $response; catch (Throwable $e) { $span->setError($e); throw $e; } finally { $span->finish(); } } }
手动设置作用域内的跨度
在编写新的监控代码时,将创建的跨度放置在作用域内作为当前跨度是很重要的。
在边缘情况下,您可能需要临时清除当前跨度。例如,启动一个不应与当前请求关联的任务。为此,只需将null传递给openScope
。
监控
测试
可以通过以下方式运行测试:
composer test
而静态检查可以通过以下方式运行:
composer static-check