[Server] Carry trace context through a request (#452)
traceparent, tracestate and baggage reach handlers through RequestContext and are echoed onto the notifications the request causes, so a span is not broken by the response stream. Passed through verbatim: what they mean is the tracing library's business, and no dependency is taken for it.
This commit is contained in:
parent
f6a995bc44
commit
855011b8dc
1 changed files with 141 additions and 1 deletions
|
|
@ -594,7 +594,7 @@ final class StatelessProtocol
|
|||
{
|
||||
try {
|
||||
while ($run->valid()) {
|
||||
yield $run->current()->jsonSerialize();
|
||||
yield self::withTraceContext($run->current()->jsonSerialize(), $meta->traceContext);
|
||||
|
||||
$run->next();
|
||||
}
|
||||
|
|
@ -654,6 +654,31 @@ final class StatelessProtocol
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts the request's trace context back onto a notification it caused, so a
|
||||
* collector can join the two without the handler carrying it by hand.
|
||||
*
|
||||
* @param array<string, mixed> $frame
|
||||
* @param array<string, string> $traceContext
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private static function withTraceContext(array $frame, array $traceContext): array
|
||||
{
|
||||
if ([] === $traceContext) {
|
||||
return $frame;
|
||||
}
|
||||
|
||||
$params = \is_array($frame['params'] ?? null) ? $frame['params'] : [];
|
||||
$frameMeta = \is_array($params['_meta'] ?? null) ? $params['_meta'] : [];
|
||||
|
||||
// Anything the notification set itself wins: it knows its own span.
|
||||
$params['_meta'] = [...$traceContext, ...$frameMeta];
|
||||
$frame['params'] = $params;
|
||||
|
||||
return $frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* The one place a handler's exception becomes an answer, so the streaming
|
||||
* and non-streaming paths cannot disagree about which code it earns.
|
||||
|
|
|
|||
Loading…
Reference in a new issue