From 82ef194b8c1b5a6de245fc2de17d39f2a29ef544 Mon Sep 17 00:00:00 2001 From: Jerry Leung Date: Thu, 11 Sep 2025 16:11:02 -0700 Subject: [PATCH 1/8] Revise contrib for response propagator --- .../src/CodeIgniterInstrumentation.php | 17 ++----------- .../Illuminate/Contracts/Http/Kernel.php | 17 ++----------- .../Slim/src/SlimInstrumentation.php | 13 ++-------- .../Symfony/src/SymfonyInstrumentation.php | 13 ++-------- .../Yii/src/YiiInstrumentation.php | 17 ++----------- src/Propagation/ServerTiming/_register.php | 15 ++++++++++++ src/Propagation/ServerTiming/composer.json | 5 +++- .../ServerTiming/src/ResponsePropagator.php | 24 ------------------- .../src/ServerTimingPropagator.php | 14 ++++++++++- src/Propagation/TraceResponse/_register.php | 15 ++++++++++++ src/Propagation/TraceResponse/composer.json | 5 +++- .../TraceResponse/src/ResponsePropagator.php | 24 ------------------- .../src/TraceResponsePropagator.php | 14 ++++++++++- 13 files changed, 74 insertions(+), 119 deletions(-) create mode 100644 src/Propagation/ServerTiming/_register.php delete mode 100644 src/Propagation/ServerTiming/src/ResponsePropagator.php create mode 100644 src/Propagation/TraceResponse/_register.php delete mode 100644 src/Propagation/TraceResponse/src/ResponsePropagator.php diff --git a/src/Instrumentation/CodeIgniter/src/CodeIgniterInstrumentation.php b/src/Instrumentation/CodeIgniter/src/CodeIgniterInstrumentation.php index 04acea57d..7d1c78368 100644 --- a/src/Instrumentation/CodeIgniter/src/CodeIgniterInstrumentation.php +++ b/src/Instrumentation/CodeIgniter/src/CodeIgniterInstrumentation.php @@ -128,21 +128,8 @@ public static function register(): void $span->setStatus(StatusCode::STATUS_ERROR); } - // Propagate server-timing header to response, if ServerTimingPropagator is present - if (class_exists('OpenTelemetry\Contrib\Propagation\ServerTiming\ServerTimingPropagator')) { - /** @phan-suppress-next-line PhanUndeclaredClassMethod */ - $prop = new \OpenTelemetry\Contrib\Propagation\ServerTiming\ServerTimingPropagator(); - /** @phan-suppress-next-line PhanUndeclaredClassMethod */ - $prop->inject($response, ResponsePropagationSetter::instance(), $scope->context()); - } - - // Propagate traceresponse header to response, if TraceResponsePropagator is present - if (class_exists('OpenTelemetry\Contrib\Propagation\TraceResponse\TraceResponsePropagator')) { - /** @phan-suppress-next-line PhanUndeclaredClassMethod */ - $prop = new \OpenTelemetry\Contrib\Propagation\TraceResponse\TraceResponsePropagator(); - /** @phan-suppress-next-line PhanUndeclaredClassMethod */ - $prop->inject($response, ResponsePropagationSetter::instance(), $scope->context()); - } + $prop = Globals::responsePropagator(); + $prop->inject($response, ResponsePropagationSetter::instance(), $scope->context()); } $controller = $controllerProperty->getValue($igniter); diff --git a/src/Instrumentation/Laravel/src/Hooks/Illuminate/Contracts/Http/Kernel.php b/src/Instrumentation/Laravel/src/Hooks/Illuminate/Contracts/Http/Kernel.php index bd564a9c6..806aa70ad 100644 --- a/src/Instrumentation/Laravel/src/Hooks/Illuminate/Contracts/Http/Kernel.php +++ b/src/Instrumentation/Laravel/src/Hooks/Illuminate/Contracts/Http/Kernel.php @@ -99,21 +99,8 @@ protected function hookHandle(): bool $span->setAttribute(TraceAttributes::NETWORK_PROTOCOL_VERSION, $response->getProtocolVersion()); $span->setAttribute(TraceAttributes::HTTP_RESPONSE_BODY_SIZE, $response->headers->get('Content-Length')); - // Propagate server-timing header to response, if ServerTimingPropagator is present - if (class_exists('OpenTelemetry\Contrib\Propagation\ServerTiming\ServerTimingPropagator')) { - /** @phan-suppress-next-line PhanUndeclaredClassMethod */ - $prop = new \OpenTelemetry\Contrib\Propagation\ServerTiming\ServerTimingPropagator(); - /** @phan-suppress-next-line PhanAccessMethodInternal,PhanUndeclaredClassMethod */ - $prop->inject($response, ResponsePropagationSetter::instance(), $scope->context()); - } - - // Propagate traceresponse header to response, if TraceResponsePropagator is present - if (class_exists('OpenTelemetry\Contrib\Propagation\TraceResponse\TraceResponsePropagator')) { - /** @phan-suppress-next-line PhanUndeclaredClassMethod */ - $prop = new \OpenTelemetry\Contrib\Propagation\TraceResponse\TraceResponsePropagator(); - /** @phan-suppress-next-line PhanAccessMethodInternal,PhanUndeclaredClassMethod */ - $prop->inject($response, ResponsePropagationSetter::instance(), $scope->context()); - } + $prop = Globals::responsePropagator(); + $prop->inject($response, ResponsePropagationSetter::instance(), $scope->context()); } $this->endSpan($exception); diff --git a/src/Instrumentation/Slim/src/SlimInstrumentation.php b/src/Instrumentation/Slim/src/SlimInstrumentation.php index 7c6adb946..1fddd4cc6 100644 --- a/src/Instrumentation/Slim/src/SlimInstrumentation.php +++ b/src/Instrumentation/Slim/src/SlimInstrumentation.php @@ -104,17 +104,8 @@ public static function register(): void $span->setAttribute(HttpIncubatingAttributes::HTTP_RESPONSE_BODY_SIZE, $response->getHeaderLine('Content-Length')); if (self::$supportsResponsePropagation) { - // Propagate server-timing header to response, if ServerTimingPropagator is present - if (class_exists('OpenTelemetry\Contrib\Propagation\ServerTiming\ServerTimingPropagator')) { - $prop = new \OpenTelemetry\Contrib\Propagation\ServerTiming\ServerTimingPropagator(); - $prop->inject($response, PsrResponsePropagationSetter::instance(), $scope->context()); - } - - // Propagate traceresponse header to response, if TraceResponsePropagator is present - if (class_exists('OpenTelemetry\Contrib\Propagation\TraceResponse\TraceResponsePropagator')) { - $prop = new \OpenTelemetry\Contrib\Propagation\TraceResponse\TraceResponsePropagator(); - $prop->inject($response, PsrResponsePropagationSetter::instance(), $scope->context()); - } + $prop = Globals::responsePropagator(); + $prop->inject($response, PsrResponsePropagationSetter::instance(), $scope->context()); } } $span->end(); diff --git a/src/Instrumentation/Symfony/src/SymfonyInstrumentation.php b/src/Instrumentation/Symfony/src/SymfonyInstrumentation.php index 4aea37588..68ebd1611 100644 --- a/src/Instrumentation/Symfony/src/SymfonyInstrumentation.php +++ b/src/Instrumentation/Symfony/src/SymfonyInstrumentation.php @@ -138,17 +138,8 @@ public static function register(): void $span->setAttribute(TraceAttributes::HTTP_RESPONSE_BODY_SIZE, $contentLength); - // Propagate server-timing header to response, if ServerTimingPropagator is present - if (class_exists('OpenTelemetry\Contrib\Propagation\ServerTiming\ServerTimingPropagator')) { - $prop = new \OpenTelemetry\Contrib\Propagation\ServerTiming\ServerTimingPropagator(); - $prop->inject($response, ResponsePropagationSetter::instance(), $scope->context()); - } - - // Propagate traceresponse header to response, if TraceResponsePropagator is present - if (class_exists('OpenTelemetry\Contrib\Propagation\TraceResponse\TraceResponsePropagator')) { - $prop = new \OpenTelemetry\Contrib\Propagation\TraceResponse\TraceResponsePropagator(); - $prop->inject($response, ResponsePropagationSetter::instance(), $scope->context()); - } + $prop = Globals::responsePropagator(); + $prop->inject($response, ResponsePropagationSetter::instance(), $scope->context()); $span->end(); } diff --git a/src/Instrumentation/Yii/src/YiiInstrumentation.php b/src/Instrumentation/Yii/src/YiiInstrumentation.php index 7be84d4aa..349dd5a6f 100644 --- a/src/Instrumentation/Yii/src/YiiInstrumentation.php +++ b/src/Instrumentation/Yii/src/YiiInstrumentation.php @@ -94,21 +94,8 @@ public static function register(): void $span->setStatus(StatusCode::STATUS_ERROR); } - // Propagate server-timing header to response, if ServerTimingPropagator is present - if (class_exists('OpenTelemetry\Contrib\Propagation\ServerTiming\ServerTimingPropagator')) { - /** @phan-suppress-next-line PhanUndeclaredClassMethod */ - $prop = new \OpenTelemetry\Contrib\Propagation\ServerTiming\ServerTimingPropagator(); - /** @phan-suppress-next-line PhanUndeclaredClassMethod */ - $prop->inject($response, ResponsePropagationSetter::instance(), $scope->context()); - } - - // Propagate traceresponse header to response, if TraceResponsePropagator is present - if (class_exists('OpenTelemetry\Contrib\Propagation\TraceResponse\TraceResponsePropagator')) { - /** @phan-suppress-next-line PhanUndeclaredClassMethod */ - $prop = new \OpenTelemetry\Contrib\Propagation\TraceResponse\TraceResponsePropagator(); - /** @phan-suppress-next-line PhanUndeclaredClassMethod */ - $prop->inject($response, ResponsePropagationSetter::instance(), $scope->context()); - } + $prop = Globals::responsePropagator(); + $prop->inject($response, ResponsePropagationSetter::instance(), $scope->context()); } if ($exception) { diff --git a/src/Propagation/ServerTiming/_register.php b/src/Propagation/ServerTiming/_register.php new file mode 100644 index 000000000..349d961d2 --- /dev/null +++ b/src/Propagation/ServerTiming/_register.php @@ -0,0 +1,15 @@ + Date: Fri, 19 Sep 2025 10:20:29 -0700 Subject: [PATCH 2/8] Bumped composer.json --- src/Instrumentation/CodeIgniter/composer.json | 8 ++- src/Instrumentation/Laravel/composer.json | 8 ++- src/Instrumentation/Slim/composer.json | 10 ++-- src/Instrumentation/Symfony/composer.json | 8 +-- .../SymfonyInstrumentationTest.php | 58 ------------------- src/Instrumentation/Yii/composer.json | 4 +- src/Propagation/ServerTiming/composer.json | 4 +- src/Propagation/TraceResponse/composer.json | 4 +- 8 files changed, 27 insertions(+), 77 deletions(-) diff --git a/src/Instrumentation/CodeIgniter/composer.json b/src/Instrumentation/CodeIgniter/composer.json index 5e5ff2ecc..f99c3f121 100644 --- a/src/Instrumentation/CodeIgniter/composer.json +++ b/src/Instrumentation/CodeIgniter/composer.json @@ -12,12 +12,16 @@ "php": "^8.1", "ext-opentelemetry": "*", "codeigniter4/framework": "^4.3", - "open-telemetry/api": "^1.0", + "open-telemetry/api": "^1.6", "open-telemetry/sem-conv": "^1.32" }, + "suggest": { + "open-telemetry/opentelemetry-propagation-server-timing": "Automatically propagate the context to the client through server-timing headers.", + "open-telemetry/opentelemetry-propagation-traceresponse": "Automatically propagate the context to the client through trace-response headers." + }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.50", - "open-telemetry/sdk": "^1.0", + "open-telemetry/sdk": "^1.8", "phan/phan": "^5.0", "php-http/mock-client": "*", "phpstan/phpstan": "^1.1", diff --git a/src/Instrumentation/Laravel/composer.json b/src/Instrumentation/Laravel/composer.json index f5a188aad..6375d293e 100644 --- a/src/Instrumentation/Laravel/composer.json +++ b/src/Instrumentation/Laravel/composer.json @@ -13,14 +13,18 @@ "ext-json": "*", "ext-opentelemetry": "*", "laravel/framework": "^6.0 || ^7.0 || ^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0", - "open-telemetry/api": "^1.0", + "open-telemetry/api": "^1.6", "open-telemetry/sem-conv": "^1.32" }, + "suggest": { + "open-telemetry/opentelemetry-propagation-server-timing": "Automatically propagate the context to the client through server-timing headers.", + "open-telemetry/opentelemetry-propagation-traceresponse": "Automatically propagate the context to the client through trace-response headers." + }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.50", "guzzlehttp/guzzle": "*", "nunomaduro/collision": "*", - "open-telemetry/sdk": "^1.0", + "open-telemetry/sdk": "^1.8", "orchestra/testbench": ">=7.41.3", "phan/phan": "^5.0", "php-http/mock-client": "*", diff --git a/src/Instrumentation/Slim/composer.json b/src/Instrumentation/Slim/composer.json index 3c13ec60f..e159b6001 100644 --- a/src/Instrumentation/Slim/composer.json +++ b/src/Instrumentation/Slim/composer.json @@ -12,23 +12,25 @@ "php": "^8.1", "ext-opentelemetry": "*", "ext-reflection": "*", - "open-telemetry/api": "^1.0", + "open-telemetry/api": "^1.6", "open-telemetry/sem-conv": "^1.36", "slim/slim": "^4" }, + "suggest": { + "open-telemetry/opentelemetry-propagation-server-timing": "Automatically propagate the context to the client through server-timing headers.", + "open-telemetry/opentelemetry-propagation-traceresponse": "Automatically propagate the context to the client through trace-response headers." + }, "require-dev": { "friendsofphp/php-cs-fixer": "^3", "mockery/mockery": "^1.5", "nyholm/psr7": "*", - "open-telemetry/opentelemetry-propagation-server-timing": "*", - "open-telemetry/opentelemetry-propagation-traceresponse": "*", "phan/phan": "^5.0", "php-http/mock-client": "*", "phpstan/phpstan-mockery": "^1.1.0", "phpstan/phpstan": "^1.1", "phpstan/phpstan-phpunit": "^1.0", "psalm/plugin-phpunit": "^0.19.2", - "open-telemetry/sdk": "^1.0", + "open-telemetry/sdk": "^1.8", "phpunit/phpunit": "^9.5", "vimeo/psalm": "6.4.0" }, diff --git a/src/Instrumentation/Symfony/composer.json b/src/Instrumentation/Symfony/composer.json index 5e15435ad..766dfb9a9 100644 --- a/src/Instrumentation/Symfony/composer.json +++ b/src/Instrumentation/Symfony/composer.json @@ -11,7 +11,7 @@ "require": { "php": "^8.1", "ext-opentelemetry": "*", - "open-telemetry/api": "^1.0", + "open-telemetry/api": "^1.6", "open-telemetry/sem-conv": "^1.32", "symfony/http-kernel": "*", "symfony/http-client-contracts": "*" @@ -27,13 +27,11 @@ "phpstan/phpstan": "^1.1", "phpstan/phpstan-phpunit": "^1.0", "psalm/plugin-phpunit": "^0.19.2", - "open-telemetry/sdk": "^1.0", + "open-telemetry/sdk": "^1.8", "phpunit/phpunit": "^9.5", "vimeo/psalm": "6.4.0", "symfony/http-client": "^5.4||^6.0", - "symfony/messenger": "^5.4||^6.0", - "open-telemetry/opentelemetry-propagation-traceresponse": "*", - "open-telemetry/opentelemetry-propagation-server-timing": "*" + "symfony/messenger": "^5.4||^6.0" }, "autoload": { "psr-4": { diff --git a/src/Instrumentation/Symfony/tests/Integration/SymfonyInstrumentationTest.php b/src/Instrumentation/Symfony/tests/Integration/SymfonyInstrumentationTest.php index 13373b47a..d63760676 100644 --- a/src/Instrumentation/Symfony/tests/Integration/SymfonyInstrumentationTest.php +++ b/src/Instrumentation/Symfony/tests/Integration/SymfonyInstrumentationTest.php @@ -6,8 +6,6 @@ use OpenTelemetry\API\Trace\SpanKind; use OpenTelemetry\API\Trace\StatusCode; -use OpenTelemetry\Contrib\Propagation\ServerTiming\ServerTimingPropagator; -use OpenTelemetry\Contrib\Propagation\TraceResponse\TraceResponsePropagator; use OpenTelemetry\SemConv\TraceAttributes; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\EventDispatcher\EventDispatcherInterface; @@ -83,17 +81,6 @@ public function test_http_kernel_handle_attributes(): void $this->assertEquals('1.0', $attributes->get(TraceAttributes::NETWORK_PROTOCOL_VERSION)); $this->assertEquals(5, $attributes->get(TraceAttributes::HTTP_RESPONSE_BODY_SIZE)); - $this->assertArrayHasKey( - TraceResponsePropagator::TRACERESPONSE, - $response->headers->all(), - 'traceresponse header is present if TraceResponsePropagator is present' - ); - - $this->assertArrayHasKey( - ServerTimingPropagator::SERVER_TIMING, - $response->headers->all(), - 'server-timings header is present if ServerTimingPropagator is present' - ); } public function test_http_kernel_handle_stream_response(): void @@ -107,18 +94,6 @@ public function test_http_kernel_handle_stream_response(): void $response = $kernel->handle(new Request()); $this->assertCount(1, $this->storage); $this->assertNull($this->storage[0]->getAttributes()->get(TraceAttributes::HTTP_RESPONSE_BODY_SIZE)); - - $this->assertArrayHasKey( - TraceResponsePropagator::TRACERESPONSE, - $response->headers->all(), - 'traceresponse header is present if TraceResponsePropagator is present' - ); - - $this->assertArrayHasKey( - ServerTimingPropagator::SERVER_TIMING, - $response->headers->all(), - 'server-timings header is present if ServerTimingPropagator is present' - ); } public function test_http_kernel_handle_binary_file_response(): void @@ -130,17 +105,6 @@ public function test_http_kernel_handle_binary_file_response(): void $this->assertCount(1, $this->storage); $this->assertNull($this->storage[0]->getAttributes()->get(TraceAttributes::HTTP_RESPONSE_BODY_SIZE)); - $this->assertArrayHasKey( - TraceResponsePropagator::TRACERESPONSE, - $response->headers->all(), - 'traceresponse header is present if TraceResponsePropagator is present' - ); - - $this->assertArrayHasKey( - ServerTimingPropagator::SERVER_TIMING, - $response->headers->all(), - 'server-timings header is present if ServerTimingPropagator is present' - ); } public function test_http_kernel_handle_with_empty_route(): void @@ -154,17 +118,6 @@ public function test_http_kernel_handle_with_empty_route(): void $this->assertCount(1, $this->storage); $this->assertFalse($this->storage[0]->getAttributes()->has(TraceAttributes::HTTP_ROUTE)); - $this->assertArrayHasKey( - TraceResponsePropagator::TRACERESPONSE, - $response->headers->all(), - 'traceresponse header is present if TraceResponsePropagator is present' - ); - - $this->assertArrayHasKey( - ServerTimingPropagator::SERVER_TIMING, - $response->headers->all(), - 'server-timings header is present if ServerTimingPropagator is present' - ); } public function test_http_kernel_handle_without_route(): void @@ -176,17 +129,6 @@ public function test_http_kernel_handle_without_route(): void $this->assertCount(1, $this->storage); $this->assertFalse($this->storage[0]->getAttributes()->has(TraceAttributes::HTTP_ROUTE)); - $this->assertArrayHasKey( - TraceResponsePropagator::TRACERESPONSE, - $response->headers->all(), - 'traceresponse header is present if TraceResponsePropagator is present' - ); - - $this->assertArrayHasKey( - ServerTimingPropagator::SERVER_TIMING, - $response->headers->all(), - 'server-timings header is present if ServerTimingPropagator is present' - ); } public function test_http_kernel_handle_subrequest(): void diff --git a/src/Instrumentation/Yii/composer.json b/src/Instrumentation/Yii/composer.json index 5eeb9af7f..8d5c56853 100644 --- a/src/Instrumentation/Yii/composer.json +++ b/src/Instrumentation/Yii/composer.json @@ -10,12 +10,12 @@ "php": "^8.1", "ext-opentelemetry": "*", "yiisoft/yii2": "^2.0.13", - "open-telemetry/api": "^1", + "open-telemetry/api": "^1.6", "open-telemetry/sem-conv": "^1.32" }, "require-dev": { "friendsofphp/php-cs-fixer": "^3", - "open-telemetry/sdk": "^1.0", + "open-telemetry/sdk": "^1.8", "phan/phan": "^5.0", "php-http/mock-client": "*", "phpstan/phpstan": "^1.1", diff --git a/src/Propagation/ServerTiming/composer.json b/src/Propagation/ServerTiming/composer.json index 059cc4f86..7a830afb4 100644 --- a/src/Propagation/ServerTiming/composer.json +++ b/src/Propagation/ServerTiming/composer.json @@ -10,7 +10,7 @@ "prefer-stable": true, "require": { "php": "^8.1", - "open-telemetry/context": "^1.0" + "open-telemetry/context": "^1.4" }, "autoload": { "psr-4": { @@ -26,7 +26,7 @@ "phpstan/phpstan": "^1.1", "phpstan/phpstan-phpunit": "^1.0", "psalm/plugin-phpunit": "^0.19.2", - "open-telemetry/sdk": "^1.0", + "open-telemetry/sdk": "^1.8", "phpunit/phpunit": "^9.5", "vimeo/psalm": "^4|^5|^6", "symfony/http-client": "^5.4|^6.0", diff --git a/src/Propagation/TraceResponse/composer.json b/src/Propagation/TraceResponse/composer.json index 88d36a753..55f5ed94b 100644 --- a/src/Propagation/TraceResponse/composer.json +++ b/src/Propagation/TraceResponse/composer.json @@ -10,7 +10,7 @@ "prefer-stable": true, "require": { "php": "^8.1", - "open-telemetry/context": "^1.0" + "open-telemetry/context": "^1.4" }, "autoload": { "psr-4": { @@ -26,7 +26,7 @@ "phpstan/phpstan": "^1.1", "phpstan/phpstan-phpunit": "^1.0", "psalm/plugin-phpunit": "^0.19.2", - "open-telemetry/sdk": "^1.0", + "open-telemetry/sdk": "^1.8", "phpunit/phpunit": "^9.5", "vimeo/psalm": "6.4.0", "symfony/http-client": "^5.4|^6.0", From 6a6383816fd865c86ceccd1d5a3a3947b8ed7833 Mon Sep 17 00:00:00 2001 From: Jerry Leung Date: Fri, 19 Sep 2025 10:33:52 -0700 Subject: [PATCH 3/8] Updated Yii composer.json --- src/Instrumentation/Yii/composer.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Instrumentation/Yii/composer.json b/src/Instrumentation/Yii/composer.json index 8d5c56853..e09642c57 100644 --- a/src/Instrumentation/Yii/composer.json +++ b/src/Instrumentation/Yii/composer.json @@ -13,6 +13,10 @@ "open-telemetry/api": "^1.6", "open-telemetry/sem-conv": "^1.32" }, + "suggest": { + "open-telemetry/opentelemetry-propagation-server-timing": "Automatically propagate the context to the client through server-timing headers.", + "open-telemetry/opentelemetry-propagation-traceresponse": "Automatically propagate the context to the client through trace-response headers." + }, "require-dev": { "friendsofphp/php-cs-fixer": "^3", "open-telemetry/sdk": "^1.8", From 4d713f69ae68f23296fa6b0dfc5942e400fb64d2 Mon Sep 17 00:00:00 2001 From: Jerry Leung Date: Fri, 19 Sep 2025 11:27:35 -0700 Subject: [PATCH 4/8] Fixed instrumentation integration tests --- .../Illuminate/Contracts/Http/Kernel.php | 1 + .../Integration/SlimInstrumentationTest.php | 3 --- .../SymfonyInstrumentationTest.php | 27 +++++-------------- 3 files changed, 8 insertions(+), 23 deletions(-) diff --git a/src/Instrumentation/Laravel/src/Hooks/Illuminate/Contracts/Http/Kernel.php b/src/Instrumentation/Laravel/src/Hooks/Illuminate/Contracts/Http/Kernel.php index 806aa70ad..b748cb715 100644 --- a/src/Instrumentation/Laravel/src/Hooks/Illuminate/Contracts/Http/Kernel.php +++ b/src/Instrumentation/Laravel/src/Hooks/Illuminate/Contracts/Http/Kernel.php @@ -100,6 +100,7 @@ protected function hookHandle(): bool $span->setAttribute(TraceAttributes::HTTP_RESPONSE_BODY_SIZE, $response->headers->get('Content-Length')); $prop = Globals::responsePropagator(); + /** @phan-suppress-next-line PhanAccessMethodInternal */ $prop->inject($response, ResponsePropagationSetter::instance(), $scope->context()); } diff --git a/src/Instrumentation/Slim/tests/Integration/SlimInstrumentationTest.php b/src/Instrumentation/Slim/tests/Integration/SlimInstrumentationTest.php index 4d7f5c1ee..293ccae67 100644 --- a/src/Instrumentation/Slim/tests/Integration/SlimInstrumentationTest.php +++ b/src/Instrumentation/Slim/tests/Integration/SlimInstrumentationTest.php @@ -145,9 +145,6 @@ public function test_response_propagation(): void $response = $app->handle($request); $this->assertCount(1, $this->storage); $this->assertArrayHasKey('X-Foo', $response->getHeaders()); - $this->assertArrayHasKey('server-timing', $response->getHeaders()); - $this->assertStringStartsWith('traceparent;desc=', $response->getHeaderLine('server-timing')); - $this->assertArrayHasKey('traceresponse', $response->getHeaders()); } public function createMockStrategy(): InvocationStrategyInterface diff --git a/src/Instrumentation/Symfony/tests/Integration/SymfonyInstrumentationTest.php b/src/Instrumentation/Symfony/tests/Integration/SymfonyInstrumentationTest.php index d63760676..03a8227d2 100644 --- a/src/Instrumentation/Symfony/tests/Integration/SymfonyInstrumentationTest.php +++ b/src/Instrumentation/Symfony/tests/Integration/SymfonyInstrumentationTest.php @@ -29,14 +29,7 @@ public function test_http_kernel_handle_exception(): void throw new \RuntimeException(); }); $this->assertCount(0, $this->storage); - - $response = $kernel->handle(new Request()); - - $this->assertArrayHasKey( - TraceResponsePropagator::TRACERESPONSE, - $response->headers->all(), - 'traceresponse header is present if TraceResponsePropagator is present' - ); + $kernel->handle(new Request()); } public function test_http_kernel_marks_root_as_erroneous(): void @@ -47,18 +40,12 @@ public function test_http_kernel_marks_root_as_erroneous(): void }); $this->assertCount(0, $this->storage); - $response = $kernel->handle(new Request(), HttpKernelInterface::MAIN_REQUEST, true); + $kernel->handle(new Request(), HttpKernelInterface::MAIN_REQUEST, true); $this->assertCount(1, $this->storage); $this->assertSame(500, $this->storage[0]->getAttributes()->get(TraceAttributes::HTTP_RESPONSE_STATUS_CODE)); $this->assertSame(StatusCode::STATUS_ERROR, $this->storage[0]->getStatus()->getCode()); - - $this->assertArrayHasKey( - TraceResponsePropagator::TRACERESPONSE, - $response->headers->all(), - 'traceresponse header is present if TraceResponsePropagator is present' - ); } public function test_http_kernel_handle_attributes(): void @@ -68,7 +55,7 @@ public function test_http_kernel_handle_attributes(): void $request = new Request(); $request->attributes->set('_route', 'test_route'); - $response = $kernel->handle($request); + $kernel->handle($request); $attributes = $this->storage[0]->getAttributes(); $this->assertCount(1, $this->storage); @@ -91,7 +78,7 @@ public function test_http_kernel_handle_stream_response(): void })); $this->assertCount(0, $this->storage); - $response = $kernel->handle(new Request()); + $kernel->handle(new Request()); $this->assertCount(1, $this->storage); $this->assertNull($this->storage[0]->getAttributes()->get(TraceAttributes::HTTP_RESPONSE_BODY_SIZE)); } @@ -101,7 +88,7 @@ public function test_http_kernel_handle_binary_file_response(): void $kernel = $this->getHttpKernel(new EventDispatcher(), fn () => new BinaryFileResponse(__FILE__)); $this->assertCount(0, $this->storage); - $response = $kernel->handle(new Request()); + $kernel->handle(new Request()); $this->assertCount(1, $this->storage); $this->assertNull($this->storage[0]->getAttributes()->get(TraceAttributes::HTTP_RESPONSE_BODY_SIZE)); @@ -114,7 +101,7 @@ public function test_http_kernel_handle_with_empty_route(): void $request = new Request(); $request->attributes->set('_route', ''); - $response = $kernel->handle($request, HttpKernelInterface::MAIN_REQUEST, true); + $kernel->handle($request, HttpKernelInterface::MAIN_REQUEST, true); $this->assertCount(1, $this->storage); $this->assertFalse($this->storage[0]->getAttributes()->has(TraceAttributes::HTTP_ROUTE)); @@ -125,7 +112,7 @@ public function test_http_kernel_handle_without_route(): void $kernel = $this->getHttpKernel(new EventDispatcher()); $this->assertCount(0, $this->storage); - $response = $kernel->handle(new Request(), HttpKernelInterface::MAIN_REQUEST, true); + $kernel->handle(new Request(), HttpKernelInterface::MAIN_REQUEST, true); $this->assertCount(1, $this->storage); $this->assertFalse($this->storage[0]->getAttributes()->has(TraceAttributes::HTTP_ROUTE)); From 8c649ced417e63708bb91191ca077b1428289ee7 Mon Sep 17 00:00:00 2001 From: Jerry Leung Date: Fri, 19 Sep 2025 11:43:55 -0700 Subject: [PATCH 5/8] Fixed Propagation tests --- .../tests/Unit/PropagatorTest.php | 25 +++++++++++-------- .../tests/Unit/PropagatorTest.php | 25 +++++++++++-------- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/Propagation/ServerTiming/tests/Unit/PropagatorTest.php b/src/Propagation/ServerTiming/tests/Unit/PropagatorTest.php index 9282dc6bc..a98bbb7a9 100644 --- a/src/Propagation/ServerTiming/tests/Unit/PropagatorTest.php +++ b/src/Propagation/ServerTiming/tests/Unit/PropagatorTest.php @@ -11,7 +11,7 @@ use OpenTelemetry\API\Trace\TraceState; use OpenTelemetry\Context\Context; use OpenTelemetry\Context\ContextInterface; -use OpenTelemetry\Contrib\Propagation\ServerTiming\ServerTimingPropagator as Propagator; +use OpenTelemetry\Contrib\Propagation\ServerTiming\ServerTimingPropagator; use OpenTelemetry\SDK\Trace\Span; use PHPUnit\Framework\TestCase; @@ -21,15 +21,20 @@ class PropagatorTest extends TestCase private const SPAN_ID = '53995c3f42cd8ad8'; private const TRACERESPONSE_HEADER_SAMPLED = '00-5759e988bd862e3fe1be46a994272793-53995c3f42cd8ad8-01'; private const TRACERESPONSE_HEADER_NOT_SAMPLED = '00-5759e988bd862e3fe1be46a994272793-53995c3f42cd8ad8-00'; + private ServerTimingPropagator $propagator; + #[\Override] + protected function setUp(): void + { + $this->propagator = ServerTimingPropagator::getInstance(); + } /** * @test * fields() should return an array of fields that will be set on the carrier */ public function test_fields() { - $propagator = new Propagator(); - $this->assertSame($propagator->fields(), [Propagator::SERVER_TIMING]); + $this->assertSame($this->propagator->fields(), [ServerTimingPropagator::SERVER_TIMING]); } /** @@ -40,7 +45,7 @@ public function test_fields() public function test_inject_valid_sampled_trace_id() { $carrier = []; - (new Propagator())->inject( + $this->propagator->inject( $carrier, null, $this->withSpanContext( @@ -50,7 +55,7 @@ public function test_inject_valid_sampled_trace_id() ); $this->assertSame( - [Propagator::SERVER_TIMING => sprintf('%s;desc=%s', Propagator::TRACEPARENT, self::TRACERESPONSE_HEADER_SAMPLED)], + [ServerTimingPropagator::SERVER_TIMING => sprintf('%s;desc=%s', ServerTimingPropagator::TRACEPARENT, self::TRACERESPONSE_HEADER_SAMPLED)], $carrier ); } @@ -62,7 +67,7 @@ public function test_inject_valid_sampled_trace_id() public function test_inject_valid_not_sampled_trace_id() { $carrier = []; - (new Propagator())->inject( + $this->propagator->inject( $carrier, null, $this->withSpanContext( @@ -72,7 +77,7 @@ public function test_inject_valid_not_sampled_trace_id() ); $this->assertSame( - [Propagator::SERVER_TIMING => sprintf('%s;desc=%s', Propagator::TRACEPARENT, self::TRACERESPONSE_HEADER_NOT_SAMPLED)], + [ServerTimingPropagator::SERVER_TIMING => sprintf('%s;desc=%s', ServerTimingPropagator::TRACEPARENT, self::TRACERESPONSE_HEADER_NOT_SAMPLED)], $carrier ); } @@ -84,7 +89,7 @@ public function test_inject_valid_not_sampled_trace_id() public function test_inject_trace_id_with_trace_state() { $carrier = []; - (new Propagator())->inject( + $this->propagator->inject( $carrier, null, $this->withSpanContext( @@ -94,7 +99,7 @@ public function test_inject_trace_id_with_trace_state() ); $this->assertSame( - [Propagator::SERVER_TIMING => sprintf('%s;desc=%s', Propagator::TRACEPARENT, self::TRACERESPONSE_HEADER_SAMPLED)], + [ServerTimingPropagator::SERVER_TIMING => sprintf('%s;desc=%s', ServerTimingPropagator::TRACEPARENT, self::TRACERESPONSE_HEADER_SAMPLED)], $carrier ); } @@ -106,7 +111,7 @@ public function test_inject_trace_id_with_trace_state() public function test_inject_trace_id_with_invalid_span_context() { $carrier = []; - (new Propagator())->inject( + $this->propagator->inject( $carrier, null, $this->withSpanContext( diff --git a/src/Propagation/TraceResponse/tests/Unit/PropagatorTest.php b/src/Propagation/TraceResponse/tests/Unit/PropagatorTest.php index e854d70d9..69959ccda 100644 --- a/src/Propagation/TraceResponse/tests/Unit/PropagatorTest.php +++ b/src/Propagation/TraceResponse/tests/Unit/PropagatorTest.php @@ -11,7 +11,7 @@ use OpenTelemetry\API\Trace\TraceState; use OpenTelemetry\Context\Context; use OpenTelemetry\Context\ContextInterface; -use OpenTelemetry\Contrib\Propagation\TraceResponse\TraceResponsePropagator as Propagator; +use OpenTelemetry\Contrib\Propagation\TraceResponse\TraceResponsePropagator; use OpenTelemetry\SDK\Trace\Span; use PHPUnit\Framework\TestCase; @@ -21,15 +21,20 @@ class PropagatorTest extends TestCase private const SPAN_ID = '53995c3f42cd8ad8'; private const TRACERESPONSE_HEADER_SAMPLED = '00-5759e988bd862e3fe1be46a994272793-53995c3f42cd8ad8-01'; private const TRACERESPONSE_HEADER_NOT_SAMPLED = '00-5759e988bd862e3fe1be46a994272793-53995c3f42cd8ad8-00'; + private TraceResponsePropagator $propagator; + #[\Override] + protected function setUp(): void + { + $this->propagator = TraceResponsePropagator::getInstance(); + } /** * @test * fields() should return an array of fields with AWS X-Ray Trace ID Header */ public function test_fields() { - $propagator = new Propagator(); - $this->assertSame($propagator->fields(), [Propagator::TRACERESPONSE]); + $this->assertSame($this->propagator->fields(), [TraceResponsePropagator::TRACERESPONSE]); } /** @@ -40,7 +45,7 @@ public function test_fields() public function test_inject_valid_sampled_trace_id() { $carrier = []; - (new Propagator())->inject( + $this->propagator->inject( $carrier, null, $this->withSpanContext( @@ -50,7 +55,7 @@ public function test_inject_valid_sampled_trace_id() ); $this->assertSame( - [Propagator::TRACERESPONSE => self::TRACERESPONSE_HEADER_SAMPLED], + [TraceResponsePropagator::TRACERESPONSE => self::TRACERESPONSE_HEADER_SAMPLED], $carrier ); } @@ -62,7 +67,7 @@ public function test_inject_valid_sampled_trace_id() public function test_inject_valid_not_sampled_trace_id() { $carrier = []; - (new Propagator())->inject( + $this->propagator->inject( $carrier, null, $this->withSpanContext( @@ -72,7 +77,7 @@ public function test_inject_valid_not_sampled_trace_id() ); $this->assertSame( - [Propagator::TRACERESPONSE => self::TRACERESPONSE_HEADER_NOT_SAMPLED], + [TraceResponsePropagator::TRACERESPONSE => self::TRACERESPONSE_HEADER_NOT_SAMPLED], $carrier ); } @@ -84,7 +89,7 @@ public function test_inject_valid_not_sampled_trace_id() public function test_inject_trace_id_with_trace_state() { $carrier = []; - (new Propagator())->inject( + $this->propagator->inject( $carrier, null, $this->withSpanContext( @@ -94,7 +99,7 @@ public function test_inject_trace_id_with_trace_state() ); $this->assertSame( - [Propagator::TRACERESPONSE => self::TRACERESPONSE_HEADER_SAMPLED], + [TraceResponsePropagator::TRACERESPONSE => self::TRACERESPONSE_HEADER_SAMPLED], $carrier ); } @@ -106,7 +111,7 @@ public function test_inject_trace_id_with_trace_state() public function test_inject_trace_id_with_invalid_span_context() { $carrier = []; - (new Propagator())->inject( + $this->propagator->inject( $carrier, null, $this->withSpanContext( From ec1eca8607ad4ce08f1a83a150a3cdb81a16a71a Mon Sep 17 00:00:00 2001 From: Jerry Leung Date: Fri, 19 Sep 2025 13:32:14 -0700 Subject: [PATCH 6/8] Fixed style issue for Symfony --- .../src/OtelSdkBundle/Util/ServicesConfiguratorHelper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/src/OtelSdkBundle/Util/ServicesConfiguratorHelper.php b/src/Symfony/src/OtelSdkBundle/Util/ServicesConfiguratorHelper.php index b82adcae6..5b95f94f7 100644 --- a/src/Symfony/src/OtelSdkBundle/Util/ServicesConfiguratorHelper.php +++ b/src/Symfony/src/OtelSdkBundle/Util/ServicesConfiguratorHelper.php @@ -30,8 +30,8 @@ public static function create(ServicesConfigurator $configurator): self /** * @param string $class - * @psalm-param class-string $class * @param bool $alias + * @psalm-param class-string $class * @return ServiceConfigurator */ public function setService(string $class, bool $alias = true): ServiceConfigurator From 552b68c9877a5d1eb5fe88cb6eb5530a4c1771e4 Mon Sep 17 00:00:00 2001 From: Jerry Leung Date: Fri, 19 Sep 2025 14:05:52 -0700 Subject: [PATCH 7/8] Fixed semconv issue of MongoDB --- .../src/MongoDBInstrumentationSubscriber.php | 20 ++++++++++--------- .../MongoDBInstrumentationTest.php | 18 +++++++++-------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/Instrumentation/MongoDB/src/MongoDBInstrumentationSubscriber.php b/src/Instrumentation/MongoDB/src/MongoDBInstrumentationSubscriber.php index 03e8fa6a8..441393bc1 100644 --- a/src/Instrumentation/MongoDB/src/MongoDBInstrumentationSubscriber.php +++ b/src/Instrumentation/MongoDB/src/MongoDBInstrumentationSubscriber.php @@ -25,7 +25,9 @@ use OpenTelemetry\API\Trace\SpanKind; use OpenTelemetry\API\Trace\StatusCode; use OpenTelemetry\Context\Context; -use OpenTelemetry\SemConv\TraceAttributes; +use OpenTelemetry\SemConv\Attributes\DbAttributes; +use OpenTelemetry\SemConv\Attributes\NetworkAttributes; +use OpenTelemetry\SemConv\Attributes\ServerAttributes; use Throwable; /** @@ -86,14 +88,14 @@ public function commandStarted(CommandStartedEvent $event): void $builder = self::startSpan($this->instrumentation, 'MongoDB ' . $scopedCommand) ->setSpanKind(SpanKind::KIND_CLIENT) - ->setAttribute(TraceAttributes::DB_SYSTEM_NAME, 'mongodb') - ->setAttribute(TraceAttributes::DB_NAMESPACE, $databaseName) - ->setAttribute(TraceAttributes::DB_OPERATION_NAME, $commandName) - ->setAttribute(TraceAttributes::SERVER_ADDRESS, $isSocket ? null : $host) - ->setAttribute(TraceAttributes::SERVER_PORT, $isSocket ? null : $port) - ->setAttribute(TraceAttributes::NETWORK_TRANSPORT, $isSocket ? 'unix' : 'tcp') - ->setAttribute(TraceAttributes::DB_QUERY_TEXT, ($this->commandSerializer)($command)) - ->setAttribute(TraceAttributes::DB_COLLECTION_NAME, $collectionName) + ->setAttribute(DbAttributes::DB_SYSTEM_NAME, 'mongodb') + ->setAttribute(DbAttributes::DB_NAMESPACE, $databaseName) + ->setAttribute(DbAttributes::DB_OPERATION_NAME, $commandName) + ->setAttribute(ServerAttributes::SERVER_ADDRESS, $isSocket ? null : $host) + ->setAttribute(ServerAttributes::SERVER_PORT, $isSocket ? null : $port) + ->setAttribute(NetworkAttributes::NETWORK_TRANSPORT, $isSocket ? 'unix' : 'tcp') + ->setAttribute(DbAttributes::DB_QUERY_TEXT, ($this->commandSerializer)($command)) + ->setAttribute(DbAttributes::DB_COLLECTION_NAME, $collectionName) ->setAttribute(MongoDBTraceAttributes::DB_MONGODB_REQUEST_ID, $event->getRequestId()) ->setAttribute(MongoDBTraceAttributes::DB_MONGODB_OPERATION_ID, $event->getOperationId()) ->setAttributes($attributes) diff --git a/src/Instrumentation/MongoDB/tests/Integration/MongoDBInstrumentationTest.php b/src/Instrumentation/MongoDB/tests/Integration/MongoDBInstrumentationTest.php index 692191e51..10e65a19a 100644 --- a/src/Instrumentation/MongoDB/tests/Integration/MongoDBInstrumentationTest.php +++ b/src/Instrumentation/MongoDB/tests/Integration/MongoDBInstrumentationTest.php @@ -15,7 +15,9 @@ use OpenTelemetry\SDK\Trace\SpanExporter\InMemoryExporter; use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor; use OpenTelemetry\SDK\Trace\TracerProvider; -use OpenTelemetry\SemConv\TraceAttributes; +use OpenTelemetry\SemConv\Attributes\DbAttributes; +use OpenTelemetry\SemConv\Attributes\NetworkAttributes; +use OpenTelemetry\SemConv\Attributes\ServerAttributes; use PHPUnit\Framework\TestCase; class MongoDBInstrumentationTest extends TestCase @@ -69,13 +71,13 @@ public function test_mongodb_find_one(): void self::assertSame('MongoDB coll.find', $this->span->getName()); self::assertSame(SpanKind::KIND_CLIENT, $this->span->getKind()); $attributes = $this->span->getAttributes(); - self::assertSame('mongodb', $attributes->get(TraceAttributes::DB_SYSTEM_NAME)); - self::assertSame(self::DATABASE_NAME, $attributes->get(TraceAttributes::DB_NAMESPACE)); - self::assertSame('find', $attributes->get(TraceAttributes::DB_OPERATION_NAME)); - self::assertSame(self::COLLECTION_NAME, $attributes->get(TraceAttributes::DB_COLLECTION_NAME)); - self::assertSame($this->host, $attributes->get(TraceAttributes::SERVER_ADDRESS)); - self::assertSame($this->port, $attributes->get(TraceAttributes::SERVER_PORT)); - self::assertSame('tcp', $attributes->get(TraceAttributes::NETWORK_TRANSPORT)); + self::assertSame('mongodb', $attributes->get(DbAttributes::DB_SYSTEM_NAME)); + self::assertSame(self::DATABASE_NAME, $attributes->get(DbAttributes::DB_NAMESPACE)); + self::assertSame('find', $attributes->get(DbAttributes::DB_OPERATION_NAME)); + self::assertSame(self::COLLECTION_NAME, $attributes->get(DbAttributes::DB_COLLECTION_NAME)); + self::assertSame($this->host, $attributes->get(ServerAttributes::SERVER_ADDRESS)); + self::assertSame($this->port, $attributes->get(ServerAttributes::SERVER_PORT)); + self::assertSame('tcp', $attributes->get(NetworkAttributes::NETWORK_TRANSPORT)); self::assertTrue($attributes->get(MongoDBTraceAttributes::DB_MONGODB_MASTER)); self::assertFalse($attributes->get(MongoDBTraceAttributes::DB_MONGODB_READ_ONLY)); self::assertIsNumeric($attributes->get(MongoDBTraceAttributes::DB_MONGODB_CONNECTION_ID)); From 6530c3bdf51cc1ee1faa0bb827923aadb156af0d Mon Sep 17 00:00:00 2001 From: Jerry Leung Date: Tue, 23 Sep 2025 09:10:15 -0700 Subject: [PATCH 8/8] Bumped sem-conv version in MongoDB to 1.36 --- src/Instrumentation/MongoDB/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Instrumentation/MongoDB/composer.json b/src/Instrumentation/MongoDB/composer.json index 2ce2065c5..9b5ba62bb 100644 --- a/src/Instrumentation/MongoDB/composer.json +++ b/src/Instrumentation/MongoDB/composer.json @@ -12,7 +12,7 @@ "ext-json": "*", "mongodb/mongodb": "^1.15 || ^2.0", "open-telemetry/api": "^1.0", - "open-telemetry/sem-conv": "^1.32" + "open-telemetry/sem-conv": "^1.36" }, "require-dev": { "friendsofphp/php-cs-fixer": "^3",