From d99662f948e639567da4fc94ac1b569209433cb0 Mon Sep 17 00:00:00 2001 From: Evan <138915122+ycchuang99@users.noreply.github.com> Date: Thu, 17 Apr 2025 07:39:10 +0800 Subject: [PATCH 1/3] remove FilteredAttributes and related references (#1565) --- .../Attribute/FilteredAttributesBuilder.php | 77 ------------------- .../Attribute/FilteredAttributesFactory.php | 30 -------- Trace/SpanLimitsBuilder.php | 27 +------ 3 files changed, 1 insertion(+), 133 deletions(-) delete mode 100644 Common/Attribute/FilteredAttributesBuilder.php delete mode 100644 Common/Attribute/FilteredAttributesFactory.php diff --git a/Common/Attribute/FilteredAttributesBuilder.php b/Common/Attribute/FilteredAttributesBuilder.php deleted file mode 100644 index 8d7c9c1..0000000 --- a/Common/Attribute/FilteredAttributesBuilder.php +++ /dev/null @@ -1,77 +0,0 @@ - $rejectedKeys - */ - public function __construct( - private AttributesBuilderInterface $builder, - private readonly array $rejectedKeys, - ) { - } - - public function __clone() - { - $this->builder = clone $this->builder; - } - - public function build(): AttributesInterface - { - $attributes = $this->builder->build(); - $dropped = $attributes->getDroppedAttributesCount() + $this->rejected; - - return new Attributes($attributes->toArray(), $dropped); - } - - public function merge(AttributesInterface $old, AttributesInterface $updating): AttributesInterface - { - return $this->builder->merge($old, $updating); - } - - public function offsetExists($offset): bool - { - return $this->builder->offsetExists($offset); - } - - /** - * @phan-suppress PhanUndeclaredClassAttribute - */ - public function offsetGet(mixed $offset): mixed - { - return $this->builder->offsetGet($offset); - } - - /** - * @phan-suppress PhanUndeclaredClassAttribute - */ - public function offsetSet($offset, $value): void - { - if ($value !== null && in_array($offset, $this->rejectedKeys, true)) { - $this->rejected++; - - return; - } - - $this->builder->offsetSet($offset, $value); - } - - /** - * @phan-suppress PhanUndeclaredClassAttribute - */ - public function offsetUnset($offset): void - { - $this->builder->offsetUnset($offset); - } -} diff --git a/Common/Attribute/FilteredAttributesFactory.php b/Common/Attribute/FilteredAttributesFactory.php deleted file mode 100644 index d6ad75c..0000000 --- a/Common/Attribute/FilteredAttributesFactory.php +++ /dev/null @@ -1,30 +0,0 @@ - $rejectedKeys - */ - public function __construct( - private readonly AttributesFactoryInterface $factory, - private readonly array $rejectedKeys, - ) { - } - - public function builder(iterable $attributes = [], ?AttributeValidatorInterface $attributeValidator = null): AttributesBuilderInterface - { - $builder = new FilteredAttributesBuilder($this->factory->builder([], $attributeValidator), $this->rejectedKeys); - foreach ($attributes as $attribute => $value) { - $builder[$attribute] = $value; - } - - return $builder; - } -} diff --git a/Trace/SpanLimitsBuilder.php b/Trace/SpanLimitsBuilder.php index c8c8189..4d9e26e 100644 --- a/Trace/SpanLimitsBuilder.php +++ b/Trace/SpanLimitsBuilder.php @@ -5,10 +5,8 @@ namespace OpenTelemetry\SDK\Trace; use OpenTelemetry\SDK\Common\Attribute\Attributes; -use OpenTelemetry\SDK\Common\Attribute\FilteredAttributesFactory; use OpenTelemetry\SDK\Common\Configuration\Configuration; use OpenTelemetry\SDK\Common\Configuration\Variables as Env; -use OpenTelemetry\SemConv\TraceAttributes; use const PHP_INT_MAX; class SpanLimitsBuilder @@ -31,8 +29,6 @@ class SpanLimitsBuilder /** @var ?int Maximum allowed attribute per span link count */ private ?int $attributePerLinkCountLimit = null; - private bool $retainGeneralIdentityAttributes = false; - /** * @param int $attributeCountLimit Maximum allowed attribute count per record */ @@ -93,18 +89,6 @@ public function setAttributePerLinkCountLimit(int $attributePerLinkCountLimit): return $this; } - /** - * @param bool $retain whether general identity attributes should be retained - * - * @see https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/attributes.md#general-identity-attributes - */ - public function retainGeneralIdentityAttributes(bool $retain = true): SpanLimitsBuilder - { - $this->retainGeneralIdentityAttributes = $retain; - - return $this; - } - /** * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#span-limits * @phan-suppress PhanDeprecatedClassConstant @@ -128,17 +112,8 @@ public function build(): SpanLimits $attributeValueLengthLimit = null; } - $spanAttributesFactory = Attributes::factory($attributeCountLimit, $attributeValueLengthLimit); - - if (!$this->retainGeneralIdentityAttributes) { - $spanAttributesFactory = new FilteredAttributesFactory($spanAttributesFactory, [ - TraceAttributes::USER_ID, - TraceAttributes::USER_ROLES, - ]); - } - return new SpanLimits( - $spanAttributesFactory, + Attributes::factory($attributeCountLimit, $attributeValueLengthLimit), Attributes::factory($attributePerEventCountLimit, $attributeValueLengthLimit), Attributes::factory($attributePerLinkCountLimit, $attributeValueLengthLimit), $eventCountLimit, From 2722618f69dce0617687cc0b8749a4a24b620bd0 Mon Sep 17 00:00:00 2001 From: Brett McBride Date: Thu, 1 May 2025 13:37:15 +1000 Subject: [PATCH 2/3] update resource detectors to align with spec changes (#1573) PR https://github.com/open-telemetry/opentelemetry-specification/pull/4461 clarifies that some attributes (service.name, telemetry.*) are mandatory. It also reserves a couple of well-known detectors names (container, host, process, service) and the attributes they should populate. Consolidate some of our resource detectors into the built-in ones: - process-runtime into process, and deprecate - os into host, and deprecate - sdk-provided into sdk, and deprecate - service.name attribute from environment into service detector Add "mandatory attributes", which is currently service.name, and initially set this to "unknown_service:php" similar to Java's implementation. Ensure that the composite detector starts with mandatory attributes. Ensure that "sdk" and "service" detectors are always included from ResourceInfoFactory. The deprecated detectors are still available, but do not do anything. --- Resource/Detectors/Composer.php | 3 ++ Resource/Detectors/Composite.php | 2 +- Resource/Detectors/Environment.php | 8 ----- Resource/Detectors/Host.php | 8 +++++ Resource/Detectors/OperatingSystem.php | 17 ++-------- Resource/Detectors/Process.php | 13 ++++++-- Resource/Detectors/ProcessRuntime.php | 13 ++------ Resource/Detectors/Sdk.php | 3 +- Resource/Detectors/SdkProvided.php | 10 ++---- Resource/Detectors/Service.php | 8 +++++ Resource/ResourceInfoFactory.php | 44 +++++++++++--------------- 11 files changed, 57 insertions(+), 72 deletions(-) diff --git a/Resource/Detectors/Composer.php b/Resource/Detectors/Composer.php index 56b136e..0302f6c 100644 --- a/Resource/Detectors/Composer.php +++ b/Resource/Detectors/Composer.php @@ -12,6 +12,9 @@ use OpenTelemetry\SDK\Resource\ResourceInfoFactory; use OpenTelemetry\SemConv\ResourceAttributes; +/** + * Detect service name and version of root package. Not included in `all` detectors. + */ final class Composer implements ResourceDetectorInterface { public function getResource(): ResourceInfo diff --git a/Resource/Detectors/Composite.php b/Resource/Detectors/Composite.php index 7515e5d..36996a2 100644 --- a/Resource/Detectors/Composite.php +++ b/Resource/Detectors/Composite.php @@ -19,7 +19,7 @@ public function __construct(private readonly iterable $resourceDetectors) public function getResource(): ResourceInfo { - $resource = ResourceInfoFactory::emptyResource(); + $resource = ResourceInfoFactory::mandatoryResource(); foreach ($this->resourceDetectors as $resourceDetector) { $resource = $resource->merge($resourceDetector->getResource()); } diff --git a/Resource/Detectors/Environment.php b/Resource/Detectors/Environment.php index ceee8fc..2e7ba50 100644 --- a/Resource/Detectors/Environment.php +++ b/Resource/Detectors/Environment.php @@ -22,14 +22,6 @@ public function getResource(): ResourceInfo ? self::decode(Configuration::getMap(Variables::OTEL_RESOURCE_ATTRIBUTES, [])) : []; - //@see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#general-sdk-configuration - $serviceName = Configuration::has(Variables::OTEL_SERVICE_NAME) - ? Configuration::getString(Variables::OTEL_SERVICE_NAME) - : null; - if ($serviceName) { - $attributes[ResourceAttributes::SERVICE_NAME] = $serviceName; - } - return ResourceInfo::create(Attributes::create($attributes), ResourceAttributes::SCHEMA_URL); } diff --git a/Resource/Detectors/Host.php b/Resource/Detectors/Host.php index 73c7afa..9bc0b6c 100644 --- a/Resource/Detectors/Host.php +++ b/Resource/Detectors/Host.php @@ -8,10 +8,14 @@ use OpenTelemetry\SDK\Resource\ResourceDetectorInterface; use OpenTelemetry\SDK\Resource\ResourceInfo; use OpenTelemetry\SemConv\ResourceAttributes; +use const PHP_OS; +use const PHP_OS_FAMILY; use function php_uname; +use function strtolower; /** * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.8.0/specification/resource/semantic_conventions/host.md#host + * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.8.0/specification/resource/semantic_conventions/os.md */ final class Host implements ResourceDetectorInterface { @@ -31,6 +35,10 @@ public function getResource(): ResourceInfo ResourceAttributes::HOST_NAME => php_uname('n'), ResourceAttributes::HOST_ARCH => php_uname('m'), ResourceAttributes::HOST_ID => $this->getMachineId(), + ResourceAttributes::OS_TYPE => strtolower(PHP_OS_FAMILY), + ResourceAttributes::OS_DESCRIPTION => php_uname('r'), + ResourceAttributes::OS_NAME => PHP_OS, + ResourceAttributes::OS_VERSION => php_uname('v'), ]; return ResourceInfo::create(Attributes::create($attributes), ResourceAttributes::SCHEMA_URL); diff --git a/Resource/Detectors/OperatingSystem.php b/Resource/Detectors/OperatingSystem.php index 2cb350d..99b2939 100644 --- a/Resource/Detectors/OperatingSystem.php +++ b/Resource/Detectors/OperatingSystem.php @@ -4,29 +4,16 @@ namespace OpenTelemetry\SDK\Resource\Detectors; -use OpenTelemetry\SDK\Common\Attribute\Attributes; use OpenTelemetry\SDK\Resource\ResourceDetectorInterface; use OpenTelemetry\SDK\Resource\ResourceInfo; -use OpenTelemetry\SemConv\ResourceAttributes; -use const PHP_OS; -use const PHP_OS_FAMILY; -use function php_uname; -use function strtolower; /** - * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.8.0/specification/resource/semantic_conventions/os.md + * @deprecated Use Host detector instead. */ final class OperatingSystem implements ResourceDetectorInterface { public function getResource(): ResourceInfo { - $attributes = [ - ResourceAttributes::OS_TYPE => strtolower(PHP_OS_FAMILY), - ResourceAttributes::OS_DESCRIPTION => php_uname('r'), - ResourceAttributes::OS_NAME => PHP_OS, - ResourceAttributes::OS_VERSION => php_uname('v'), - ]; - - return ResourceInfo::create(Attributes::create($attributes), ResourceAttributes::SCHEMA_URL); + return ResourceInfo::emptyResource(); } } diff --git a/Resource/Detectors/Process.php b/Resource/Detectors/Process.php index 7f1d993..db636b9 100644 --- a/Resource/Detectors/Process.php +++ b/Resource/Detectors/Process.php @@ -11,9 +11,12 @@ use OpenTelemetry\SDK\Resource\ResourceInfo; use OpenTelemetry\SemConv\ResourceAttributes; use const PHP_BINARY; +use function php_sapi_name; +use const PHP_VERSION; /** * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.8.0/specification/resource/semantic_conventions/process.md#process + * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.8.0/specification/resource/semantic_conventions/process.md#process-runtimes */ final class Process implements ResourceDetectorInterface { @@ -22,9 +25,13 @@ final class Process implements ResourceDetectorInterface */ public function getResource(): ResourceInfo { - $attributes = []; - $attributes[ResourceAttributes::PROCESS_PID] = getmypid(); - $attributes[ResourceAttributes::PROCESS_EXECUTABLE_PATH] = PHP_BINARY; + $attributes = [ + ResourceAttributes::PROCESS_RUNTIME_NAME => php_sapi_name(), + ResourceAttributes::PROCESS_RUNTIME_VERSION => PHP_VERSION, + ResourceAttributes::PROCESS_PID => getmypid(), + ResourceAttributes::PROCESS_EXECUTABLE_PATH => PHP_BINARY, + ]; + /** * @psalm-suppress PossiblyUndefinedArrayOffset */ diff --git a/Resource/Detectors/ProcessRuntime.php b/Resource/Detectors/ProcessRuntime.php index f29ddfc..81dafd8 100644 --- a/Resource/Detectors/ProcessRuntime.php +++ b/Resource/Detectors/ProcessRuntime.php @@ -4,25 +4,16 @@ namespace OpenTelemetry\SDK\Resource\Detectors; -use OpenTelemetry\SDK\Common\Attribute\Attributes; use OpenTelemetry\SDK\Resource\ResourceDetectorInterface; use OpenTelemetry\SDK\Resource\ResourceInfo; -use OpenTelemetry\SemConv\ResourceAttributes; -use function php_sapi_name; -use const PHP_VERSION; /** - * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.8.0/specification/resource/semantic_conventions/process.md#process-runtimes + * @deprecated Use Process detector instead. */ final class ProcessRuntime implements ResourceDetectorInterface { public function getResource(): ResourceInfo { - $attributes = [ - ResourceAttributes::PROCESS_RUNTIME_NAME => php_sapi_name(), - ResourceAttributes::PROCESS_RUNTIME_VERSION => PHP_VERSION, - ]; - - return ResourceInfo::create(Attributes::create($attributes), ResourceAttributes::SCHEMA_URL); + return ResourceInfo::emptyResource(); } } diff --git a/Resource/Detectors/Sdk.php b/Resource/Detectors/Sdk.php index dba3eb8..0c17f64 100644 --- a/Resource/Detectors/Sdk.php +++ b/Resource/Detectors/Sdk.php @@ -12,7 +12,8 @@ use OpenTelemetry\SemConv\ResourceAttributes; /** - * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.8.0/specification/resource/semantic_conventions/README.md#telemetry-sdk + * The SDK MUST provide access to a Resource with at least the attributes listed + * at {@see https://github.com/open-telemetry/semantic-conventions/blob/v1.32.0/docs/resource/README.md#semantic-attributes-with-sdk-provided-default-value} */ final class Sdk implements ResourceDetectorInterface { diff --git a/Resource/Detectors/SdkProvided.php b/Resource/Detectors/SdkProvided.php index ec4ec7d..212e6f8 100644 --- a/Resource/Detectors/SdkProvided.php +++ b/Resource/Detectors/SdkProvided.php @@ -4,22 +4,16 @@ namespace OpenTelemetry\SDK\Resource\Detectors; -use OpenTelemetry\SDK\Common\Attribute\Attributes; use OpenTelemetry\SDK\Resource\ResourceDetectorInterface; use OpenTelemetry\SDK\Resource\ResourceInfo; -use OpenTelemetry\SemConv\ResourceAttributes; /** - * @see https://github.com/open-telemetry/semantic-conventions/blob/main/docs/resource/README.md#semantic-attributes-with-sdk-provided-default-value + * @deprecated Use Service detector instead. */ final class SdkProvided implements ResourceDetectorInterface { public function getResource(): ResourceInfo { - $attributes = [ - ResourceAttributes::SERVICE_NAME => 'unknown_service:php', - ]; - - return ResourceInfo::create(Attributes::create($attributes), ResourceAttributes::SCHEMA_URL); + return ResourceInfo::emptyResource(); } } diff --git a/Resource/Detectors/Service.php b/Resource/Detectors/Service.php index b51920b..7009875 100644 --- a/Resource/Detectors/Service.php +++ b/Resource/Detectors/Service.php @@ -5,6 +5,8 @@ namespace OpenTelemetry\SDK\Resource\Detectors; use OpenTelemetry\SDK\Common\Attribute\Attributes; +use OpenTelemetry\SDK\Common\Configuration\Configuration; +use OpenTelemetry\SDK\Common\Configuration\Variables; use OpenTelemetry\SDK\Resource\ResourceDetectorInterface; use OpenTelemetry\SDK\Resource\ResourceInfo; use OpenTelemetry\SemConv\ResourceAttributes; @@ -19,10 +21,16 @@ public function getResource(): ResourceInfo { static $serviceInstanceId; $serviceInstanceId ??= Uuid::uuid4()->toString(); + $serviceName = Configuration::has(Variables::OTEL_SERVICE_NAME) + ? Configuration::getString(Variables::OTEL_SERVICE_NAME) + : null; $attributes = [ ResourceAttributes::SERVICE_INSTANCE_ID => $serviceInstanceId, ]; + if ($serviceName !== null) { + $attributes[ResourceAttributes::SERVICE_NAME] = $serviceName; + } return ResourceInfo::create(Attributes::create($attributes), ResourceAttributes::SCHEMA_URL); } diff --git a/Resource/ResourceInfoFactory.php b/Resource/ResourceInfoFactory.php index 62759dd..0a07343 100644 --- a/Resource/ResourceInfoFactory.php +++ b/Resource/ResourceInfoFactory.php @@ -11,6 +11,7 @@ use OpenTelemetry\SDK\Common\Configuration\KnownValues as Values; use OpenTelemetry\SDK\Common\Configuration\Variables as Env; use OpenTelemetry\SDK\Registry; +use OpenTelemetry\SemConv\ResourceAttributes; use RuntimeException; class ResourceInfoFactory @@ -27,14 +28,11 @@ public static function defaultResource(): ResourceInfo // ascending priority: keys from later detectors will overwrite earlier return (new Detectors\Composite([ new Detectors\Host(), - new Detectors\OperatingSystem(), new Detectors\Process(), - new Detectors\ProcessRuntime(), - new Detectors\Sdk(), - new Detectors\SdkProvided(), - new Detectors\Composer(), ...Registry::resourceDetectors(), new Detectors\Environment(), + new Detectors\Sdk(), + new Detectors\Service(), ]))->getResource(); } @@ -42,10 +40,6 @@ public static function defaultResource(): ResourceInfo foreach ($detectors as $detector) { switch ($detector) { - case Values::VALUE_DETECTORS_SERVICE: - $resourceDetectors[] = new Detectors\Service(); - - break; case Values::VALUE_DETECTORS_ENVIRONMENT: $resourceDetectors[] = new Detectors\Environment(); @@ -53,32 +47,19 @@ public static function defaultResource(): ResourceInfo case Values::VALUE_DETECTORS_HOST: $resourceDetectors[] = new Detectors\Host(); - break; - case Values::VALUE_DETECTORS_OS: - $resourceDetectors[] = new Detectors\OperatingSystem(); - break; case Values::VALUE_DETECTORS_PROCESS: $resourceDetectors[] = new Detectors\Process(); - break; - case Values::VALUE_DETECTORS_PROCESS_RUNTIME: - $resourceDetectors[] = new Detectors\ProcessRuntime(); - - break; - case Values::VALUE_DETECTORS_SDK: - $resourceDetectors[] = new Detectors\Sdk(); - - break; - case Values::VALUE_DETECTORS_SDK_PROVIDED: - $resourceDetectors[] = new Detectors\SdkProvided(); - break; case Values::VALUE_DETECTORS_COMPOSER: $resourceDetectors[] = new Detectors\Composer(); break; + case Values::VALUE_DETECTORS_SDK_PROVIDED: //deprecated + case Values::VALUE_DETECTORS_OS: //deprecated + case Values::VALUE_DETECTORS_PROCESS_RUNTIME: //deprecated case Values::VALUE_NONE: break; @@ -90,6 +71,8 @@ public static function defaultResource(): ResourceInfo } } } + $resourceDetectors [] = new Detectors\Sdk(); + $resourceDetectors [] = new Detectors\Service(); return (new Detectors\Composite($resourceDetectors))->getResource(); } @@ -102,4 +85,15 @@ public static function emptyResource(): ResourceInfo return self::$emptyResource; } + + public static function mandatoryResource(): ResourceInfo + { + return ResourceInfo::create( + Attributes::create( + [ + ResourceAttributes::SERVICE_NAME => 'unknown_service:php', + ], + ) + ); + } } From 05d9ceb6773b5bddcf485af6d4a6f543bbeb980b Mon Sep 17 00:00:00 2001 From: Bartosz Tomczak Date: Fri, 2 May 2025 01:20:43 +0200 Subject: [PATCH 3/3] Use timeout to set max_duration on symfony http client (#1575) --- Common/Http/Psr/Client/Discovery/Symfony.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Common/Http/Psr/Client/Discovery/Symfony.php b/Common/Http/Psr/Client/Discovery/Symfony.php index b2c8932..dcc0588 100644 --- a/Common/Http/Psr/Client/Discovery/Symfony.php +++ b/Common/Http/Psr/Client/Discovery/Symfony.php @@ -23,6 +23,10 @@ public function available(): bool */ public function create(mixed $options): ClientInterface { + if (is_array($options) && array_key_exists('timeout', $options)) { + $options['max_duration'] = $options['timeout']; + } + return new Psr18Client(HttpClient::create($options)); } }