diff --git a/src/Propagation/ResponsePropagator/.gitattributes b/src/Propagation/ResponsePropagator/.gitattributes new file mode 100644 index 00000000..1676cf82 --- /dev/null +++ b/src/Propagation/ResponsePropagator/.gitattributes @@ -0,0 +1,12 @@ +* text=auto + +*.md diff=markdown +*.php diff=php + +/.gitattributes export-ignore +/.gitignore export-ignore +/.php-cs-fixer.php export-ignore +/phpstan.neon.dist export-ignore +/phpunit.xml.dist export-ignore +/psalm.xml.dist export-ignore +/tests export-ignore diff --git a/src/Propagation/ResponsePropagator/.gitignore b/src/Propagation/ResponsePropagator/.gitignore new file mode 100644 index 00000000..57872d0f --- /dev/null +++ b/src/Propagation/ResponsePropagator/.gitignore @@ -0,0 +1 @@ +/vendor/ diff --git a/src/Propagation/ResponsePropagator/.php-cs-fixer.php b/src/Propagation/ResponsePropagator/.php-cs-fixer.php new file mode 100644 index 00000000..248b4b9a --- /dev/null +++ b/src/Propagation/ResponsePropagator/.php-cs-fixer.php @@ -0,0 +1,43 @@ +exclude('vendor') + ->exclude('var/cache') + ->in(__DIR__); + +$config = new PhpCsFixer\Config(); +return $config->setRules([ + 'concat_space' => ['spacing' => 'one'], + 'declare_equal_normalize' => ['space' => 'none'], + 'is_null' => true, + 'modernize_types_casting' => true, + 'ordered_imports' => true, + 'php_unit_construct' => true, + 'single_line_comment_style' => true, + 'yoda_style' => false, + '@PSR2' => true, + 'array_syntax' => ['syntax' => 'short'], + 'blank_line_after_opening_tag' => true, + 'blank_line_before_statement' => true, + 'cast_spaces' => true, + 'declare_strict_types' => true, + 'function_typehint_space' => true, + 'include' => true, + 'lowercase_cast' => true, + 'new_with_braces' => true, + 'no_extra_blank_lines' => true, + 'no_leading_import_slash' => true, + 'echo_tag_syntax' => true, + 'no_unused_imports' => true, + 'no_useless_else' => true, + 'no_useless_return' => true, + 'phpdoc_order' => true, + 'phpdoc_scalar' => true, + 'phpdoc_types' => true, + 'short_scalar_cast' => true, + 'single_blank_line_before_namespace' => true, + 'single_quote' => true, + 'trailing_comma_in_multiline' => true, + ]) + ->setRiskyAllowed(true) + ->setFinder($finder); + diff --git a/src/Propagation/ResponsePropagator/README.md b/src/Propagation/ResponsePropagator/README.md new file mode 100644 index 00000000..8789ba94 --- /dev/null +++ b/src/Propagation/ResponsePropagator/README.md @@ -0,0 +1,65 @@ +[![Releases](https://img.shields.io/badge/releases-purple)](https://github.com/opentelemetry-php/contrib-propagator-traceresponse/releases) +[![Issues](https://img.shields.io/badge/issues-pink)](https://github.com/open-telemetry/opentelemetry-php/issues) +[![Source](https://img.shields.io/badge/source-contrib-green)](https://github.com/open-telemetry/opentelemetry-php-contrib/tree/main/src/Propagation/TraceResponse) +[![Mirror](https://img.shields.io/badge/mirror-opentelemetry--php--contrib-blue)](https://github.com/opentelemetry-php/contrib-propagator-traceresponse) +[![Latest Version](http://poser.pugx.org/open-telemetry/opentelemetry-propagation-traceresponse/v/unstable)](https://packagist.org/packages/open-telemetry/opentelemetry-propagation-traceresponse/) +[![Stable](http://poser.pugx.org/open-telemetry/opentelemetry-propagation-traceresponse/v/stable)](https://packagist.org/packages/open-telemetry/opentelemetry-propagation-traceresponse/) + +This is a read-only subtree split of https://github.com/open-telemetry/opentelemetry-php-contrib. + +# OpenTelemetry TraceResponse Propagator + +**Note:** This package is experimental as `traceresponse` is currently an editors' draft. + +This package provides a [Trace Context HTTP Response Headers Format](https://w3c.github.io/trace-context/#trace-context-http-response-headers-format) +propagator to inject the current span context into Response datastructures. + +The main goal is to allow client-side technology (Real User Monitoring, HTTP Clients) to record +the server side context in order to allow referencing it. + +## Requirements + +* OpenTelemetry SDK and exporters (required to actually export traces) + +Optional: +* OpenTelemetry extension (Some instrumentations can automatically use the `TraceResponsePropagator`) + +## Usage + +Assuming there is an active `SpanContext`, you can inject it into your response as follows: + +```php +// your framework probably provides a datastructure to model HTTP responses +// and allows you to hook into the end of a request / listen to a matching event. +$response = new Response(); + +// get the current scope, bail out if none +$scope = Context::storage()->scope(); +if (null === $scope) { + return; +} + +// create a PropagationSetterInterface that knows how to inject response headers +$propagationSetter = new class implements OpenTelemetry\Context\Propagation\PropagationSetterInterface { + public function set(&$carrier, string $key, string $value) : void { + $carrier->headers->set($key, $value); + } +}; +$propagator = new TraceResponseProgator(); +$propagator->inject($response, $propagationSetter, $scope->context()); +``` + +## Installation via composer + +```bash +$ composer require open-telemetry/opentelemetry-propagation-traceresponse +``` + +## Installing dependencies and executing tests + +From TraceResponse subdirectory: + +```bash +$ composer install +$ ./vendor/bin/phpunit tests +``` diff --git a/src/Propagation/ResponsePropagator/composer.json b/src/Propagation/ResponsePropagator/composer.json new file mode 100644 index 00000000..4674b8de --- /dev/null +++ b/src/Propagation/ResponsePropagator/composer.json @@ -0,0 +1,39 @@ +{ + "name": "open-telemetry/opentelemetry-propagation-response", + "description": "OpenTelemetry response propagator api", + "keywords": ["opentelemetry", "otel", "open-telemetry", "propagator", "response"], + "type": "library", + "homepage": "https://opentelemetry.io/docs/php", + "readme": "./README.md", + "license": "Apache-2.0", + "minimum-stability": "dev", + "prefer-stable": true, + "require": { + "php": "^7.0|^8.0", + "open-telemetry/context": "^1.0" + }, + "autoload": { + "psr-4": { + "OpenTelemetry\\Contrib\\Propagation\\Response\\": "src/" + } + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3", + "phan/phan": "^5.0", + "phpstan/phpstan": "^1.1", + "phpstan/phpstan-phpunit": "^1.0", + "psalm/plugin-phpunit": "^0.16", + "open-telemetry/sdk": "^1.0", + "phpunit/phpunit": "^9.5", + "vimeo/psalm": "^4.0", + "symfony/http-client": "^5.4|^6.0", + "guzzlehttp/promises": "^1.5", + "php-http/message-factory": "^1.0", + "nyholm/psr7": "^1.5" + }, + "config": { + "allow-plugins": { + "php-http/discovery": true + } + } +} diff --git a/src/Propagation/ResponsePropagator/phpstan.neon.dist b/src/Propagation/ResponsePropagator/phpstan.neon.dist new file mode 100644 index 00000000..ed94c13d --- /dev/null +++ b/src/Propagation/ResponsePropagator/phpstan.neon.dist @@ -0,0 +1,9 @@ +includes: + - vendor/phpstan/phpstan-phpunit/extension.neon + +parameters: + tmpDir: var/cache/phpstan + level: 5 + paths: + - src + - tests diff --git a/src/Propagation/ResponsePropagator/phpunit.xml.dist b/src/Propagation/ResponsePropagator/phpunit.xml.dist new file mode 100644 index 00000000..44d976f6 --- /dev/null +++ b/src/Propagation/ResponsePropagator/phpunit.xml.dist @@ -0,0 +1,44 @@ + + + + + + + src + + + + + + + + + + + + + tests/Unit + + + + diff --git a/src/Propagation/ResponsePropagator/psalm.xml.dist b/src/Propagation/ResponsePropagator/psalm.xml.dist new file mode 100644 index 00000000..15571171 --- /dev/null +++ b/src/Propagation/ResponsePropagator/psalm.xml.dist @@ -0,0 +1,15 @@ + + + + + + + + + + diff --git a/src/Propagation/TraceResponse/src/ResponsePropagator.php b/src/Propagation/ResponsePropagator/src/ResponsePropagator.php similarity index 92% rename from src/Propagation/TraceResponse/src/ResponsePropagator.php rename to src/Propagation/ResponsePropagator/src/ResponsePropagator.php index aedd8697..e6d93abf 100644 --- a/src/Propagation/TraceResponse/src/ResponsePropagator.php +++ b/src/Propagation/ResponsePropagator/src/ResponsePropagator.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace OpenTelemetry\Contrib\Propagation\TraceResponse; +namespace OpenTelemetry\Contrib\Propagation\Response; use OpenTelemetry\Context\ContextInterface; use OpenTelemetry\Context\Propagation\PropagationSetterInterface; diff --git a/src/Propagation/ResponsePropagator/tests/Unit/PropagatorTest.php b/src/Propagation/ResponsePropagator/tests/Unit/PropagatorTest.php new file mode 100644 index 00000000..9c103c5d --- /dev/null +++ b/src/Propagation/ResponsePropagator/tests/Unit/PropagatorTest.php @@ -0,0 +1,125 @@ +assertSame($propagator->fields(), [Propagator::TRACERESPONSE]); + } + + /** + * @test + * Injects with a valid traceId, spanId, and is sampled + * restore(string $traceId, string $spanId, bool $sampled = false, bool $isRemote = false, ?API\TraceState $traceState = null): SpanContext + */ + public function test_inject_valid_sampled_trace_id() + { + $carrier = []; + (new Propagator())->inject( + $carrier, + null, + $this->withSpanContext( + SpanContext::create(self::TRACE_ID, self::SPAN_ID, TraceFlags::SAMPLED), + Context::getCurrent() + ) + ); + + $this->assertSame( + [Propagator::TRACERESPONSE => self::TRACERESPONSE_HEADER_SAMPLED], + $carrier + ); + } + + /** + * @test + * Injects with a valid traceId, spanId, and is not sampled + */ + public function test_inject_valid_not_sampled_trace_id() + { + $carrier = []; + (new Propagator())->inject( + $carrier, + null, + $this->withSpanContext( + SpanContext::create(self::TRACE_ID, self::SPAN_ID), + Context::getCurrent() + ) + ); + + $this->assertSame( + [Propagator::TRACERESPONSE => self::TRACERESPONSE_HEADER_NOT_SAMPLED], + $carrier + ); + } + + /** + * @test + * Test inject with tracestate - note: tracestate is not a part of traceresponse + */ + public function test_inject_trace_id_with_trace_state() + { + $carrier = []; + (new Propagator())->inject( + $carrier, + null, + $this->withSpanContext( + SpanContext::create(self::TRACE_ID, self::SPAN_ID, TraceFlags::SAMPLED, new TraceState('vendor1=opaqueValue1')), + Context::getCurrent() + ) + ); + + $this->assertSame( + [Propagator::TRACERESPONSE => self::TRACERESPONSE_HEADER_SAMPLED], + $carrier + ); + } + + /** + * @test + * Test with an invalid spanContext, should return null + */ + public function test_inject_trace_id_with_invalid_span_context() + { + $carrier = []; + (new Propagator())->inject( + $carrier, + null, + $this->withSpanContext( + SpanContext::create(SpanContextValidator::INVALID_TRACE, SpanContextValidator::INVALID_SPAN, TraceFlags::SAMPLED, new TraceState('vendor1=opaqueValue1')), + Context::getCurrent() + ) + ); + + $this->assertEmpty($carrier); + } + + private function withSpanContext(SpanContextInterface $spanContext, ContextInterface $context): ContextInterface + { + return $context->withContextValue(Span::wrap($spanContext)); + } +} diff --git a/src/Propagation/ServerTiming/.gitattributes b/src/Propagation/ServerTiming/.gitattributes new file mode 100644 index 00000000..1676cf82 --- /dev/null +++ b/src/Propagation/ServerTiming/.gitattributes @@ -0,0 +1,12 @@ +* text=auto + +*.md diff=markdown +*.php diff=php + +/.gitattributes export-ignore +/.gitignore export-ignore +/.php-cs-fixer.php export-ignore +/phpstan.neon.dist export-ignore +/phpunit.xml.dist export-ignore +/psalm.xml.dist export-ignore +/tests export-ignore diff --git a/src/Propagation/ServerTiming/.gitignore b/src/Propagation/ServerTiming/.gitignore new file mode 100644 index 00000000..57872d0f --- /dev/null +++ b/src/Propagation/ServerTiming/.gitignore @@ -0,0 +1 @@ +/vendor/ diff --git a/src/Propagation/ServerTiming/.php-cs-fixer.php b/src/Propagation/ServerTiming/.php-cs-fixer.php new file mode 100644 index 00000000..248b4b9a --- /dev/null +++ b/src/Propagation/ServerTiming/.php-cs-fixer.php @@ -0,0 +1,43 @@ +exclude('vendor') + ->exclude('var/cache') + ->in(__DIR__); + +$config = new PhpCsFixer\Config(); +return $config->setRules([ + 'concat_space' => ['spacing' => 'one'], + 'declare_equal_normalize' => ['space' => 'none'], + 'is_null' => true, + 'modernize_types_casting' => true, + 'ordered_imports' => true, + 'php_unit_construct' => true, + 'single_line_comment_style' => true, + 'yoda_style' => false, + '@PSR2' => true, + 'array_syntax' => ['syntax' => 'short'], + 'blank_line_after_opening_tag' => true, + 'blank_line_before_statement' => true, + 'cast_spaces' => true, + 'declare_strict_types' => true, + 'function_typehint_space' => true, + 'include' => true, + 'lowercase_cast' => true, + 'new_with_braces' => true, + 'no_extra_blank_lines' => true, + 'no_leading_import_slash' => true, + 'echo_tag_syntax' => true, + 'no_unused_imports' => true, + 'no_useless_else' => true, + 'no_useless_return' => true, + 'phpdoc_order' => true, + 'phpdoc_scalar' => true, + 'phpdoc_types' => true, + 'short_scalar_cast' => true, + 'single_blank_line_before_namespace' => true, + 'single_quote' => true, + 'trailing_comma_in_multiline' => true, + ]) + ->setRiskyAllowed(true) + ->setFinder($finder); + diff --git a/src/Propagation/ServerTiming/README.md b/src/Propagation/ServerTiming/README.md new file mode 100644 index 00000000..8789ba94 --- /dev/null +++ b/src/Propagation/ServerTiming/README.md @@ -0,0 +1,65 @@ +[![Releases](https://img.shields.io/badge/releases-purple)](https://github.com/opentelemetry-php/contrib-propagator-traceresponse/releases) +[![Issues](https://img.shields.io/badge/issues-pink)](https://github.com/open-telemetry/opentelemetry-php/issues) +[![Source](https://img.shields.io/badge/source-contrib-green)](https://github.com/open-telemetry/opentelemetry-php-contrib/tree/main/src/Propagation/TraceResponse) +[![Mirror](https://img.shields.io/badge/mirror-opentelemetry--php--contrib-blue)](https://github.com/opentelemetry-php/contrib-propagator-traceresponse) +[![Latest Version](http://poser.pugx.org/open-telemetry/opentelemetry-propagation-traceresponse/v/unstable)](https://packagist.org/packages/open-telemetry/opentelemetry-propagation-traceresponse/) +[![Stable](http://poser.pugx.org/open-telemetry/opentelemetry-propagation-traceresponse/v/stable)](https://packagist.org/packages/open-telemetry/opentelemetry-propagation-traceresponse/) + +This is a read-only subtree split of https://github.com/open-telemetry/opentelemetry-php-contrib. + +# OpenTelemetry TraceResponse Propagator + +**Note:** This package is experimental as `traceresponse` is currently an editors' draft. + +This package provides a [Trace Context HTTP Response Headers Format](https://w3c.github.io/trace-context/#trace-context-http-response-headers-format) +propagator to inject the current span context into Response datastructures. + +The main goal is to allow client-side technology (Real User Monitoring, HTTP Clients) to record +the server side context in order to allow referencing it. + +## Requirements + +* OpenTelemetry SDK and exporters (required to actually export traces) + +Optional: +* OpenTelemetry extension (Some instrumentations can automatically use the `TraceResponsePropagator`) + +## Usage + +Assuming there is an active `SpanContext`, you can inject it into your response as follows: + +```php +// your framework probably provides a datastructure to model HTTP responses +// and allows you to hook into the end of a request / listen to a matching event. +$response = new Response(); + +// get the current scope, bail out if none +$scope = Context::storage()->scope(); +if (null === $scope) { + return; +} + +// create a PropagationSetterInterface that knows how to inject response headers +$propagationSetter = new class implements OpenTelemetry\Context\Propagation\PropagationSetterInterface { + public function set(&$carrier, string $key, string $value) : void { + $carrier->headers->set($key, $value); + } +}; +$propagator = new TraceResponseProgator(); +$propagator->inject($response, $propagationSetter, $scope->context()); +``` + +## Installation via composer + +```bash +$ composer require open-telemetry/opentelemetry-propagation-traceresponse +``` + +## Installing dependencies and executing tests + +From TraceResponse subdirectory: + +```bash +$ composer install +$ ./vendor/bin/phpunit tests +``` diff --git a/src/Propagation/ServerTiming/composer.json b/src/Propagation/ServerTiming/composer.json new file mode 100644 index 00000000..cdd67174 --- /dev/null +++ b/src/Propagation/ServerTiming/composer.json @@ -0,0 +1,40 @@ +{ + "name": "open-telemetry/opentelemetry-propagation-server-timing", + "description": "OpenTelemetry server-timing propagator.", + "keywords": ["opentelemetry", "otel", "open-telemetry", "propagator", "server-timing"], + "type": "library", + "homepage": "https://opentelemetry.io/docs/php", + "readme": "./README.md", + "license": "Apache-2.0", + "minimum-stability": "dev", + "prefer-stable": true, + "require": { + "php": "^7.0|^8.0", + "open-telemetry/context": "^1.0", + "open-telemetry/opentelemetry-propagation-response": "*" + }, + "autoload": { + "psr-4": { + "OpenTelemetry\\Contrib\\Propagation\\ServerTiming\\": "src/" + } + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3", + "phan/phan": "^5.0", + "phpstan/phpstan": "^1.1", + "phpstan/phpstan-phpunit": "^1.0", + "psalm/plugin-phpunit": "^0.16", + "open-telemetry/sdk": "^1.0", + "phpunit/phpunit": "^9.5", + "vimeo/psalm": "^4.0", + "symfony/http-client": "^5.4|^6.0", + "guzzlehttp/promises": "^1.5", + "php-http/message-factory": "^1.0", + "nyholm/psr7": "^1.5" + }, + "config": { + "allow-plugins": { + "php-http/discovery": true + } + } +} diff --git a/src/Propagation/ServerTiming/phpstan.neon.dist b/src/Propagation/ServerTiming/phpstan.neon.dist new file mode 100644 index 00000000..ed94c13d --- /dev/null +++ b/src/Propagation/ServerTiming/phpstan.neon.dist @@ -0,0 +1,9 @@ +includes: + - vendor/phpstan/phpstan-phpunit/extension.neon + +parameters: + tmpDir: var/cache/phpstan + level: 5 + paths: + - src + - tests diff --git a/src/Propagation/ServerTiming/phpunit.xml.dist b/src/Propagation/ServerTiming/phpunit.xml.dist new file mode 100644 index 00000000..44d976f6 --- /dev/null +++ b/src/Propagation/ServerTiming/phpunit.xml.dist @@ -0,0 +1,44 @@ + + + + + + + src + + + + + + + + + + + + + tests/Unit + + + + diff --git a/src/Propagation/ServerTiming/psalm.xml.dist b/src/Propagation/ServerTiming/psalm.xml.dist new file mode 100644 index 00000000..15571171 --- /dev/null +++ b/src/Propagation/ServerTiming/psalm.xml.dist @@ -0,0 +1,15 @@ + + + + + + + + + + diff --git a/src/Propagation/ServerTiming/src/TraceResponsePropagator.php b/src/Propagation/ServerTiming/src/TraceResponsePropagator.php new file mode 100644 index 00000000..f11f969d --- /dev/null +++ b/src/Propagation/ServerTiming/src/TraceResponsePropagator.php @@ -0,0 +1,51 @@ +getContext(); + + if (!$spanContext->isValid()) { + return; + } + + $traceId = $spanContext->getTraceId(); + $spanId = $spanContext->getSpanId(); + + $samplingFlag = $spanContext->isSampled() ? self::IS_SAMPLED : self::NOT_SAMPLED; + + $header = self::SUPPORTED_VERSION . '-' . $traceId . '-' . $spanId . '-' . $samplingFlag; + $setter->set($carrier, self::TRACERESPONSE, $header); + } +} diff --git a/src/Propagation/ServerTiming/tests/Unit/PropagatorTest.php b/src/Propagation/ServerTiming/tests/Unit/PropagatorTest.php new file mode 100644 index 00000000..6c64eac0 --- /dev/null +++ b/src/Propagation/ServerTiming/tests/Unit/PropagatorTest.php @@ -0,0 +1,125 @@ +assertSame($propagator->fields(), [Propagator::TRACERESPONSE]); + } + + /** + * @test + * Injects with a valid traceId, spanId, and is sampled + * restore(string $traceId, string $spanId, bool $sampled = false, bool $isRemote = false, ?API\TraceState $traceState = null): SpanContext + */ + public function test_inject_valid_sampled_trace_id() + { + $carrier = []; + (new Propagator())->inject( + $carrier, + null, + $this->withSpanContext( + SpanContext::create(self::TRACE_ID, self::SPAN_ID, TraceFlags::SAMPLED), + Context::getCurrent() + ) + ); + + $this->assertSame( + [Propagator::TRACERESPONSE => self::TRACERESPONSE_HEADER_SAMPLED], + $carrier + ); + } + + /** + * @test + * Injects with a valid traceId, spanId, and is not sampled + */ + public function test_inject_valid_not_sampled_trace_id() + { + $carrier = []; + (new Propagator())->inject( + $carrier, + null, + $this->withSpanContext( + SpanContext::create(self::TRACE_ID, self::SPAN_ID), + Context::getCurrent() + ) + ); + + $this->assertSame( + [Propagator::TRACERESPONSE => self::TRACERESPONSE_HEADER_NOT_SAMPLED], + $carrier + ); + } + + /** + * @test + * Test inject with tracestate - note: tracestate is not a part of traceresponse + */ + public function test_inject_trace_id_with_trace_state() + { + $carrier = []; + (new Propagator())->inject( + $carrier, + null, + $this->withSpanContext( + SpanContext::create(self::TRACE_ID, self::SPAN_ID, TraceFlags::SAMPLED, new TraceState('vendor1=opaqueValue1')), + Context::getCurrent() + ) + ); + + $this->assertSame( + [Propagator::TRACERESPONSE => self::TRACERESPONSE_HEADER_SAMPLED], + $carrier + ); + } + + /** + * @test + * Test with an invalid spanContext, should return null + */ + public function test_inject_trace_id_with_invalid_span_context() + { + $carrier = []; + (new Propagator())->inject( + $carrier, + null, + $this->withSpanContext( + SpanContext::create(SpanContextValidator::INVALID_TRACE, SpanContextValidator::INVALID_SPAN, TraceFlags::SAMPLED, new TraceState('vendor1=opaqueValue1')), + Context::getCurrent() + ) + ); + + $this->assertEmpty($carrier); + } + + private function withSpanContext(SpanContextInterface $spanContext, ContextInterface $context): ContextInterface + { + return $context->withContextValue(Span::wrap($spanContext)); + } +} diff --git a/src/Propagation/TraceResponse/composer.json b/src/Propagation/TraceResponse/composer.json index 54464e2a..6075989a 100644 --- a/src/Propagation/TraceResponse/composer.json +++ b/src/Propagation/TraceResponse/composer.json @@ -10,7 +10,8 @@ "prefer-stable": true, "require": { "php": "^7.0|^8.0", - "open-telemetry/context": "^1.0" + "open-telemetry/context": "^1.0", + "open-telemetry/opentelemetry-propagation-response": "*" }, "autoload": { "psr-4": { diff --git a/src/Propagation/TraceResponse/src/TraceResponsePropagator.php b/src/Propagation/TraceResponse/src/TraceResponsePropagator.php index d9917312..3bbcf052 100644 --- a/src/Propagation/TraceResponse/src/TraceResponsePropagator.php +++ b/src/Propagation/TraceResponse/src/TraceResponsePropagator.php @@ -9,6 +9,7 @@ use OpenTelemetry\Context\ContextInterface; use OpenTelemetry\Context\Propagation\ArrayAccessGetterSetter; use OpenTelemetry\Context\Propagation\PropagationSetterInterface; +use OpenTelemetry\Contrib\Propagation\Response\ResponsePropagator; /** * Provides a ResponsePropagator for the Trace Context HTTP Response Headers Format