diff options
Diffstat (limited to 'vendor/open-telemetry/sdk/Common/Attribute')
11 files changed, 462 insertions, 0 deletions
diff --git a/vendor/open-telemetry/sdk/Common/Attribute/AttributeValidator.php b/vendor/open-telemetry/sdk/Common/Attribute/AttributeValidator.php new file mode 100644 index 000000000..e9a1f7334 --- /dev/null +++ b/vendor/open-telemetry/sdk/Common/Attribute/AttributeValidator.php @@ -0,0 +1,58 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\SDK\Common\Attribute; + +class AttributeValidator implements AttributeValidatorInterface +{ + private const PRIMITIVES = [ + 'string', + 'integer', + 'double', + 'boolean', + ]; + private const NUMERICS = [ + 'double', + 'integer', + ]; + + /** + * Validate whether a value is a primitive, or a homogeneous array of primitives (treating int/double as equivalent). + * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.21.0/specification/common/README.md#attribute + */ + public function validate($value): bool + { + if (is_array($value)) { + return $this->validateArray($value); + } + + return in_array(gettype($value), self::PRIMITIVES); + } + + private function validateArray(array $value): bool + { + if ($value === []) { + return true; + } + $type = gettype(reset($value)); + if (!in_array($type, self::PRIMITIVES)) { + return false; + } + foreach ($value as $v) { + if (in_array(gettype($v), self::NUMERICS) && in_array($type, self::NUMERICS)) { + continue; + } + if (gettype($v) !== $type) { + return false; + } + } + + return true; + } + + public function getInvalidMessage(): string + { + return 'attribute with non-primitive or non-homogeneous array of primitives dropped'; + } +} diff --git a/vendor/open-telemetry/sdk/Common/Attribute/AttributeValidatorInterface.php b/vendor/open-telemetry/sdk/Common/Attribute/AttributeValidatorInterface.php new file mode 100644 index 000000000..afbfba6e7 --- /dev/null +++ b/vendor/open-telemetry/sdk/Common/Attribute/AttributeValidatorInterface.php @@ -0,0 +1,11 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\SDK\Common\Attribute; + +interface AttributeValidatorInterface +{ + public function validate($value): bool; + public function getInvalidMessage(): string; +} diff --git a/vendor/open-telemetry/sdk/Common/Attribute/Attributes.php b/vendor/open-telemetry/sdk/Common/Attribute/Attributes.php new file mode 100644 index 000000000..bb131ce94 --- /dev/null +++ b/vendor/open-telemetry/sdk/Common/Attribute/Attributes.php @@ -0,0 +1,67 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\SDK\Common\Attribute; + +use function array_key_exists; +use IteratorAggregate; +use Traversable; + +final class Attributes implements AttributesInterface, IteratorAggregate +{ + private array $attributes; + private int $droppedAttributesCount; + + /** + * @internal + */ + public function __construct(array $attributes, int $droppedAttributesCount) + { + $this->attributes = $attributes; + $this->droppedAttributesCount = $droppedAttributesCount; + } + + public static function create(iterable $attributes): AttributesInterface + { + return self::factory()->builder($attributes)->build(); + } + + public static function factory(?int $attributeCountLimit = null, ?int $attributeValueLengthLimit = null): AttributesFactoryInterface + { + return new AttributesFactory($attributeCountLimit, $attributeValueLengthLimit); + } + + public function has(string $name): bool + { + return array_key_exists($name, $this->attributes); + } + + public function get(string $name) + { + return $this->attributes[$name] ?? null; + } + + /** @psalm-mutation-free */ + public function count(): int + { + return \count($this->attributes); + } + + public function getIterator(): Traversable + { + foreach ($this->attributes as $key => $value) { + yield (string) $key => $value; + } + } + + public function toArray(): array + { + return $this->attributes; + } + + public function getDroppedAttributesCount(): int + { + return $this->droppedAttributesCount; + } +} diff --git a/vendor/open-telemetry/sdk/Common/Attribute/AttributesBuilder.php b/vendor/open-telemetry/sdk/Common/Attribute/AttributesBuilder.php new file mode 100644 index 000000000..5c1150638 --- /dev/null +++ b/vendor/open-telemetry/sdk/Common/Attribute/AttributesBuilder.php @@ -0,0 +1,120 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\SDK\Common\Attribute; + +use function array_key_exists; +use function count; +use function is_array; +use function is_string; +use function mb_substr; +use OpenTelemetry\API\Behavior\LogsMessagesTrait; + +/** + * @internal + */ +final class AttributesBuilder implements AttributesBuilderInterface +{ + use LogsMessagesTrait; + + private array $attributes; + private ?int $attributeCountLimit; + private ?int $attributeValueLengthLimit; + private int $droppedAttributesCount; + private AttributeValidatorInterface $attributeValidator; + + public function __construct( + array $attributes, + ?int $attributeCountLimit, + ?int $attributeValueLengthLimit, + int $droppedAttributesCount, + ?AttributeValidatorInterface $attributeValidator + ) { + $this->attributes = $attributes; + $this->attributeCountLimit = $attributeCountLimit; + $this->attributeValueLengthLimit = $attributeValueLengthLimit; + $this->droppedAttributesCount = $droppedAttributesCount; + $this->attributeValidator = $attributeValidator ?? new AttributeValidator(); + } + + public function build(): AttributesInterface + { + return new Attributes($this->attributes, $this->droppedAttributesCount); + } + + public function offsetExists($offset): bool + { + return array_key_exists($offset, $this->attributes); + } + + /** + * @phan-suppress PhanUndeclaredClassAttribute + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + return $this->attributes[$offset] ?? null; + } + + /** + * @phan-suppress PhanUndeclaredClassAttribute + */ + #[\ReturnTypeWillChange] + public function offsetSet($offset, $value) + { + if ($offset === null) { + return; + } + if ($value === null) { + unset($this->attributes[$offset]); + + return; + } + if (!$this->attributeValidator->validate($value)) { + self::logWarning($this->attributeValidator->getInvalidMessage() . ': ' . $offset); + $this->droppedAttributesCount++; + + return; + } + if (count($this->attributes) === $this->attributeCountLimit && !array_key_exists($offset, $this->attributes)) { + $this->droppedAttributesCount++; + + return; + } + + $this->attributes[$offset] = $this->normalizeValue($value); + //@todo "There SHOULD be a message printed in the SDK's log to indicate to the user that an attribute was + // discarded due to such a limit. To prevent excessive logging, the message MUST be printed at most + // once per <thing> (i.e., not per discarded attribute)." + } + + /** + * @phan-suppress PhanUndeclaredClassAttribute + */ + #[\ReturnTypeWillChange] + public function offsetUnset($offset) + { + unset($this->attributes[$offset]); + } + + private function normalizeValue($value) + { + if (is_string($value) && $this->attributeValueLengthLimit !== null) { + return mb_substr($value, 0, $this->attributeValueLengthLimit); + } + + if (is_array($value)) { + foreach ($value as $k => $v) { + $processed = $this->normalizeValue($v); + if ($processed !== $v) { + $value[$k] = $processed; + } + } + + return $value; + } + + return $value; + } +} diff --git a/vendor/open-telemetry/sdk/Common/Attribute/AttributesBuilderInterface.php b/vendor/open-telemetry/sdk/Common/Attribute/AttributesBuilderInterface.php new file mode 100644 index 000000000..7e3d64062 --- /dev/null +++ b/vendor/open-telemetry/sdk/Common/Attribute/AttributesBuilderInterface.php @@ -0,0 +1,12 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\SDK\Common\Attribute; + +use ArrayAccess; + +interface AttributesBuilderInterface extends ArrayAccess +{ + public function build(): AttributesInterface; +} diff --git a/vendor/open-telemetry/sdk/Common/Attribute/AttributesFactory.php b/vendor/open-telemetry/sdk/Common/Attribute/AttributesFactory.php new file mode 100644 index 000000000..d53ab25aa --- /dev/null +++ b/vendor/open-telemetry/sdk/Common/Attribute/AttributesFactory.php @@ -0,0 +1,36 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\SDK\Common\Attribute; + +/** + * @internal + */ +final class AttributesFactory implements AttributesFactoryInterface +{ + private ?int $attributeCountLimit; + private ?int $attributeValueLengthLimit; + + public function __construct(?int $attributeCountLimit = null, ?int $attributeValueLengthLimit = null) + { + $this->attributeCountLimit = $attributeCountLimit; + $this->attributeValueLengthLimit = $attributeValueLengthLimit; + } + + public function builder(iterable $attributes = [], ?AttributeValidatorInterface $attributeValidator = null): AttributesBuilderInterface + { + $builder = new AttributesBuilder( + [], + $this->attributeCountLimit, + $this->attributeValueLengthLimit, + 0, + $attributeValidator, + ); + foreach ($attributes as $key => $value) { + $builder[$key] = $value; + } + + return $builder; + } +} diff --git a/vendor/open-telemetry/sdk/Common/Attribute/AttributesFactoryInterface.php b/vendor/open-telemetry/sdk/Common/Attribute/AttributesFactoryInterface.php new file mode 100644 index 000000000..1b74461d4 --- /dev/null +++ b/vendor/open-telemetry/sdk/Common/Attribute/AttributesFactoryInterface.php @@ -0,0 +1,10 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\SDK\Common\Attribute; + +interface AttributesFactoryInterface +{ + public function builder(iterable $attributes = [], ?AttributeValidatorInterface $attributeValidator = null): AttributesBuilderInterface; +} diff --git a/vendor/open-telemetry/sdk/Common/Attribute/AttributesInterface.php b/vendor/open-telemetry/sdk/Common/Attribute/AttributesInterface.php new file mode 100644 index 000000000..1af7dc8d9 --- /dev/null +++ b/vendor/open-telemetry/sdk/Common/Attribute/AttributesInterface.php @@ -0,0 +1,19 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\SDK\Common\Attribute; + +use Countable; +use Traversable; + +interface AttributesInterface extends Traversable, Countable +{ + public function has(string $name): bool; + + public function get(string $name); + + public function getDroppedAttributesCount(): int; + + public function toArray(): array; +} diff --git a/vendor/open-telemetry/sdk/Common/Attribute/FilteredAttributesBuilder.php b/vendor/open-telemetry/sdk/Common/Attribute/FilteredAttributesBuilder.php new file mode 100644 index 000000000..d79cff96a --- /dev/null +++ b/vendor/open-telemetry/sdk/Common/Attribute/FilteredAttributesBuilder.php @@ -0,0 +1,77 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\SDK\Common\Attribute; + +use function in_array; + +/** + * @internal + */ +final class FilteredAttributesBuilder implements AttributesBuilderInterface +{ + private AttributesBuilderInterface $builder; + private array $rejectedKeys; + private int $rejected = 0; + + /** + * @param list<string> $rejectedKeys + */ + public function __construct(AttributesBuilderInterface $builder, array $rejectedKeys) + { + $this->builder = $builder; + $this->rejectedKeys = $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 offsetExists($offset): bool + { + return $this->builder->offsetExists($offset); + } + + /** + * @phan-suppress PhanUndeclaredClassAttribute + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + return $this->builder->offsetGet($offset); + } + + /** + * @phan-suppress PhanUndeclaredClassAttribute + */ + #[\ReturnTypeWillChange] + public function offsetSet($offset, $value) + { + if ($value !== null && in_array($offset, $this->rejectedKeys, true)) { + $this->rejected++; + + return; + } + + $this->builder->offsetSet($offset, $value); + } + + /** + * @phan-suppress PhanUndeclaredClassAttribute + */ + #[\ReturnTypeWillChange] + public function offsetUnset($offset) + { + $this->builder->offsetUnset($offset); + } +} diff --git a/vendor/open-telemetry/sdk/Common/Attribute/FilteredAttributesFactory.php b/vendor/open-telemetry/sdk/Common/Attribute/FilteredAttributesFactory.php new file mode 100644 index 000000000..1d9c4ae1c --- /dev/null +++ b/vendor/open-telemetry/sdk/Common/Attribute/FilteredAttributesFactory.php @@ -0,0 +1,33 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\SDK\Common\Attribute; + +/** + * @internal + */ +final class FilteredAttributesFactory implements AttributesFactoryInterface +{ + private AttributesFactoryInterface $factory; + private array $rejectedKeys; + + /** + * @param list<string> $rejectedKeys + */ + public function __construct(AttributesFactoryInterface $factory, array $rejectedKeys) + { + $this->factory = $factory; + $this->rejectedKeys = $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/vendor/open-telemetry/sdk/Common/Attribute/LogRecordAttributeValidator.php b/vendor/open-telemetry/sdk/Common/Attribute/LogRecordAttributeValidator.php new file mode 100644 index 000000000..a09d26372 --- /dev/null +++ b/vendor/open-telemetry/sdk/Common/Attribute/LogRecordAttributeValidator.php @@ -0,0 +1,19 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\SDK\Common\Attribute; + +class LogRecordAttributeValidator implements AttributeValidatorInterface +{ + public function validate($value): bool + { + return true; + } + + public function getInvalidMessage(): string + { + //not required as this validator always returns true + return 'unused'; + } +} |