From 6b908fd3a935e2e66c1b301647beea0c3e400e5c Mon Sep 17 00:00:00 2001 From: Christian Daguerre Date: Fri, 20 Dec 2024 10:17:11 +0100 Subject: [PATCH] feat: allow passing request and response callbacks --- src/Http/TracedResponse.php | 9 +++---- src/Http/TracingHttpClient.php | 43 ++++++++-------------------------- 2 files changed, 13 insertions(+), 39 deletions(-) diff --git a/src/Http/TracedResponse.php b/src/Http/TracedResponse.php index ea33d16..fb6650c 100644 --- a/src/Http/TracedResponse.php +++ b/src/Http/TracedResponse.php @@ -158,17 +158,14 @@ protected function endTracing(): void } try { - if (\in_array('response.headers', $info['user_data']['span_attributes'] ?? [])) { - $this->span->setAttribute('response.headers', HttpMessageHelper::formatHeadersForSpanAttribute($this->getHeaders(false))); - } - - if (\in_array('response.body', $info['user_data']['span_attributes'] ?? [])) { + if (\is_callable($info['user_data']['on_response'] ?? null)) { if (empty($this->content)) { $stream = $this->toStream(false); $this->content = stream_get_contents($stream) ?: null; rewind($stream); } - $this->span->setAttribute('response.body', $this->content); + + \call_user_func($info['user_data']['on_response'], $this->getHeaders(false), $this->content, $this->span); } } catch (\Throwable) { } diff --git a/src/Http/TracingHttpClient.php b/src/Http/TracingHttpClient.php index bd0fb20..c358772 100644 --- a/src/Http/TracingHttpClient.php +++ b/src/Http/TracingHttpClient.php @@ -14,6 +14,7 @@ use Instrumentation\Semantics\OperationName\ClientRequestOperationNameResolver; use Instrumentation\Semantics\OperationName\ClientRequestOperationNameResolverInterface; use Instrumentation\Tracing\Tracing; +use OpenTelemetry\API\Trace\SpanInterface; use OpenTelemetry\API\Trace\SpanKind; use OpenTelemetry\API\Trace\StatusCode; use OpenTelemetry\SDK\Common\Time\ClockInterface; @@ -56,34 +57,15 @@ public function __construct( $this->attributeProvider = $attributeProvider ?: new ClientRequestAttributeProvider(); } - /** - * @param array $attributes - * - * @return array - */ - protected function getExtraSpanAttributes(array|null $attributes): array - { - $attributes = $attributes ?: $_SERVER['OTEL_PHP_HTTP_SPAN_ATTRIBUTES'] ?? []; - - if (\is_string($attributes)) { - $attributes = explode(',', $attributes); - } - - if (!\is_array($attributes)) { - throw new \RuntimeException(\sprintf('Extra span attributes must be a comma separated list of attributes or an array. %s given.', get_debug_type($attributes))); - } - - return $attributes; - } - /** * @param array{ * on_progress?: ?callable, * headers?: array>, * extra?: array{ * operation_name: non-empty-string, - * span_attributes: array, - * extra_attributes: array + * extra_attributes: array, + * on_request: callable(array>, string|null, SpanInterface): void, + * on_response: callable(array>, string|null, SpanInterface): void, * } * } $options */ @@ -106,22 +88,17 @@ public function request(string $method, string $url, array $options = []): Respo $attributes = $this->attributeProvider->getAttributes($method, $url, $headers); $attributes += $options['extra']['extra_attributes'] ?? []; + $span->setAttributes($attributes); $scope->detach(); - $options['user_data']['span_attributes'] = $this->getExtraSpanAttributes($options['extra']['span_attributes'] ?? null); - - try { - if (\in_array('request.body', $options['user_data']['span_attributes']) && $body = self::getRequestBody($options)) { - $attributes['request.body'] = $body; - } - if (\in_array('request.headers', $options['user_data']['span_attributes'])) { - $attributes['request.headers'] = HttpMessageHelper::formatHeadersForSpanAttribute($headers); - } - } catch (\Throwable) { + if (\is_callable($options['extra']['on_request'] ?? null)) { + \call_user_func($options['extra']['on_request'], $headers, self::getRequestBody($options), $span); } - $span->setAttributes($attributes); + if (isset($options['extra']['on_response'])) { + $options['user_data']['on_response'] = $options['extra']['on_response']; + } $options = array_merge($options, [ 'on_progress' => function ($dlNow, $dlSize, $info) use ($onProgress, $span, $options) {