diff options
Diffstat (limited to 'vendor/open-telemetry/sdk/Metrics/Exemplar')
11 files changed, 361 insertions, 0 deletions
diff --git a/vendor/open-telemetry/sdk/Metrics/Exemplar/BucketEntry.php b/vendor/open-telemetry/sdk/Metrics/Exemplar/BucketEntry.php new file mode 100644 index 000000000..3a50430ed --- /dev/null +++ b/vendor/open-telemetry/sdk/Metrics/Exemplar/BucketEntry.php @@ -0,0 +1,26 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\SDK\Metrics\Exemplar; + +use OpenTelemetry\SDK\Common\Attribute\AttributesInterface; + +/** + * @internal + */ +final class BucketEntry +{ + /** + * @var int|string + */ + public $index; + /** + * @var float|int + */ + public $value; + public int $timestamp; + public AttributesInterface $attributes; + public ?string $traceId = null; + public ?string $spanId = null; +} diff --git a/vendor/open-telemetry/sdk/Metrics/Exemplar/BucketStorage.php b/vendor/open-telemetry/sdk/Metrics/Exemplar/BucketStorage.php new file mode 100644 index 000000000..574ce92af --- /dev/null +++ b/vendor/open-telemetry/sdk/Metrics/Exemplar/BucketStorage.php @@ -0,0 +1,92 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\SDK\Metrics\Exemplar; + +use function array_fill; +use function assert; +use function count; +use OpenTelemetry\API\Trace\Span; +use OpenTelemetry\Context\ContextInterface; +use OpenTelemetry\SDK\Common\Attribute\Attributes; +use OpenTelemetry\SDK\Common\Attribute\AttributesInterface; +use OpenTelemetry\SDK\Metrics\Data\Exemplar; + +/** + * @internal + */ +final class BucketStorage +{ + /** @var array<int, BucketEntry|null> */ + private array $buckets; + + public function __construct(int $size = 0) + { + $this->buckets = array_fill(0, $size, null); + } + + /** + * @param int|string $index + * @param float|int $value + */ + public function store(int $bucket, $index, $value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): void + { + assert($bucket <= count($this->buckets)); + + $exemplar = $this->buckets[$bucket] ??= new BucketEntry(); + $exemplar->index = $index; + $exemplar->value = $value; + $exemplar->timestamp = $timestamp; + $exemplar->attributes = $attributes; + + if (($spanContext = Span::fromContext($context)->getContext())->isValid()) { + $exemplar->traceId = $spanContext->getTraceId(); + $exemplar->spanId = $spanContext->getSpanId(); + } else { + $exemplar->traceId = null; + $exemplar->spanId = null; + } + } + + /** + * @param array<AttributesInterface> $dataPointAttributes + * @return array<Exemplar> + */ + public function collect(array $dataPointAttributes): array + { + $exemplars = []; + foreach ($this->buckets as $index => &$exemplar) { + if (!$exemplar) { + continue; + } + + $exemplars[$index] = new Exemplar( + $exemplar->index, + $exemplar->value, + $exemplar->timestamp, + $this->filterExemplarAttributes( + $dataPointAttributes[$exemplar->index], + $exemplar->attributes, + ), + $exemplar->traceId, + $exemplar->spanId, + ); + $exemplar = null; + } + + return $exemplars; + } + + private function filterExemplarAttributes(AttributesInterface $dataPointAttributes, AttributesInterface $exemplarAttributes): AttributesInterface + { + $attributes = []; + foreach ($exemplarAttributes as $key => $value) { + if ($dataPointAttributes->get($key) === null) { + $attributes[$key] = $value; + } + } + + return new Attributes($attributes, $exemplarAttributes->getDroppedAttributesCount()); + } +} diff --git a/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilter/AllExemplarFilter.php b/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilter/AllExemplarFilter.php new file mode 100644 index 000000000..b74e738aa --- /dev/null +++ b/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilter/AllExemplarFilter.php @@ -0,0 +1,21 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilter; + +use OpenTelemetry\Context\ContextInterface; +use OpenTelemetry\SDK\Common\Attribute\AttributesInterface; +use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilterInterface; + +/** + * The exemplar spec is not yet stable, and can change at any time. + * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exemplar + */ +final class AllExemplarFilter implements ExemplarFilterInterface +{ + public function accepts($value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): bool + { + return true; + } +} diff --git a/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilter/NoneExemplarFilter.php b/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilter/NoneExemplarFilter.php new file mode 100644 index 000000000..91fdf3b55 --- /dev/null +++ b/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilter/NoneExemplarFilter.php @@ -0,0 +1,21 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilter; + +use OpenTelemetry\Context\ContextInterface; +use OpenTelemetry\SDK\Common\Attribute\AttributesInterface; +use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilterInterface; + +/** + * The exemplar spec is not yet stable, and can change at any time. + * see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exemplar + */ +final class NoneExemplarFilter implements ExemplarFilterInterface +{ + public function accepts($value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): bool + { + return false; + } +} diff --git a/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilter/WithSampledTraceExemplarFilter.php b/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilter/WithSampledTraceExemplarFilter.php new file mode 100644 index 000000000..3e800b416 --- /dev/null +++ b/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilter/WithSampledTraceExemplarFilter.php @@ -0,0 +1,22 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilter; + +use OpenTelemetry\API\Trace\Span; +use OpenTelemetry\Context\ContextInterface; +use OpenTelemetry\SDK\Common\Attribute\AttributesInterface; +use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilterInterface; + +/** + * The exemplar spec is not yet stable, and can change at any time. + * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exemplar + */ +final class WithSampledTraceExemplarFilter implements ExemplarFilterInterface +{ + public function accepts($value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): bool + { + return Span::fromContext($context)->getContext()->isSampled(); + } +} diff --git a/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilterInterface.php b/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilterInterface.php new file mode 100644 index 000000000..1d5dec7b8 --- /dev/null +++ b/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilterInterface.php @@ -0,0 +1,20 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\SDK\Metrics\Exemplar; + +use OpenTelemetry\Context\ContextInterface; +use OpenTelemetry\SDK\Common\Attribute\AttributesInterface; + +/** + * The exemplar spec is not yet stable, and can change at any time. + * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exemplar + */ +interface ExemplarFilterInterface +{ + /** + * @param float|int $value + */ + public function accepts($value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): bool; +} diff --git a/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarReservoirInterface.php b/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarReservoirInterface.php new file mode 100644 index 000000000..70648b919 --- /dev/null +++ b/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarReservoirInterface.php @@ -0,0 +1,24 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\SDK\Metrics\Exemplar; + +use OpenTelemetry\Context\ContextInterface; +use OpenTelemetry\SDK\Common\Attribute\AttributesInterface; +use OpenTelemetry\SDK\Metrics\Data\Exemplar; + +interface ExemplarReservoirInterface +{ + /** + * @param int|string $index + * @param float|int $value + */ + public function offer($index, $value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): void; + + /** + * @param array<AttributesInterface> $dataPointAttributes + * @return array<Exemplar> + */ + public function collect(array $dataPointAttributes): array; +} diff --git a/vendor/open-telemetry/sdk/Metrics/Exemplar/FilteredReservoir.php b/vendor/open-telemetry/sdk/Metrics/Exemplar/FilteredReservoir.php new file mode 100644 index 000000000..0e4f24357 --- /dev/null +++ b/vendor/open-telemetry/sdk/Metrics/Exemplar/FilteredReservoir.php @@ -0,0 +1,36 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\SDK\Metrics\Exemplar; + +use OpenTelemetry\Context\ContextInterface; +use OpenTelemetry\SDK\Common\Attribute\AttributesInterface; + +/** + * The exemplar spec is not yet stable, and can change at any time. + * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exemplar + */ +final class FilteredReservoir implements ExemplarReservoirInterface +{ + private ExemplarReservoirInterface $reservoir; + private ExemplarFilterInterface $filter; + + public function __construct(ExemplarReservoirInterface $reservoir, ExemplarFilterInterface $filter) + { + $this->reservoir = $reservoir; + $this->filter = $filter; + } + + public function offer($index, $value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): void + { + if ($this->filter->accepts($value, $attributes, $context, $timestamp)) { + $this->reservoir->offer($index, $value, $attributes, $context, $timestamp); + } + } + + public function collect(array $dataPointAttributes): array + { + return $this->reservoir->collect($dataPointAttributes); + } +} diff --git a/vendor/open-telemetry/sdk/Metrics/Exemplar/FixedSizeReservoir.php b/vendor/open-telemetry/sdk/Metrics/Exemplar/FixedSizeReservoir.php new file mode 100644 index 000000000..479292a4c --- /dev/null +++ b/vendor/open-telemetry/sdk/Metrics/Exemplar/FixedSizeReservoir.php @@ -0,0 +1,38 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\SDK\Metrics\Exemplar; + +use OpenTelemetry\Context\ContextInterface; +use OpenTelemetry\SDK\Common\Attribute\AttributesInterface; +use function random_int; + +final class FixedSizeReservoir implements ExemplarReservoirInterface +{ + private BucketStorage $storage; + private int $size; + private int $measurements = 0; + + public function __construct(int $size = 4) + { + $this->storage = new BucketStorage($size); + $this->size = $size; + } + + public function offer($index, $value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): void + { + $bucket = random_int(0, $this->measurements); + $this->measurements++; + if ($bucket < $this->size) { + $this->storage->store($bucket, $index, $value, $attributes, $context, $timestamp); + } + } + + public function collect(array $dataPointAttributes): array + { + $this->measurements = 0; + + return $this->storage->collect($dataPointAttributes); + } +} diff --git a/vendor/open-telemetry/sdk/Metrics/Exemplar/HistogramBucketReservoir.php b/vendor/open-telemetry/sdk/Metrics/Exemplar/HistogramBucketReservoir.php new file mode 100644 index 000000000..b56a1b2be --- /dev/null +++ b/vendor/open-telemetry/sdk/Metrics/Exemplar/HistogramBucketReservoir.php @@ -0,0 +1,40 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\SDK\Metrics\Exemplar; + +use function count; +use OpenTelemetry\Context\ContextInterface; +use OpenTelemetry\SDK\Common\Attribute\AttributesInterface; + +final class HistogramBucketReservoir implements ExemplarReservoirInterface +{ + private BucketStorage $storage; + /** + * @var list<float|int> + */ + private array $boundaries; + + /** + * @param list<float|int> $boundaries + */ + public function __construct(array $boundaries) + { + $this->storage = new BucketStorage(count($boundaries) + 1); + $this->boundaries = $boundaries; + } + + public function offer($index, $value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): void + { + $boundariesCount = count($this->boundaries); + for ($i = 0; $i < $boundariesCount && $this->boundaries[$i] < $value; $i++) { + } + $this->storage->store($i, $index, $value, $attributes, $context, $timestamp); + } + + public function collect(array $dataPointAttributes): array + { + return $this->storage->collect($dataPointAttributes); + } +} diff --git a/vendor/open-telemetry/sdk/Metrics/Exemplar/NoopReservoir.php b/vendor/open-telemetry/sdk/Metrics/Exemplar/NoopReservoir.php new file mode 100644 index 000000000..010aeff20 --- /dev/null +++ b/vendor/open-telemetry/sdk/Metrics/Exemplar/NoopReservoir.php @@ -0,0 +1,21 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\SDK\Metrics\Exemplar; + +use OpenTelemetry\Context\ContextInterface; +use OpenTelemetry\SDK\Common\Attribute\AttributesInterface; + +final class NoopReservoir implements ExemplarReservoirInterface +{ + public function offer($index, $value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): void + { + // no-op + } + + public function collect(array $dataPointAttributes): array + { + return []; + } +} |