伝搬

PHP API のコンテキスト伝搬

コンテキスト伝搬により、シグナルは、生成される場所に関係なく、相互に関連付けることができます。 トレーシングに限定されませんが、コンテキスト伝搬により、トレースは、プロセスとネットワークの境界を越えて任意に分散されたサービス間で、システムに関する因果関係の情報を構築できます。

大多数のユースケースでは、OpenTelemetryをネイティブにサポートするライブラリまたは計装ライブラリが、自動的にサービス間でトレースコンテキストを伝搬します。 手動でコンテキストを伝搬する必要があるのは、まれなケースのみです。

詳細については、コンテキスト伝搬を参照してください。

伝搬は、サービスやプロセス間でデータを移動させる仕組みです。 トレーシングに限定されませんが、伝搬により、プロセス境界やネットワーク境界をまたいで任意に分散されたサービス間で、システムに関する因果関係の情報をトレースが構築できるようになります。

OpenTelemetry は、W3C Trace Context の HTTP ヘッダーを使用して、リモートサービスにコンテキストを伝搬するためのテキストベースの方法を提供します。

自動的なコンテキスト伝搬

一般的なフレームワーク、ライブラリ、PHP エクステンション向けの自動計装が用意されています。 それらの多くは受信および送信のコンテキスト伝搬を行い、レジストリまたは Packagist で見つけることができます。

受信リクエスト

コンテキスト伝搬は、以下の方法で自動的に処理できます。

  • サポートされている PHP フレームワーク(例: Laravel、Symfony、Slim)を、対応する自動計装パッケージとともに使用する
  • コード内で PSR-15RequestHandlerInterface を実装し、対応する自動計装パッケージとともに使用する
  • 実験的な自動ルートスパン機能を使用する

送信リクエスト

HTTP クライアントおよびインターフェイス向けの自動計装パッケージは、送信 HTTP リクエストに W3C tracecontext ヘッダーを自動的に注入します。

手動でのコンテキスト伝搬

計装ライブラリを使用してコンテキストを伝搬できないケースもあります。 サービス間通信に使用しているライブラリに合致する計装ライブラリが存在しない場合があります。 あるいは、計装ライブラリが存在していたとしても、それでは満たせない要件がある場合もあります。

コンテキストを手動で伝搬する必要がある場合は、コンテキスト API を使用してください。

次のスニペットは、送信 HTTP リクエストの例を示しています。

$request = new Request('GET', 'http://localhost:8080/resource');
$outgoing = $tracer->spanBuilder('/resource')->setSpanKind(SpanKind::CLIENT)->startSpan();
$outgoing->setAttribute(TraceAttributes::HTTP_METHOD, $request->getMethod());
$outgoing->setAttribute(TraceAttributes::HTTP_URL, (string) $request->getUri());

$carrier = [];
TraceContextPropagator::getInstance()->inject($carrier);
foreach ($carrier as $name => $value) {
    $request = $request->withAddedHeader($name, $value);
}
try {
    $response = $client->send($request);
} finally {
    $outgoing->end();
}

同様に、テキストベースのアプローチを使用して、受信リクエストから W3C Trace Context を読み取ります。 次の例は、受信 HTTP リクエストの処理を示しています。

$request = ServerRequestCreator::createFromGlobals();
$context = TraceContextPropagator::getInstance()->extract($request->getHeaders());
$root = $tracer->spanBuilder('HTTP ' . $request->getMethod())
    ->setStartTimestamp((int) ($request->getServerParams()['REQUEST_TIME_FLOAT'] * 1e9))
    ->setParent($context)
    ->setSpanKind(SpanKind::KIND_SERVER)
    ->startSpan();
$scope = $root->activate();
try {
    /* do stuff */
} finally {
    $root->end();
    $scope->detach();
}

次のステップ

伝搬についてさらに学ぶには、Propagators API 仕様を参照してください。