summaryrefslogtreecommitdiff
path: root/vendor/open-telemetry/sdk/Metrics
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/open-telemetry/sdk/Metrics')
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Aggregation/ExplicitBucketHistogramAggregation.php167
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Aggregation/ExplicitBucketHistogramSummary.php40
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Aggregation/LastValueAggregation.php81
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Aggregation/LastValueSummary.php22
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Aggregation/SumAggregation.php91
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Aggregation/SumSummary.php20
-rw-r--r--vendor/open-telemetry/sdk/Metrics/AggregationInterface.php57
-rw-r--r--vendor/open-telemetry/sdk/Metrics/AggregationTemporalitySelectorInterface.php21
-rw-r--r--vendor/open-telemetry/sdk/Metrics/AttributeProcessor/FilteredAttributeProcessor.php33
-rw-r--r--vendor/open-telemetry/sdk/Metrics/AttributeProcessor/IdentityAttributeProcessor.php20
-rw-r--r--vendor/open-telemetry/sdk/Metrics/AttributeProcessorInterface.php16
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Counter.php37
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Data/DataInterface.php9
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Data/Exemplar.php65
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Data/Gauge.php22
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Data/Histogram.php29
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Data/HistogramDataPoint.php76
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Data/Metric.php46
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Data/NumberDataPoint.php43
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Data/Sum.php34
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Data/Temporality.php20
-rw-r--r--vendor/open-telemetry/sdk/Metrics/DefaultAggregationProviderInterface.php13
-rw-r--r--vendor/open-telemetry/sdk/Metrics/DefaultAggregationProviderTrait.php28
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Exemplar/BucketEntry.php26
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Exemplar/BucketStorage.php92
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilter/AllExemplarFilter.php21
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilter/NoneExemplarFilter.php21
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilter/WithSampledTraceExemplarFilter.php22
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilterInterface.php20
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarReservoirInterface.php24
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Exemplar/FilteredReservoir.php36
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Exemplar/FixedSizeReservoir.php38
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Exemplar/HistogramBucketReservoir.php40
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Exemplar/NoopReservoir.php21
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Histogram.php37
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Instrument.php36
-rw-r--r--vendor/open-telemetry/sdk/Metrics/InstrumentType.php25
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Meter.php314
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MeterInstruments.php29
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MeterProvider.php130
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MeterProviderBuilder.php62
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MeterProviderFactory.php78
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MeterProviderInterface.php12
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricExporter/ConsoleMetricExporter.php105
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricExporter/ConsoleMetricExporterFactory.php16
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricExporter/InMemoryExporter.php78
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricExporter/InMemoryExporterFactory.php16
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricExporter/NoopMetricExporter.php23
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricExporter/NoopMetricExporterFactory.php16
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricExporter/_register.php7
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricExporterFactoryInterface.php10
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricExporterInterface.php17
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricFactory/StreamFactory.php187
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricFactory/StreamMetricSource.php44
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricFactory/StreamMetricSourceProvider.php98
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricFactoryInterface.php41
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricMetadataInterface.php28
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricReader/ExportingReader.php156
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricReaderInterface.php14
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricRegistration/MultiRegistryRegistration.php36
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricRegistration/RegistryRegistration.php31
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricRegistrationInterface.php13
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricCollectorInterface.php13
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricRegistry.php184
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricRegistryInterface.php22
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricWriterInterface.php20
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricRegistry/MultiObserver.php37
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricRegistry/NoopObserver.php18
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricSourceInterface.php24
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricSourceProviderInterface.php15
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricSourceRegistryInterface.php10
-rw-r--r--vendor/open-telemetry/sdk/Metrics/NoopMeterProvider.php26
-rw-r--r--vendor/open-telemetry/sdk/Metrics/ObservableCallback.php58
-rw-r--r--vendor/open-telemetry/sdk/Metrics/ObservableCallbackDestructor.php32
-rw-r--r--vendor/open-telemetry/sdk/Metrics/ObservableCounter.php15
-rw-r--r--vendor/open-telemetry/sdk/Metrics/ObservableGauge.php15
-rw-r--r--vendor/open-telemetry/sdk/Metrics/ObservableInstrumentTrait.php61
-rw-r--r--vendor/open-telemetry/sdk/Metrics/ObservableUpDownCounter.php15
-rw-r--r--vendor/open-telemetry/sdk/Metrics/PushMetricExporterInterface.php12
-rw-r--r--vendor/open-telemetry/sdk/Metrics/ReferenceCounterInterface.php15
-rw-r--r--vendor/open-telemetry/sdk/Metrics/StalenessHandler/DelayedStalenessHandler.php71
-rw-r--r--vendor/open-telemetry/sdk/Metrics/StalenessHandler/DelayedStalenessHandlerFactory.php64
-rw-r--r--vendor/open-telemetry/sdk/Metrics/StalenessHandler/ImmediateStalenessHandler.php50
-rw-r--r--vendor/open-telemetry/sdk/Metrics/StalenessHandler/ImmediateStalenessHandlerFactory.php16
-rw-r--r--vendor/open-telemetry/sdk/Metrics/StalenessHandler/NoopStalenessHandler.php30
-rw-r--r--vendor/open-telemetry/sdk/Metrics/StalenessHandler/NoopStalenessHandlerFactory.php18
-rw-r--r--vendor/open-telemetry/sdk/Metrics/StalenessHandlerFactoryInterface.php13
-rw-r--r--vendor/open-telemetry/sdk/Metrics/StalenessHandlerInterface.php12
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Stream/AsynchronousMetricStream.php111
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Stream/Delta.php33
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Stream/DeltaStorage.php110
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Stream/Metric.php44
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregator.php73
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregatorFactory.php28
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregatorFactoryInterface.php13
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregatorInterface.php12
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Stream/MetricCollectorInterface.php13
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Stream/MetricStreamInterface.php58
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Stream/SynchronousMetricStream.php126
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Stream/WritableMetricStreamInterface.php19
-rw-r--r--vendor/open-telemetry/sdk/Metrics/UpDownCounter.php37
-rw-r--r--vendor/open-telemetry/sdk/Metrics/View/CriteriaViewRegistry.php40
-rw-r--r--vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/AllCriteria.php33
-rw-r--r--vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentNameCriteria.php28
-rw-r--r--vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentTypeCriteria.php29
-rw-r--r--vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentationScopeNameCriteria.php24
-rw-r--r--vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentationScopeSchemaUrlCriteria.php24
-rw-r--r--vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentationScopeVersionCriteria.php24
-rw-r--r--vendor/open-telemetry/sdk/Metrics/View/SelectionCriteriaInterface.php13
-rw-r--r--vendor/open-telemetry/sdk/Metrics/View/ViewTemplate.php77
-rw-r--r--vendor/open-telemetry/sdk/Metrics/ViewProjection.php47
-rw-r--r--vendor/open-telemetry/sdk/Metrics/ViewRegistryInterface.php15
112 files changed, 4907 insertions, 0 deletions
diff --git a/vendor/open-telemetry/sdk/Metrics/Aggregation/ExplicitBucketHistogramAggregation.php b/vendor/open-telemetry/sdk/Metrics/Aggregation/ExplicitBucketHistogramAggregation.php
new file mode 100644
index 000000000..d68ecd830
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Aggregation/ExplicitBucketHistogramAggregation.php
@@ -0,0 +1,167 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Aggregation;
+
+use function array_fill;
+use function count;
+use const INF;
+use const NAN;
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Metrics\AggregationInterface;
+use OpenTelemetry\SDK\Metrics\Data;
+
+/**
+ * @implements AggregationInterface<ExplicitBucketHistogramSummary>
+ */
+final class ExplicitBucketHistogramAggregation implements AggregationInterface
+{
+ /**
+ * @var list<float|int>
+ * @readonly
+ */
+ public array $boundaries;
+
+ /**
+ * @param list<float|int> $boundaries strictly ascending histogram bucket boundaries
+ */
+ public function __construct(array $boundaries)
+ {
+ $this->boundaries = $boundaries;
+ }
+
+ public function initialize(): ExplicitBucketHistogramSummary
+ {
+ return new ExplicitBucketHistogramSummary(
+ 0,
+ 0,
+ +INF,
+ -INF,
+ array_fill(0, count($this->boundaries) + 1, 0),
+ );
+ }
+
+ /**
+ * @param ExplicitBucketHistogramSummary $summary
+ */
+ public function record($summary, $value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): void
+ {
+ $boundariesCount = count($this->boundaries);
+ for ($i = 0; $i < $boundariesCount && $this->boundaries[$i] < $value; $i++) {
+ }
+ $summary->count++;
+ $summary->sum += $value;
+ $summary->min = self::min($value, $summary->min);
+ $summary->max = self::max($value, $summary->max);
+ $summary->buckets[$i]++;
+ }
+
+ /**
+ * @param ExplicitBucketHistogramSummary $left
+ * @param ExplicitBucketHistogramSummary $right
+ */
+ public function merge($left, $right): ExplicitBucketHistogramSummary
+ {
+ $count = $left->count + $right->count;
+ $sum = $left->sum + $right->sum;
+ $min = self::min($left->min, $right->min);
+ $max = self::max($left->max, $right->max);
+ $buckets = $right->buckets;
+ foreach ($left->buckets as $i => $bucketCount) {
+ $buckets[$i] += $bucketCount;
+ }
+
+ return new ExplicitBucketHistogramSummary(
+ $count,
+ $sum,
+ $min,
+ $max,
+ $buckets,
+ );
+ }
+
+ /**
+ * @param ExplicitBucketHistogramSummary $left
+ * @param ExplicitBucketHistogramSummary $right
+ */
+ public function diff($left, $right): ExplicitBucketHistogramSummary
+ {
+ $count = -$left->count + $right->count;
+ $sum = -$left->sum + $right->sum;
+ $min = $left->min > $right->min ? $right->min : NAN;
+ $max = $left->max < $right->max ? $right->max : NAN;
+ $buckets = $right->buckets;
+ foreach ($left->buckets as $i => $bucketCount) {
+ $buckets[$i] -= $bucketCount;
+ }
+
+ return new ExplicitBucketHistogramSummary(
+ $count,
+ $sum,
+ $min,
+ $max,
+ $buckets,
+ );
+ }
+
+ /**
+ * @param array<ExplicitBucketHistogramSummary> $summaries
+ */
+ public function toData(
+ array $attributes,
+ array $summaries,
+ array $exemplars,
+ int $startTimestamp,
+ int $timestamp,
+ $temporality
+ ): Data\Histogram {
+ $dataPoints = [];
+ foreach ($attributes as $key => $dataPointAttributes) {
+ if ($summaries[$key]->count === 0) {
+ continue;
+ }
+
+ $dataPoints[] = new Data\HistogramDataPoint(
+ $summaries[$key]->count,
+ $summaries[$key]->sum,
+ $summaries[$key]->min,
+ $summaries[$key]->max,
+ $summaries[$key]->buckets,
+ $this->boundaries,
+ $dataPointAttributes,
+ $startTimestamp,
+ $timestamp,
+ $exemplars[$key] ?? [],
+ );
+ }
+
+ return new Data\Histogram(
+ $dataPoints,
+ $temporality,
+ );
+ }
+
+ /**
+ * @param float|int $left
+ * @param float|int $right
+ * @return float|int
+ */
+ private static function min($left, $right)
+ {
+ /** @noinspection PhpConditionAlreadyCheckedInspection */
+ return $left <= $right ? $left : ($right <= $left ? $right : NAN);
+ }
+
+ /**
+ * @param float|int $left
+ * @param float|int $right
+ * @return float|int
+ */
+ private static function max($left, $right)
+ {
+ /** @noinspection PhpConditionAlreadyCheckedInspection */
+ return $left >= $right ? $left : ($right >= $left ? $right : NAN);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Aggregation/ExplicitBucketHistogramSummary.php b/vendor/open-telemetry/sdk/Metrics/Aggregation/ExplicitBucketHistogramSummary.php
new file mode 100644
index 000000000..1878a34a0
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Aggregation/ExplicitBucketHistogramSummary.php
@@ -0,0 +1,40 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Aggregation;
+
+final class ExplicitBucketHistogramSummary
+{
+ public int $count;
+ /**
+ * @var float|int
+ */
+ public $sum;
+ /**
+ * @var float|int
+ */
+ public $min;
+ /**
+ * @var float|int
+ */
+ public $max;
+ /**
+ * @var int[]
+ */
+ public array $buckets;
+ /**
+ * @param float|int $sum
+ * @param float|int $min
+ * @param float|int $max
+ * @param int[] $buckets
+ */
+ public function __construct(int $count, $sum, $min, $max, array $buckets)
+ {
+ $this->count = $count;
+ $this->sum = $sum;
+ $this->min = $min;
+ $this->max = $max;
+ $this->buckets = $buckets;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Aggregation/LastValueAggregation.php b/vendor/open-telemetry/sdk/Metrics/Aggregation/LastValueAggregation.php
new file mode 100644
index 000000000..aff04e315
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Aggregation/LastValueAggregation.php
@@ -0,0 +1,81 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Aggregation;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Metrics\AggregationInterface;
+use OpenTelemetry\SDK\Metrics\Data;
+
+/**
+ * @implements AggregationInterface<LastValueSummary>
+ */
+final class LastValueAggregation implements AggregationInterface
+{
+ public function initialize(): LastValueSummary
+ {
+ return new LastValueSummary(null, 0);
+ }
+
+ /**
+ * @param LastValueSummary $summary
+ */
+ public function record($summary, $value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): void
+ {
+ if ($summary->value === null || $timestamp >= $summary->timestamp) {
+ $summary->value = $value;
+ $summary->timestamp = $timestamp;
+ }
+ }
+
+ /**
+ * @param LastValueSummary $left
+ * @param LastValueSummary $right
+ */
+ public function merge($left, $right): LastValueSummary
+ {
+ return $right->timestamp >= $left->timestamp ? $right : $left;
+ }
+
+ /**
+ * @param LastValueSummary $left
+ * @param LastValueSummary $right
+ */
+ public function diff($left, $right): LastValueSummary
+ {
+ return $right->timestamp >= $left->timestamp ? $right : $left;
+ }
+
+ /**
+ * @param array<LastValueSummary> $summaries
+ */
+ public function toData(
+ array $attributes,
+ array $summaries,
+ array $exemplars,
+ int $startTimestamp,
+ int $timestamp,
+ $temporality
+ ): Data\Gauge {
+ $dataPoints = [];
+ foreach ($attributes as $key => $dataPointAttributes) {
+ if ($summaries[$key]->value === null) {
+ continue;
+ }
+
+ $dataPoints[] = new Data\NumberDataPoint(
+ $summaries[$key]->value,
+ $dataPointAttributes,
+ $startTimestamp,
+ $timestamp,
+ $exemplars[$key] ?? [],
+ );
+ }
+
+ return new Data\Gauge(
+ $dataPoints,
+ );
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Aggregation/LastValueSummary.php b/vendor/open-telemetry/sdk/Metrics/Aggregation/LastValueSummary.php
new file mode 100644
index 000000000..6cdb5ac9f
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Aggregation/LastValueSummary.php
@@ -0,0 +1,22 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Aggregation;
+
+final class LastValueSummary
+{
+ /**
+ * @var float|int|null
+ */
+ public $value;
+ public int $timestamp;
+ /**
+ * @param float|int|null $value
+ */
+ public function __construct($value, int $timestamp)
+ {
+ $this->value = $value;
+ $this->timestamp = $timestamp;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Aggregation/SumAggregation.php b/vendor/open-telemetry/sdk/Metrics/Aggregation/SumAggregation.php
new file mode 100644
index 000000000..dc317ce73
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Aggregation/SumAggregation.php
@@ -0,0 +1,91 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Aggregation;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Metrics\AggregationInterface;
+use OpenTelemetry\SDK\Metrics\Data;
+
+/**
+ * @implements AggregationInterface<SumSummary>
+ */
+final class SumAggregation implements AggregationInterface
+{
+ private bool $monotonic;
+
+ public function __construct(bool $monotonic = false)
+ {
+ $this->monotonic = $monotonic;
+ }
+
+ public function initialize(): SumSummary
+ {
+ return new SumSummary(0);
+ }
+
+ /**
+ * @param SumSummary $summary
+ */
+ public function record($summary, $value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): void
+ {
+ $summary->value += $value;
+ }
+
+ /**
+ * @param SumSummary $left
+ * @param SumSummary $right
+ */
+ public function merge($left, $right): SumSummary
+ {
+ $sum = $left->value + $right->value;
+
+ return new SumSummary(
+ $sum,
+ );
+ }
+
+ /**
+ * @param SumSummary $left
+ * @param SumSummary $right
+ */
+ public function diff($left, $right): SumSummary
+ {
+ $sum = -$left->value + $right->value;
+
+ return new SumSummary(
+ $sum,
+ );
+ }
+
+ /**
+ * @param array<SumSummary> $summaries
+ */
+ public function toData(
+ array $attributes,
+ array $summaries,
+ array $exemplars,
+ int $startTimestamp,
+ int $timestamp,
+ $temporality
+ ): Data\Sum {
+ $dataPoints = [];
+ foreach ($attributes as $key => $dataPointAttributes) {
+ $dataPoints[] = new Data\NumberDataPoint(
+ $summaries[$key]->value,
+ $dataPointAttributes,
+ $startTimestamp,
+ $timestamp,
+ $exemplars[$key] ?? [],
+ );
+ }
+
+ return new Data\Sum(
+ $dataPoints,
+ $temporality,
+ $this->monotonic,
+ );
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Aggregation/SumSummary.php b/vendor/open-telemetry/sdk/Metrics/Aggregation/SumSummary.php
new file mode 100644
index 000000000..9b257193c
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Aggregation/SumSummary.php
@@ -0,0 +1,20 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Aggregation;
+
+final class SumSummary
+{
+ /**
+ * @var float|int
+ */
+ public $value;
+ /**
+ * @param float|int $value
+ */
+ public function __construct($value)
+ {
+ $this->value = $value;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/AggregationInterface.php b/vendor/open-telemetry/sdk/Metrics/AggregationInterface.php
new file mode 100644
index 000000000..0a85207e0
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/AggregationInterface.php
@@ -0,0 +1,57 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Metrics\Data\DataInterface;
+use OpenTelemetry\SDK\Metrics\Data\Exemplar;
+use OpenTelemetry\SDK\Metrics\Data\Temporality;
+
+/**
+ * @psalm-template T
+ */
+interface AggregationInterface
+{
+ /**
+ * @psalm-return T
+ */
+ public function initialize();
+
+ /**
+ * @psalm-param T $summary
+ * @psalm-param float|int $value
+ */
+ public function record($summary, $value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): void;
+
+ /**
+ * @psalm-param T $left
+ * @psalm-param T $right
+ * @psalm-return T
+ */
+ public function merge($left, $right);
+
+ /**
+ * @psalm-param T $left
+ * @psalm-param T $right
+ * @psalm-return T
+ */
+ public function diff($left, $right);
+
+ /**
+ * @param array<AttributesInterface> $attributes
+ * @psalm-param array<T> $summaries
+ * @param array<list<Exemplar>> $exemplars
+ * @param string|Temporality $temporality
+ */
+ public function toData(
+ array $attributes,
+ array $summaries,
+ array $exemplars,
+ int $startTimestamp,
+ int $timestamp,
+ $temporality
+ ): DataInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/AggregationTemporalitySelectorInterface.php b/vendor/open-telemetry/sdk/Metrics/AggregationTemporalitySelectorInterface.php
new file mode 100644
index 000000000..f046d033d
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/AggregationTemporalitySelectorInterface.php
@@ -0,0 +1,21 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\SDK\Metrics\Data\Temporality;
+
+interface AggregationTemporalitySelectorInterface
+{
+ /**
+ * Returns the temporality to use for the given metric.
+ *
+ * It is recommended to return {@see MetricMetadataInterface::temporality()}
+ * if the exporter does not require a specific temporality.
+ *
+ * @return string|Temporality|null temporality to use, or null to signal
+ * that the given metric should not be exported by this exporter
+ */
+ public function temporality(MetricMetadataInterface $metric);
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/AttributeProcessor/FilteredAttributeProcessor.php b/vendor/open-telemetry/sdk/Metrics/AttributeProcessor/FilteredAttributeProcessor.php
new file mode 100644
index 000000000..c4df8e878
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/AttributeProcessor/FilteredAttributeProcessor.php
@@ -0,0 +1,33 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\AttributeProcessor;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\Attributes;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Metrics\AttributeProcessorInterface;
+
+/**
+ * @internal
+ */
+final class FilteredAttributeProcessor implements AttributeProcessorInterface
+{
+ private array $attributeKeys;
+
+ public function __construct(array $attributeKeys)
+ {
+ $this->attributeKeys = $attributeKeys;
+ }
+
+ public function process(AttributesInterface $attributes, ContextInterface $context): AttributesInterface
+ {
+ $filtered = [];
+ foreach ($this->attributeKeys as $key) {
+ $filtered[$key] = $attributes->get($key);
+ }
+
+ return new Attributes($filtered, 0);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/AttributeProcessor/IdentityAttributeProcessor.php b/vendor/open-telemetry/sdk/Metrics/AttributeProcessor/IdentityAttributeProcessor.php
new file mode 100644
index 000000000..f261563ea
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/AttributeProcessor/IdentityAttributeProcessor.php
@@ -0,0 +1,20 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\AttributeProcessor;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Metrics\AttributeProcessorInterface;
+
+/**
+ * @internal
+ */
+final class IdentityAttributeProcessor implements AttributeProcessorInterface
+{
+ public function process(AttributesInterface $attributes, ContextInterface $context): AttributesInterface
+ {
+ return $attributes;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/AttributeProcessorInterface.php b/vendor/open-telemetry/sdk/Metrics/AttributeProcessorInterface.php
new file mode 100644
index 000000000..d2077aa39
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/AttributeProcessorInterface.php
@@ -0,0 +1,16 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+/**
+ * @internal
+ */
+interface AttributeProcessorInterface
+{
+ public function process(AttributesInterface $attributes, ContextInterface $context): AttributesInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Counter.php b/vendor/open-telemetry/sdk/Metrics/Counter.php
new file mode 100644
index 000000000..9cc6b75f9
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Counter.php
@@ -0,0 +1,37 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\API\Metrics\CounterInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricWriterInterface;
+
+/**
+ * @internal
+ */
+final class Counter implements CounterInterface
+{
+ private MetricWriterInterface $writer;
+ private Instrument $instrument;
+ private ReferenceCounterInterface $referenceCounter;
+
+ public function __construct(MetricWriterInterface $writer, Instrument $instrument, ReferenceCounterInterface $referenceCounter)
+ {
+ $this->writer = $writer;
+ $this->instrument = $instrument;
+ $this->referenceCounter = $referenceCounter;
+
+ $this->referenceCounter->acquire();
+ }
+
+ public function __destruct()
+ {
+ $this->referenceCounter->release();
+ }
+
+ public function add($amount, iterable $attributes = [], $context = null): void
+ {
+ $this->writer->record($this->instrument, $amount, $attributes, $context);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Data/DataInterface.php b/vendor/open-telemetry/sdk/Metrics/Data/DataInterface.php
new file mode 100644
index 000000000..7aa0c0e20
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Data/DataInterface.php
@@ -0,0 +1,9 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Data;
+
+interface DataInterface
+{
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Data/Exemplar.php b/vendor/open-telemetry/sdk/Metrics/Data/Exemplar.php
new file mode 100644
index 000000000..bd2034f75
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Data/Exemplar.php
@@ -0,0 +1,65 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Data;
+
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+final class Exemplar
+{
+
+ /**
+ * @var int|string
+ */
+ private $index;
+ /**
+ * @var float|int
+ * @readonly
+ */
+ public $value;
+ /**
+ * @readonly
+ */
+ public int $timestamp;
+ /**
+ * @readonly
+ */
+ public AttributesInterface $attributes;
+ /**
+ * @readonly
+ */
+ public ?string $traceId;
+ /**
+ * @readonly
+ */
+ public ?string $spanId;
+
+ /**
+ * @param int|string $index
+ * @param float|int $value
+ */
+ public function __construct($index, $value, int $timestamp, AttributesInterface $attributes, ?string $traceId, ?string $spanId)
+ {
+ $this->index = $index;
+ $this->value = $value;
+ $this->timestamp = $timestamp;
+ $this->attributes = $attributes;
+ $this->traceId = $traceId;
+ $this->spanId = $spanId;
+ }
+
+ /**
+ * @param iterable<Exemplar> $exemplars
+ * @return array<list<Exemplar>>
+ */
+ public static function groupByIndex(iterable $exemplars): array
+ {
+ $grouped = [];
+ foreach ($exemplars as $exemplar) {
+ $grouped[$exemplar->index][] = $exemplar;
+ }
+
+ return $grouped;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Data/Gauge.php b/vendor/open-telemetry/sdk/Metrics/Data/Gauge.php
new file mode 100644
index 000000000..00eb50939
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Data/Gauge.php
@@ -0,0 +1,22 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Data;
+
+final class Gauge implements DataInterface
+{
+
+ /**
+ * @var iterable<NumberDataPoint>
+ * @readonly
+ */
+ public iterable $dataPoints;
+ /**
+ * @param iterable<NumberDataPoint> $dataPoints
+ */
+ public function __construct(iterable $dataPoints)
+ {
+ $this->dataPoints = $dataPoints;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Data/Histogram.php b/vendor/open-telemetry/sdk/Metrics/Data/Histogram.php
new file mode 100644
index 000000000..782698026
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Data/Histogram.php
@@ -0,0 +1,29 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Data;
+
+final class Histogram implements DataInterface
+{
+
+ /**
+ * @var iterable<HistogramDataPoint>
+ * @readonly
+ */
+ public iterable $dataPoints;
+ /**
+ * @var string|Temporality
+ * @readonly
+ */
+ public $temporality;
+ /**
+ * @param iterable<HistogramDataPoint> $dataPoints
+ * @param string|Temporality $temporality
+ */
+ public function __construct(iterable $dataPoints, $temporality)
+ {
+ $this->dataPoints = $dataPoints;
+ $this->temporality = $temporality;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Data/HistogramDataPoint.php b/vendor/open-telemetry/sdk/Metrics/Data/HistogramDataPoint.php
new file mode 100644
index 000000000..4c9df07b4
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Data/HistogramDataPoint.php
@@ -0,0 +1,76 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Data;
+
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+final class HistogramDataPoint
+{
+ /**
+ * @readonly
+ */
+ public int $count;
+ /**
+ * @var float|int
+ * @readonly
+ */
+ public $sum;
+ /**
+ * @var float|int
+ * @readonly
+ */
+ public $min;
+ /**
+ * @var float|int
+ * @readonly
+ */
+ public $max;
+ /**
+ * @var int[]
+ * @readonly
+ */
+ public array $bucketCounts;
+ /**
+ * @var list<float|int>
+ * @readonly
+ */
+ public array $explicitBounds;
+ /**
+ * @readonly
+ */
+ public AttributesInterface $attributes;
+ /**
+ * @readonly
+ */
+ public int $startTimestamp;
+ /**
+ * @readonly
+ */
+ public int $timestamp;
+ /**
+ * @readonly
+ */
+ public iterable $exemplars = [];
+ /**
+ * @param float|int $sum
+ * @param float|int $min
+ * @param float|int $max
+ * @param int[] $bucketCounts
+ * @param list<float|int> $explicitBounds
+ */
+ public function __construct(int $count, $sum, $min, $max, array $bucketCounts, array $explicitBounds, AttributesInterface $attributes, int $startTimestamp, int $timestamp, iterable $exemplars = [])
+ {
+ $this->count = $count;
+ $this->sum = $sum;
+ $this->min = $min;
+ $this->max = $max;
+ $this->bucketCounts = $bucketCounts;
+ $this->explicitBounds = $explicitBounds;
+ $this->attributes = $attributes;
+ $this->startTimestamp = $startTimestamp;
+ $this->timestamp = $timestamp;
+ $this->exemplars = $exemplars;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Data/Metric.php b/vendor/open-telemetry/sdk/Metrics/Data/Metric.php
new file mode 100644
index 000000000..41fcb52dd
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Data/Metric.php
@@ -0,0 +1,46 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Data;
+
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+
+final class Metric
+{
+ /**
+ * @readonly
+ */
+ public InstrumentationScopeInterface $instrumentationScope;
+ /**
+ * @readonly
+ */
+ public ResourceInfo $resource;
+ /**
+ * @readonly
+ */
+ public string $name;
+ /**
+ * @readonly
+ */
+ public ?string $description;
+ /**
+ * @readonly
+ */
+ public ?string $unit;
+ /**
+ * @readonly
+ */
+ public DataInterface $data;
+
+ public function __construct(InstrumentationScopeInterface $instrumentationScope, ResourceInfo $resource, string $name, ?string $unit, ?string $description, DataInterface $data)
+ {
+ $this->instrumentationScope = $instrumentationScope;
+ $this->resource = $resource;
+ $this->name = $name;
+ $this->description = $description;
+ $this->unit = $unit;
+ $this->data = $data;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Data/NumberDataPoint.php b/vendor/open-telemetry/sdk/Metrics/Data/NumberDataPoint.php
new file mode 100644
index 000000000..1d00e783a
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Data/NumberDataPoint.php
@@ -0,0 +1,43 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Data;
+
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+final class NumberDataPoint
+{
+ /**
+ * @var float|int
+ * @readonly
+ */
+ public $value;
+ /**
+ * @readonly
+ */
+ public AttributesInterface $attributes;
+ /**
+ * @readonly
+ */
+ public int $startTimestamp;
+ /**
+ * @readonly
+ */
+ public int $timestamp;
+ /**
+ * @readonly
+ */
+ public iterable $exemplars = [];
+ /**
+ * @param float|int $value
+ */
+ public function __construct($value, AttributesInterface $attributes, int $startTimestamp, int $timestamp, iterable $exemplars = [])
+ {
+ $this->value = $value;
+ $this->attributes = $attributes;
+ $this->startTimestamp = $startTimestamp;
+ $this->timestamp = $timestamp;
+ $this->exemplars = $exemplars;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Data/Sum.php b/vendor/open-telemetry/sdk/Metrics/Data/Sum.php
new file mode 100644
index 000000000..77c4c1021
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Data/Sum.php
@@ -0,0 +1,34 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Data;
+
+final class Sum implements DataInterface
+{
+
+ /**
+ * @var iterable<NumberDataPoint>
+ * @readonly
+ */
+ public iterable $dataPoints;
+ /**
+ * @var string|Temporality
+ * @readonly
+ */
+ public $temporality;
+ /**
+ * @readonly
+ */
+ public bool $monotonic;
+ /**
+ * @param iterable<NumberDataPoint> $dataPoints
+ * @param string|Temporality $temporality
+ */
+ public function __construct(iterable $dataPoints, $temporality, bool $monotonic)
+ {
+ $this->dataPoints = $dataPoints;
+ $this->temporality = $temporality;
+ $this->monotonic = $monotonic;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Data/Temporality.php b/vendor/open-telemetry/sdk/Metrics/Data/Temporality.php
new file mode 100644
index 000000000..b6642ebd0
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Data/Temporality.php
@@ -0,0 +1,20 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Data;
+
+/**
+ * Metric aggregation temporality.
+ *
+ * Has to be type-hinted as `string|Temporality` to be forward compatible.
+ */
+final class Temporality
+{
+ public const DELTA = 'Delta';
+ public const CUMULATIVE = 'Cumulative';
+
+ private function __construct()
+ {
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/DefaultAggregationProviderInterface.php b/vendor/open-telemetry/sdk/Metrics/DefaultAggregationProviderInterface.php
new file mode 100644
index 000000000..e5c2fcc0c
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/DefaultAggregationProviderInterface.php
@@ -0,0 +1,13 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+interface DefaultAggregationProviderInterface
+{
+ /**
+ * @param string|InstrumentType $instrumentType
+ */
+ public function defaultAggregation($instrumentType): ?AggregationInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/DefaultAggregationProviderTrait.php b/vendor/open-telemetry/sdk/Metrics/DefaultAggregationProviderTrait.php
new file mode 100644
index 000000000..37c5cb110
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/DefaultAggregationProviderTrait.php
@@ -0,0 +1,28 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+trait DefaultAggregationProviderTrait
+{
+ public function defaultAggregation($instrumentType): ?AggregationInterface
+ {
+ switch ($instrumentType) {
+ case InstrumentType::COUNTER:
+ case InstrumentType::ASYNCHRONOUS_COUNTER:
+ return new Aggregation\SumAggregation(true);
+ case InstrumentType::UP_DOWN_COUNTER:
+ case InstrumentType::ASYNCHRONOUS_UP_DOWN_COUNTER:
+ return new Aggregation\SumAggregation();
+ case InstrumentType::HISTOGRAM:
+ return new Aggregation\ExplicitBucketHistogramAggregation([0, 5, 10, 25, 50, 75, 100, 250, 500, 1000]);
+ case InstrumentType::ASYNCHRONOUS_GAUGE:
+ return new Aggregation\LastValueAggregation();
+ }
+
+ // @codeCoverageIgnoreStart
+ return null;
+ // @codeCoverageIgnoreEnd
+ }
+}
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 [];
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Histogram.php b/vendor/open-telemetry/sdk/Metrics/Histogram.php
new file mode 100644
index 000000000..532b1b4bf
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Histogram.php
@@ -0,0 +1,37 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\API\Metrics\HistogramInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricWriterInterface;
+
+/**
+ * @internal
+ */
+final class Histogram implements HistogramInterface
+{
+ private MetricWriterInterface $writer;
+ private Instrument $instrument;
+ private ReferenceCounterInterface $referenceCounter;
+
+ public function __construct(MetricWriterInterface $writer, Instrument $instrument, ReferenceCounterInterface $referenceCounter)
+ {
+ $this->writer = $writer;
+ $this->instrument = $instrument;
+ $this->referenceCounter = $referenceCounter;
+
+ $this->referenceCounter->acquire();
+ }
+
+ public function __destruct()
+ {
+ $this->referenceCounter->release();
+ }
+
+ public function record($amount, iterable $attributes = [], $context = null): void
+ {
+ $this->writer->record($this->instrument, $amount, $attributes, $context);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Instrument.php b/vendor/open-telemetry/sdk/Metrics/Instrument.php
new file mode 100644
index 000000000..3543604c0
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Instrument.php
@@ -0,0 +1,36 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+final class Instrument
+{
+ /**
+ * @var string|InstrumentType
+ * @readonly
+ */
+ public $type;
+ /**
+ * @readonly
+ */
+ public string $name;
+ /**
+ * @readonly
+ */
+ public ?string $unit;
+ /**
+ * @readonly
+ */
+ public ?string $description;
+ /**
+ * @param string|InstrumentType $type
+ */
+ public function __construct($type, string $name, ?string $unit, ?string $description)
+ {
+ $this->type = $type;
+ $this->name = $name;
+ $this->unit = $unit;
+ $this->description = $description;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/InstrumentType.php b/vendor/open-telemetry/sdk/Metrics/InstrumentType.php
new file mode 100644
index 000000000..ae603b2fe
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/InstrumentType.php
@@ -0,0 +1,25 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+/**
+ * Instrument type.
+ *
+ * Has to be type-hinted as `string|InstrumentType` to be forward compatible.
+ */
+final class InstrumentType
+{
+ public const COUNTER = 'Counter';
+ public const UP_DOWN_COUNTER = 'UpDownCounter';
+ public const HISTOGRAM = 'Histogram';
+
+ public const ASYNCHRONOUS_COUNTER = 'AsynchronousCounter';
+ public const ASYNCHRONOUS_UP_DOWN_COUNTER = 'AsynchronousUpDownCounter';
+ public const ASYNCHRONOUS_GAUGE = 'AsynchronousGauge';
+
+ private function __construct()
+ {
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Meter.php b/vendor/open-telemetry/sdk/Metrics/Meter.php
new file mode 100644
index 000000000..902284839
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Meter.php
@@ -0,0 +1,314 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use ArrayAccess;
+use OpenTelemetry\API\Metrics\CounterInterface;
+use OpenTelemetry\API\Metrics\HistogramInterface;
+use OpenTelemetry\API\Metrics\MeterInterface;
+use OpenTelemetry\API\Metrics\ObservableCounterInterface;
+use OpenTelemetry\API\Metrics\ObservableGaugeInterface;
+use OpenTelemetry\API\Metrics\ObservableUpDownCounterInterface;
+use OpenTelemetry\API\Metrics\UpDownCounterInterface;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Common\Time\ClockInterface;
+use function OpenTelemetry\SDK\Common\Util\closure;
+use OpenTelemetry\SDK\Common\Util\WeakMap;
+use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilterInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistration\MultiRegistryRegistration;
+use OpenTelemetry\SDK\Metrics\MetricRegistration\RegistryRegistration;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricRegistryInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricWriterInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+use const PHP_VERSION_ID;
+use function serialize;
+
+/**
+ * @internal
+ */
+final class Meter implements MeterInterface
+{
+ private MetricFactoryInterface $metricFactory;
+ private ResourceInfo $resource;
+ private ClockInterface $clock;
+ private StalenessHandlerFactoryInterface $stalenessHandlerFactory;
+ /** @var iterable<MetricSourceRegistryInterface&DefaultAggregationProviderInterface> */
+ private iterable $metricRegistries;
+ private ViewRegistryInterface $viewRegistry;
+ private ?ExemplarFilterInterface $exemplarFilter;
+ private MeterInstruments $instruments;
+ private InstrumentationScopeInterface $instrumentationScope;
+
+ private MetricRegistryInterface $registry;
+ private MetricWriterInterface $writer;
+
+ private ?string $instrumentationScopeId = null;
+
+ /**
+ * @param iterable<MetricSourceRegistryInterface&DefaultAggregationProviderInterface> $metricRegistries
+ */
+ public function __construct(
+ MetricFactoryInterface $metricFactory,
+ ResourceInfo $resource,
+ ClockInterface $clock,
+ StalenessHandlerFactoryInterface $stalenessHandlerFactory,
+ iterable $metricRegistries,
+ ViewRegistryInterface $viewRegistry,
+ ?ExemplarFilterInterface $exemplarFilter,
+ MeterInstruments $instruments,
+ InstrumentationScopeInterface $instrumentationScope,
+ MetricRegistryInterface $registry,
+ MetricWriterInterface $writer
+ ) {
+ $this->metricFactory = $metricFactory;
+ $this->resource = $resource;
+ $this->clock = $clock;
+ $this->stalenessHandlerFactory = $stalenessHandlerFactory;
+ $this->metricRegistries = $metricRegistries;
+ $this->viewRegistry = $viewRegistry;
+ $this->exemplarFilter = $exemplarFilter;
+ $this->instruments = $instruments;
+ $this->instrumentationScope = $instrumentationScope;
+ $this->registry = $registry;
+ $this->writer = $writer;
+ }
+
+ public function createCounter(string $name, ?string $unit = null, ?string $description = null): CounterInterface
+ {
+ [$instrument, $referenceCounter] = $this->createSynchronousWriter(
+ InstrumentType::COUNTER,
+ $name,
+ $unit,
+ $description,
+ );
+
+ return new Counter($this->writer, $instrument, $referenceCounter);
+ }
+
+ public function createObservableCounter(string $name, ?string $unit = null, ?string $description = null, callable ...$callbacks): ObservableCounterInterface
+ {
+ [$instrument, $referenceCounter, $destructors] = $this->createAsynchronousObserver(
+ InstrumentType::ASYNCHRONOUS_COUNTER,
+ $name,
+ $unit,
+ $description,
+ );
+
+ foreach ($callbacks as $callback) {
+ $this->writer->registerCallback(closure($callback), $instrument);
+ $referenceCounter->acquire(true);
+ }
+
+ return new ObservableCounter($this->writer, $instrument, $referenceCounter, $destructors);
+ }
+
+ public function createHistogram(string $name, ?string $unit = null, ?string $description = null): HistogramInterface
+ {
+ [$instrument, $referenceCounter] = $this->createSynchronousWriter(
+ InstrumentType::HISTOGRAM,
+ $name,
+ $unit,
+ $description,
+ );
+
+ return new Histogram($this->writer, $instrument, $referenceCounter);
+ }
+
+ public function createObservableGauge(string $name, ?string $unit = null, ?string $description = null, callable ...$callbacks): ObservableGaugeInterface
+ {
+ [$instrument, $referenceCounter, $destructors] = $this->createAsynchronousObserver(
+ InstrumentType::ASYNCHRONOUS_GAUGE,
+ $name,
+ $unit,
+ $description,
+ );
+
+ foreach ($callbacks as $callback) {
+ $this->writer->registerCallback(closure($callback), $instrument);
+ $referenceCounter->acquire(true);
+ }
+
+ return new ObservableGauge($this->writer, $instrument, $referenceCounter, $destructors);
+ }
+
+ public function createUpDownCounter(string $name, ?string $unit = null, ?string $description = null): UpDownCounterInterface
+ {
+ [$instrument, $referenceCounter] = $this->createSynchronousWriter(
+ InstrumentType::UP_DOWN_COUNTER,
+ $name,
+ $unit,
+ $description,
+ );
+
+ return new UpDownCounter($this->writer, $instrument, $referenceCounter);
+ }
+
+ public function createObservableUpDownCounter(string $name, ?string $unit = null, ?string $description = null, callable ...$callbacks): ObservableUpDownCounterInterface
+ {
+ [$instrument, $referenceCounter, $destructors] = $this->createAsynchronousObserver(
+ InstrumentType::ASYNCHRONOUS_UP_DOWN_COUNTER,
+ $name,
+ $unit,
+ $description,
+ );
+
+ foreach ($callbacks as $callback) {
+ $this->writer->registerCallback(closure($callback), $instrument);
+ $referenceCounter->acquire(true);
+ }
+
+ return new ObservableUpDownCounter($this->writer, $instrument, $referenceCounter, $destructors);
+ }
+
+ /**
+ * @param string|InstrumentType $instrumentType
+ * @return array{Instrument, ReferenceCounterInterface}
+ */
+ private function createSynchronousWriter($instrumentType, string $name, ?string $unit, ?string $description): array
+ {
+ $instrument = new Instrument($instrumentType, $name, $unit, $description);
+
+ $instrumentationScopeId = $this->instrumentationScopeId($this->instrumentationScope);
+ $instrumentId = $this->instrumentId($instrument);
+
+ $instruments = $this->instruments;
+ if ($writer = $instruments->writers[$instrumentationScopeId][$instrumentId] ?? null) {
+ return $writer;
+ }
+
+ $stalenessHandler = $this->stalenessHandlerFactory->create();
+ $instruments->startTimestamp ??= $this->clock->now();
+ $streamIds = $this->metricFactory->createSynchronousWriter(
+ $this->registry,
+ $this->resource,
+ $this->instrumentationScope,
+ $instrument,
+ $instruments->startTimestamp,
+ $this->viewRegistrationRequests($instrument, $stalenessHandler),
+ $this->exemplarFilter,
+ );
+
+ $registry = $this->registry;
+ $stalenessHandler->onStale(static function () use ($instruments, $instrumentationScopeId, $instrumentId, $registry, $streamIds): void {
+ unset($instruments->writers[$instrumentationScopeId][$instrumentId]);
+ if (!$instruments->writers[$instrumentationScopeId]) {
+ unset($instruments->writers[$instrumentationScopeId]);
+ }
+ foreach ($streamIds as $streamId) {
+ $registry->unregisterStream($streamId);
+ }
+
+ $instruments->startTimestamp = null;
+ });
+
+ return $instruments->writers[$instrumentationScopeId][$instrumentId] = [
+ $instrument,
+ $stalenessHandler,
+ ];
+ }
+
+ /**
+ * @param string|InstrumentType $instrumentType
+ * @return array{Instrument, ReferenceCounterInterface, ArrayAccess<object, ObservableCallbackDestructor>}
+ */
+ private function createAsynchronousObserver($instrumentType, string $name, ?string $unit, ?string $description): array
+ {
+ $instrument = new Instrument($instrumentType, $name, $unit, $description);
+
+ $instrumentationScopeId = $this->instrumentationScopeId($this->instrumentationScope);
+ $instrumentId = $this->instrumentId($instrument);
+
+ $instruments = $this->instruments;
+ /** @phan-suppress-next-line PhanDeprecatedProperty */
+ $instruments->staleObservers = [];
+ if ($observer = $instruments->observers[$instrumentationScopeId][$instrumentId] ?? null) {
+ return $observer;
+ }
+
+ $stalenessHandler = $this->stalenessHandlerFactory->create();
+ $instruments->startTimestamp ??= $this->clock->now();
+ $streamIds = $this->metricFactory->createAsynchronousObserver(
+ $this->registry,
+ $this->resource,
+ $this->instrumentationScope,
+ $instrument,
+ $instruments->startTimestamp,
+ $this->viewRegistrationRequests($instrument, $stalenessHandler),
+ );
+
+ $registry = $this->registry;
+ $stalenessHandler->onStale(static function () use ($instruments, $instrumentationScopeId, $instrumentId, $registry, $streamIds): void {
+ if (PHP_VERSION_ID < 80000) {
+ /** @phan-suppress-next-line PhanDeprecatedProperty */
+ $instruments->staleObservers[] = $instruments->observers[$instrumentationScopeId][$instrumentId][2];
+ }
+
+ unset($instruments->observers[$instrumentationScopeId][$instrumentId]);
+ if (!$instruments->observers[$instrumentationScopeId]) {
+ unset($instruments->observers[$instrumentationScopeId]);
+ }
+ foreach ($streamIds as $streamId) {
+ $registry->unregisterStream($streamId);
+ }
+
+ $instruments->startTimestamp = null;
+ });
+
+ /** @var ArrayAccess<object, ObservableCallbackDestructor> $destructors */
+ $destructors = WeakMap::create();
+
+ return $instruments->observers[$instrumentationScopeId][$instrumentId] = [
+ $instrument,
+ $stalenessHandler,
+ $destructors,
+ ];
+ }
+
+ /**
+ * @return iterable<array{ViewProjection, MetricRegistrationInterface}>
+ */
+ private function viewRegistrationRequests(Instrument $instrument, StalenessHandlerInterface $stalenessHandler): iterable
+ {
+ $views = $this->viewRegistry->find($instrument, $this->instrumentationScope) ?? [
+ new ViewProjection(
+ $instrument->name,
+ $instrument->unit,
+ $instrument->description,
+ null,
+ null,
+ ),
+ ];
+
+ $compositeRegistration = new MultiRegistryRegistration($this->metricRegistries, $stalenessHandler);
+ foreach ($views as $view) {
+ if ($view->aggregation !== null) {
+ yield [$view, $compositeRegistration];
+ } else {
+ foreach ($this->metricRegistries as $metricRegistry) {
+ yield [
+ new ViewProjection(
+ $view->name,
+ $view->unit,
+ $view->description,
+ $view->attributeKeys,
+ $metricRegistry->defaultAggregation($instrument->type),
+ ),
+ new RegistryRegistration($metricRegistry, $stalenessHandler),
+ ];
+ }
+ }
+ }
+ }
+
+ private function instrumentationScopeId(InstrumentationScopeInterface $instrumentationScope): string
+ {
+ return $this->instrumentationScopeId ??= serialize($instrumentationScope);
+ }
+
+ private function instrumentId(Instrument $instrument): string
+ {
+ return serialize($instrument);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MeterInstruments.php b/vendor/open-telemetry/sdk/Metrics/MeterInstruments.php
new file mode 100644
index 000000000..c331cb608
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MeterInstruments.php
@@ -0,0 +1,29 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use ArrayAccess;
+
+/**
+ * @internal
+ */
+final class MeterInstruments
+{
+ public ?int $startTimestamp = null;
+ /**
+ * @var array<string, array<string, array{Instrument, ReferenceCounterInterface, ArrayAccess<object, ObservableCallbackDestructor>}>>
+ */
+ public array $observers = [];
+ /**
+ * @var array<string, array<string, array{Instrument, ReferenceCounterInterface}>>
+ */
+ public array $writers = [];
+
+ /**
+ * @var list<ArrayAccess<object, ObservableCallbackDestructor>>
+ * @deprecated
+ */
+ public array $staleObservers = [];
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MeterProvider.php b/vendor/open-telemetry/sdk/Metrics/MeterProvider.php
new file mode 100644
index 000000000..36c17cf81
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MeterProvider.php
@@ -0,0 +1,130 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\API\Metrics\MeterInterface;
+use OpenTelemetry\API\Metrics\Noop\NoopMeter;
+use OpenTelemetry\Context\ContextStorageInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesFactoryInterface;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeFactoryInterface;
+use OpenTelemetry\SDK\Common\Time\ClockInterface;
+use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilterInterface;
+use OpenTelemetry\SDK\Metrics\MetricFactory\StreamFactory;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricRegistry;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricRegistryInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricWriterInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+use OpenTelemetry\SDK\Sdk;
+
+final class MeterProvider implements MeterProviderInterface
+{
+ private MetricFactoryInterface $metricFactory;
+ private ResourceInfo $resource;
+ private ClockInterface $clock;
+ private InstrumentationScopeFactoryInterface $instrumentationScopeFactory;
+ private iterable $metricReaders;
+ private ViewRegistryInterface $viewRegistry;
+ private ?ExemplarFilterInterface $exemplarFilter;
+ private StalenessHandlerFactoryInterface $stalenessHandlerFactory;
+ private MeterInstruments $instruments;
+ private MetricRegistryInterface $registry;
+ private MetricWriterInterface $writer;
+
+ private bool $closed = false;
+
+ /**
+ * @param iterable<MetricReaderInterface&MetricSourceRegistryInterface&DefaultAggregationProviderInterface> $metricReaders
+ */
+ public function __construct(
+ ?ContextStorageInterface $contextStorage,
+ ResourceInfo $resource,
+ ClockInterface $clock,
+ AttributesFactoryInterface $attributesFactory,
+ InstrumentationScopeFactoryInterface $instrumentationScopeFactory,
+ iterable $metricReaders,
+ ViewRegistryInterface $viewRegistry,
+ ?ExemplarFilterInterface $exemplarFilter,
+ StalenessHandlerFactoryInterface $stalenessHandlerFactory,
+ MetricFactoryInterface $metricFactory = null
+ ) {
+ $this->metricFactory = $metricFactory ?? new StreamFactory();
+ $this->resource = $resource;
+ $this->clock = $clock;
+ $this->instrumentationScopeFactory = $instrumentationScopeFactory;
+ $this->metricReaders = $metricReaders;
+ $this->viewRegistry = $viewRegistry;
+ $this->exemplarFilter = $exemplarFilter;
+ $this->stalenessHandlerFactory = $stalenessHandlerFactory;
+ $this->instruments = new MeterInstruments();
+
+ $registry = new MetricRegistry($contextStorage, $attributesFactory, $clock);
+ $this->registry = $registry;
+ $this->writer = $registry;
+ }
+
+ public function getMeter(
+ string $name,
+ ?string $version = null,
+ ?string $schemaUrl = null,
+ iterable $attributes = []
+ ): MeterInterface {
+ if ($this->closed || Sdk::isDisabled()) { //@todo create meter provider from factory, and move Sdk::isDisabled() there
+ return new NoopMeter();
+ }
+
+ return new Meter(
+ $this->metricFactory,
+ $this->resource,
+ $this->clock,
+ $this->stalenessHandlerFactory,
+ $this->metricReaders,
+ $this->viewRegistry,
+ $this->exemplarFilter,
+ $this->instruments,
+ $this->instrumentationScopeFactory->create($name, $version, $schemaUrl, $attributes),
+ $this->registry,
+ $this->writer,
+ );
+ }
+
+ public function shutdown(): bool
+ {
+ if ($this->closed) {
+ return false;
+ }
+
+ $this->closed = true;
+
+ $success = true;
+ foreach ($this->metricReaders as $metricReader) {
+ if (!$metricReader->shutdown()) {
+ $success = false;
+ }
+ }
+
+ return $success;
+ }
+
+ public function forceFlush(): bool
+ {
+ if ($this->closed) {
+ return false;
+ }
+
+ $success = true;
+ foreach ($this->metricReaders as $metricReader) {
+ if (!$metricReader->forceFlush()) {
+ $success = false;
+ }
+ }
+
+ return $success;
+ }
+
+ public static function builder(): MeterProviderBuilder
+ {
+ return new MeterProviderBuilder();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MeterProviderBuilder.php b/vendor/open-telemetry/sdk/Metrics/MeterProviderBuilder.php
new file mode 100644
index 000000000..17f0be895
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MeterProviderBuilder.php
@@ -0,0 +1,62 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\SDK\Common\Attribute\Attributes;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeFactory;
+use OpenTelemetry\SDK\Common\Time\ClockFactory;
+use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilter\WithSampledTraceExemplarFilter;
+use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilterInterface;
+use OpenTelemetry\SDK\Metrics\StalenessHandler\NoopStalenessHandlerFactory;
+use OpenTelemetry\SDK\Metrics\View\CriteriaViewRegistry;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+use OpenTelemetry\SDK\Resource\ResourceInfoFactory;
+
+class MeterProviderBuilder
+{
+ // @var array<MetricReaderInterface>
+ private array $metricReaders = [];
+ private ?ResourceInfo $resource = null;
+ private ?ExemplarFilterInterface $exemplarFilter = null;
+
+ public function setResource(ResourceInfo $resource): self
+ {
+ $this->resource = $resource;
+
+ return $this;
+ }
+
+ public function setExemplarFilter(ExemplarFilterInterface $exemplarFilter): self
+ {
+ $this->exemplarFilter = $exemplarFilter;
+
+ return $this;
+ }
+
+ public function addReader(MetricReaderInterface $reader): self
+ {
+ $this->metricReaders[] = $reader;
+
+ return $this;
+ }
+
+ /**
+ * @psalm-suppress PossiblyInvalidArgument
+ */
+ public function build(): MeterProviderInterface
+ {
+ return new MeterProvider(
+ null,
+ $this->resource ?? ResourceInfoFactory::emptyResource(),
+ ClockFactory::getDefault(),
+ Attributes::factory(),
+ new InstrumentationScopeFactory(Attributes::factory()),
+ $this->metricReaders,
+ new CriteriaViewRegistry(),
+ $this->exemplarFilter ?? new WithSampledTraceExemplarFilter(),
+ new NoopStalenessHandlerFactory(),
+ );
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MeterProviderFactory.php b/vendor/open-telemetry/sdk/Metrics/MeterProviderFactory.php
new file mode 100644
index 000000000..5f7f9988d
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MeterProviderFactory.php
@@ -0,0 +1,78 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use InvalidArgumentException;
+use OpenTelemetry\API\Behavior\LogsMessagesTrait;
+use OpenTelemetry\SDK\Common\Configuration\Configuration;
+use OpenTelemetry\SDK\Common\Configuration\KnownValues;
+use OpenTelemetry\SDK\Common\Configuration\Variables;
+use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilter\AllExemplarFilter;
+use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilter\NoneExemplarFilter;
+use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilter\WithSampledTraceExemplarFilter;
+use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilterInterface;
+use OpenTelemetry\SDK\Metrics\MetricExporter\NoopMetricExporter;
+use OpenTelemetry\SDK\Metrics\MetricReader\ExportingReader;
+use OpenTelemetry\SDK\Registry;
+use OpenTelemetry\SDK\Resource\ResourceInfoFactory;
+use OpenTelemetry\SDK\Sdk;
+
+class MeterProviderFactory
+{
+ use LogsMessagesTrait;
+
+ /**
+ * @todo https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk_exporters/otlp.md#general
+ * - "The exporter MUST configure the default aggregation on the basis of instrument kind using the
+ * OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION variable as described below if it is implemented."
+ */
+ public function create(): MeterProviderInterface
+ {
+ if (Sdk::isDisabled()) {
+ return new NoopMeterProvider();
+ }
+ $exporters = Configuration::getList(Variables::OTEL_METRICS_EXPORTER);
+ //TODO "The SDK MAY accept a comma-separated list to enable setting multiple exporters"
+ if (count($exporters) !== 1) {
+ throw new InvalidArgumentException(sprintf('Configuration %s requires exactly 1 exporter', Variables::OTEL_METRICS_EXPORTER));
+ }
+ $exporterName = $exporters[0];
+
+ try {
+ $factory = Registry::metricExporterFactory($exporterName);
+ $exporter = $factory->create();
+ } catch (\Throwable $t) {
+ self::logWarning(sprintf('Unable to create %s meter provider: %s', $exporterName, $t->getMessage()));
+ $exporter = new NoopMetricExporter();
+ }
+
+ // @todo "The exporter MUST be paired with a periodic exporting MetricReader"
+ $reader = new ExportingReader($exporter);
+ $resource = ResourceInfoFactory::defaultResource();
+ $exemplarFilter = $this->createExemplarFilter(Configuration::getEnum(Variables::OTEL_METRICS_EXEMPLAR_FILTER));
+
+ return MeterProvider::builder()
+ ->setResource($resource)
+ ->addReader($reader)
+ ->setExemplarFilter($exemplarFilter)
+ ->build();
+ }
+
+ private function createExemplarFilter(string $name): ExemplarFilterInterface
+ {
+ switch ($name) {
+ case KnownValues::VALUE_WITH_SAMPLED_TRACE:
+ return new WithSampledTraceExemplarFilter();
+ case KnownValues::VALUE_ALL:
+ return new AllExemplarFilter();
+ case KnownValues::VALUE_NONE:
+ return new NoneExemplarFilter();
+ default:
+ self::logWarning('Unknown exemplar filter: ' . $name);
+
+ return new NoneExemplarFilter();
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MeterProviderInterface.php b/vendor/open-telemetry/sdk/Metrics/MeterProviderInterface.php
new file mode 100644
index 000000000..fcb951106
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MeterProviderInterface.php
@@ -0,0 +1,12 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+interface MeterProviderInterface extends \OpenTelemetry\API\Metrics\MeterProviderInterface
+{
+ public function shutdown(): bool;
+
+ public function forceFlush(): bool;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricExporter/ConsoleMetricExporter.php b/vendor/open-telemetry/sdk/Metrics/MetricExporter/ConsoleMetricExporter.php
new file mode 100644
index 000000000..62ea7b535
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricExporter/ConsoleMetricExporter.php
@@ -0,0 +1,105 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricExporter;
+
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Metrics\AggregationTemporalitySelectorInterface;
+use OpenTelemetry\SDK\Metrics\Data\Metric;
+use OpenTelemetry\SDK\Metrics\Data\Temporality;
+use OpenTelemetry\SDK\Metrics\MetricMetadataInterface;
+use OpenTelemetry\SDK\Metrics\PushMetricExporterInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+
+/**
+ * Console metrics exporter.
+ * Note that the output is human-readable JSON, not compatible with OTLP.
+ */
+class ConsoleMetricExporter implements PushMetricExporterInterface, AggregationTemporalitySelectorInterface
+{
+ /**
+ * @var string|Temporality|null
+ */
+ private $temporality;
+
+ /**
+ * @param string|Temporality|null $temporality
+ */
+ public function __construct($temporality = null)
+ {
+ $this->temporality = $temporality;
+ }
+ /**
+ * @inheritDoc
+ */
+ public function temporality(MetricMetadataInterface $metric)
+ {
+ return $this->temporality ?? $metric->temporality();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function export(iterable $batch): bool
+ {
+ $resource = null;
+ $scope = null;
+ foreach ($batch as $metric) {
+ /** @var Metric $metric */
+ if (!$resource) {
+ $resource = $this->convertResource($metric->resource);
+ }
+ if (!$scope) {
+ $scope = $this->convertInstrumentationScope($metric->instrumentationScope);
+ $scope['metrics'] = [];
+ }
+ $scope['metrics'][] = $this->convertMetric($metric);
+ }
+ $output = [
+ 'resource' => $resource,
+ 'scope' => $scope,
+ ];
+ echo json_encode($output, JSON_PRETTY_PRINT) . PHP_EOL;
+
+ return true;
+ }
+
+ public function shutdown(): bool
+ {
+ return true;
+ }
+
+ public function forceFlush(): bool
+ {
+ return true;
+ }
+
+ private function convertMetric(Metric $metric): array
+ {
+ return [
+ 'name' => $metric->name,
+ 'description' => $metric->description,
+ 'unit' => $metric->unit,
+ 'data' => $metric->data,
+ ];
+ }
+
+ private function convertResource(ResourceInfo $resource): array
+ {
+ return [
+ 'attributes' => $resource->getAttributes()->toArray(),
+ 'dropped_attributes_count' => $resource->getAttributes()->getDroppedAttributesCount(),
+ ];
+ }
+ private function convertInstrumentationScope(InstrumentationScopeInterface $scope): array
+ {
+ return [
+ 'name' => $scope->getName(),
+ 'version' => $scope->getVersion(),
+ 'attributes' => $scope->getAttributes()->toArray(),
+ 'dropped_attributes_count' => $scope->getAttributes()->getDroppedAttributesCount(),
+ 'schema_url' => $scope->getSchemaUrl(),
+ ];
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricExporter/ConsoleMetricExporterFactory.php b/vendor/open-telemetry/sdk/Metrics/MetricExporter/ConsoleMetricExporterFactory.php
new file mode 100644
index 000000000..19088738d
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricExporter/ConsoleMetricExporterFactory.php
@@ -0,0 +1,16 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricExporter;
+
+use OpenTelemetry\SDK\Metrics\MetricExporterFactoryInterface;
+use OpenTelemetry\SDK\Metrics\MetricExporterInterface;
+
+class ConsoleMetricExporterFactory implements MetricExporterFactoryInterface
+{
+ public function create(): MetricExporterInterface
+ {
+ return new ConsoleMetricExporter();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricExporter/InMemoryExporter.php b/vendor/open-telemetry/sdk/Metrics/MetricExporter/InMemoryExporter.php
new file mode 100644
index 000000000..6bbab8b79
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricExporter/InMemoryExporter.php
@@ -0,0 +1,78 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricExporter;
+
+use function array_push;
+use OpenTelemetry\SDK\Metrics\AggregationTemporalitySelectorInterface;
+use OpenTelemetry\SDK\Metrics\Data\Metric;
+use OpenTelemetry\SDK\Metrics\Data\Temporality;
+use OpenTelemetry\SDK\Metrics\MetricExporterInterface;
+use OpenTelemetry\SDK\Metrics\MetricMetadataInterface;
+
+/**
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk_exporters/in-memory.md
+ */
+final class InMemoryExporter implements MetricExporterInterface, AggregationTemporalitySelectorInterface
+{
+ /**
+ * @var list<Metric>
+ */
+ private array $metrics = [];
+ /**
+ * @var string|Temporality|null
+ */
+ private $temporality;
+
+ private bool $closed = false;
+
+ /**
+ * @param string|Temporality|null $temporality
+ */
+ public function __construct($temporality = null)
+ {
+ $this->temporality = $temporality;
+ }
+
+ public function temporality(MetricMetadataInterface $metric)
+ {
+ return $this->temporality ?? $metric->temporality();
+ }
+
+ /**
+ * @return list<Metric>
+ */
+ public function collect(bool $reset = false): array
+ {
+ $metrics = $this->metrics;
+ if ($reset) {
+ $this->metrics = [];
+ }
+
+ return $metrics;
+ }
+
+ public function export(iterable $batch): bool
+ {
+ if ($this->closed) {
+ return false;
+ }
+
+ /** @psalm-suppress InvalidPropertyAssignmentValue */
+ array_push($this->metrics, ...$batch);
+
+ return true;
+ }
+
+ public function shutdown(): bool
+ {
+ if ($this->closed) {
+ return false;
+ }
+
+ $this->closed = true;
+
+ return true;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricExporter/InMemoryExporterFactory.php b/vendor/open-telemetry/sdk/Metrics/MetricExporter/InMemoryExporterFactory.php
new file mode 100644
index 000000000..c72c7b169
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricExporter/InMemoryExporterFactory.php
@@ -0,0 +1,16 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricExporter;
+
+use OpenTelemetry\SDK\Metrics\MetricExporterFactoryInterface;
+use OpenTelemetry\SDK\Metrics\MetricExporterInterface;
+
+class InMemoryExporterFactory implements MetricExporterFactoryInterface
+{
+ public function create(): MetricExporterInterface
+ {
+ return new InMemoryExporter();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricExporter/NoopMetricExporter.php b/vendor/open-telemetry/sdk/Metrics/MetricExporter/NoopMetricExporter.php
new file mode 100644
index 000000000..0cac12fae
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricExporter/NoopMetricExporter.php
@@ -0,0 +1,23 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricExporter;
+
+use OpenTelemetry\SDK\Metrics\MetricExporterInterface;
+
+class NoopMetricExporter implements MetricExporterInterface
+{
+ /**
+ * @inheritDoc
+ */
+ public function export(iterable $batch): bool
+ {
+ return true;
+ }
+
+ public function shutdown(): bool
+ {
+ return true;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricExporter/NoopMetricExporterFactory.php b/vendor/open-telemetry/sdk/Metrics/MetricExporter/NoopMetricExporterFactory.php
new file mode 100644
index 000000000..ab2ab2af3
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricExporter/NoopMetricExporterFactory.php
@@ -0,0 +1,16 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricExporter;
+
+use OpenTelemetry\SDK\Metrics\MetricExporterFactoryInterface;
+use OpenTelemetry\SDK\Metrics\MetricExporterInterface;
+
+class NoopMetricExporterFactory implements MetricExporterFactoryInterface
+{
+ public function create(): MetricExporterInterface
+ {
+ return new NoopMetricExporter();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricExporter/_register.php b/vendor/open-telemetry/sdk/Metrics/MetricExporter/_register.php
new file mode 100644
index 000000000..fba543d02
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricExporter/_register.php
@@ -0,0 +1,7 @@
+<?php
+
+declare(strict_types=1);
+
+\OpenTelemetry\SDK\Registry::registerMetricExporterFactory('memory', \OpenTelemetry\SDK\Metrics\MetricExporter\InMemoryExporterFactory::class);
+\OpenTelemetry\SDK\Registry::registerMetricExporterFactory('console', \OpenTelemetry\SDK\Metrics\MetricExporter\ConsoleMetricExporterFactory::class);
+\OpenTelemetry\SDK\Registry::registerMetricExporterFactory('none', \OpenTelemetry\SDK\Metrics\MetricExporter\NoopMetricExporterFactory::class);
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricExporterFactoryInterface.php b/vendor/open-telemetry/sdk/Metrics/MetricExporterFactoryInterface.php
new file mode 100644
index 000000000..0d2541821
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricExporterFactoryInterface.php
@@ -0,0 +1,10 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+interface MetricExporterFactoryInterface
+{
+ public function create(): MetricExporterInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricExporterInterface.php b/vendor/open-telemetry/sdk/Metrics/MetricExporterInterface.php
new file mode 100644
index 000000000..fa47fbf9e
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricExporterInterface.php
@@ -0,0 +1,17 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\SDK\Metrics\Data\Metric;
+
+interface MetricExporterInterface
+{
+ /**
+ * @param iterable<int, Metric> $batch
+ */
+ public function export(iterable $batch): bool;
+
+ public function shutdown(): bool;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricFactory/StreamFactory.php b/vendor/open-telemetry/sdk/Metrics/MetricFactory/StreamFactory.php
new file mode 100644
index 000000000..2c3af4c06
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricFactory/StreamFactory.php
@@ -0,0 +1,187 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricFactory;
+
+use function array_keys;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Metrics\Aggregation\ExplicitBucketHistogramAggregation;
+use OpenTelemetry\SDK\Metrics\AggregationInterface;
+use OpenTelemetry\SDK\Metrics\AttributeProcessor\FilteredAttributeProcessor;
+use OpenTelemetry\SDK\Metrics\AttributeProcessorInterface;
+use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilterInterface;
+use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarReservoirInterface;
+use OpenTelemetry\SDK\Metrics\Exemplar\FilteredReservoir;
+use OpenTelemetry\SDK\Metrics\Exemplar\FixedSizeReservoir;
+use OpenTelemetry\SDK\Metrics\Exemplar\HistogramBucketReservoir;
+use OpenTelemetry\SDK\Metrics\Instrument;
+use OpenTelemetry\SDK\Metrics\MetricFactoryInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistrationInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricCollectorInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricRegistryInterface;
+use OpenTelemetry\SDK\Metrics\Stream\AsynchronousMetricStream;
+use OpenTelemetry\SDK\Metrics\Stream\MetricAggregator;
+use OpenTelemetry\SDK\Metrics\Stream\MetricAggregatorFactory;
+use OpenTelemetry\SDK\Metrics\Stream\MetricStreamInterface;
+use OpenTelemetry\SDK\Metrics\Stream\SynchronousMetricStream;
+use OpenTelemetry\SDK\Metrics\ViewProjection;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+use function serialize;
+use function spl_object_id;
+use Throwable;
+
+/**
+ * @internal
+ */
+final class StreamFactory implements MetricFactoryInterface
+{
+ public function createAsynchronousObserver(
+ MetricRegistryInterface $registry,
+ ResourceInfo $resource,
+ InstrumentationScopeInterface $instrumentationScope,
+ Instrument $instrument,
+ int $timestamp,
+ iterable $views
+ ): array {
+ $streams = [];
+ $dedup = [];
+ foreach ($views as [$view, $registration]) {
+ if ($view->aggregation === null) {
+ continue;
+ }
+
+ $dedupId = $this->streamId($view->aggregation, $view->attributeKeys);
+ if (($streamId = $dedup[$dedupId] ?? null) === null) {
+ $stream = new AsynchronousMetricStream($view->aggregation, $timestamp);
+ $streamId = $registry->registerAsynchronousStream($instrument, $stream, new MetricAggregatorFactory(
+ $this->attributeProcessor($view->attributeKeys),
+ $view->aggregation,
+ ));
+
+ $streams[$streamId] = $stream;
+ $dedup[$dedupId] = $streamId;
+ }
+
+ $this->registerSource(
+ $view,
+ $instrument,
+ $instrumentationScope,
+ $resource,
+ $streams[$streamId],
+ $registry,
+ $registration,
+ $streamId,
+ );
+ }
+
+ return array_keys($streams);
+ }
+
+ public function createSynchronousWriter(
+ MetricRegistryInterface $registry,
+ ResourceInfo $resource,
+ InstrumentationScopeInterface $instrumentationScope,
+ Instrument $instrument,
+ int $timestamp,
+ iterable $views,
+ ?ExemplarFilterInterface $exemplarFilter = null
+ ): array {
+ $streams = [];
+ $dedup = [];
+ foreach ($views as [$view, $registration]) {
+ if ($view->aggregation === null) {
+ continue;
+ }
+
+ $dedupId = $this->streamId($view->aggregation, $view->attributeKeys);
+ if (($streamId = $dedup[$dedupId] ?? null) === null) {
+ $stream = new SynchronousMetricStream($view->aggregation, $timestamp);
+ $streamId = $registry->registerSynchronousStream($instrument, $stream, new MetricAggregator(
+ $this->attributeProcessor($view->attributeKeys),
+ $view->aggregation,
+ $this->createExemplarReservoir($view->aggregation, $exemplarFilter),
+ ));
+
+ $streams[$streamId] = $stream;
+ $dedup[$dedupId] = $streamId;
+ }
+
+ $this->registerSource(
+ $view,
+ $instrument,
+ $instrumentationScope,
+ $resource,
+ $streams[$streamId],
+ $registry,
+ $registration,
+ $streamId,
+ );
+ }
+
+ return array_keys($streams);
+ }
+
+ private function attributeProcessor(
+ ?array $attributeKeys
+ ): ?AttributeProcessorInterface {
+ return $attributeKeys !== null
+ ? new FilteredAttributeProcessor($attributeKeys)
+ : null;
+ }
+
+ private function createExemplarReservoir(
+ AggregationInterface $aggregation,
+ ?ExemplarFilterInterface $exemplarFilter
+ ): ?ExemplarReservoirInterface {
+ if (!$exemplarFilter) {
+ return null;
+ }
+
+ if ($aggregation instanceof ExplicitBucketHistogramAggregation && $aggregation->boundaries) {
+ $exemplarReservoir = new HistogramBucketReservoir($aggregation->boundaries);
+ } else {
+ $exemplarReservoir = new FixedSizeReservoir();
+ }
+
+ return new FilteredReservoir($exemplarReservoir, $exemplarFilter);
+ }
+
+ private function registerSource(
+ ViewProjection $view,
+ Instrument $instrument,
+ InstrumentationScopeInterface $instrumentationScope,
+ ResourceInfo $resource,
+ MetricStreamInterface $stream,
+ MetricCollectorInterface $metricCollector,
+ MetricRegistrationInterface $metricRegistration,
+ int $streamId
+ ): void {
+ $provider = new StreamMetricSourceProvider(
+ $view,
+ $instrument,
+ $instrumentationScope,
+ $resource,
+ $stream,
+ $metricCollector,
+ $streamId,
+ );
+
+ $metricRegistration->register($provider, $provider);
+ }
+
+ private function streamId(AggregationInterface $aggregation, ?array $attributeKeys): string
+ {
+ return $this->trySerialize($aggregation) . serialize($attributeKeys);
+ }
+
+ private function trySerialize(object $object)
+ {
+ try {
+ return serialize($object);
+ } catch (Throwable $e) {
+ }
+
+ return spl_object_id($object);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricFactory/StreamMetricSource.php b/vendor/open-telemetry/sdk/Metrics/MetricFactory/StreamMetricSource.php
new file mode 100644
index 000000000..4939a5341
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricFactory/StreamMetricSource.php
@@ -0,0 +1,44 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricFactory;
+
+use OpenTelemetry\SDK\Metrics\Data\Metric;
+use OpenTelemetry\SDK\Metrics\MetricSourceInterface;
+
+/**
+ * @internal
+ */
+final class StreamMetricSource implements MetricSourceInterface
+{
+ private StreamMetricSourceProvider $provider;
+ private int $reader;
+ public function __construct(StreamMetricSourceProvider $provider, int $reader)
+ {
+ $this->provider = $provider;
+ $this->reader = $reader;
+ }
+
+ public function collectionTimestamp(): int
+ {
+ return $this->provider->stream->timestamp();
+ }
+
+ public function collect(): Metric
+ {
+ return new Metric(
+ $this->provider->instrumentationLibrary,
+ $this->provider->resource,
+ $this->provider->view->name,
+ $this->provider->view->unit,
+ $this->provider->view->description,
+ $this->provider->stream->collect($this->reader),
+ );
+ }
+
+ public function __destruct()
+ {
+ $this->provider->stream->unregister($this->reader);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricFactory/StreamMetricSourceProvider.php b/vendor/open-telemetry/sdk/Metrics/MetricFactory/StreamMetricSourceProvider.php
new file mode 100644
index 000000000..657c3ce62
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricFactory/StreamMetricSourceProvider.php
@@ -0,0 +1,98 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricFactory;
+
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Metrics\Instrument;
+use OpenTelemetry\SDK\Metrics\MetricMetadataInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricCollectorInterface;
+use OpenTelemetry\SDK\Metrics\MetricSourceInterface;
+use OpenTelemetry\SDK\Metrics\MetricSourceProviderInterface;
+use OpenTelemetry\SDK\Metrics\Stream\MetricStreamInterface;
+use OpenTelemetry\SDK\Metrics\ViewProjection;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+
+/**
+ * @internal
+ */
+final class StreamMetricSourceProvider implements MetricSourceProviderInterface, MetricMetadataInterface
+{
+ /**
+ * @readonly
+ */
+ public ViewProjection $view;
+ /**
+ * @readonly
+ */
+ public Instrument $instrument;
+ /**
+ * @readonly
+ */
+ public InstrumentationScopeInterface $instrumentationLibrary;
+ /**
+ * @readonly
+ */
+ public ResourceInfo $resource;
+ /**
+ * @readonly
+ */
+ public MetricStreamInterface $stream;
+ /**
+ * @readonly
+ */
+ public MetricCollectorInterface $metricCollector;
+ /**
+ * @readonly
+ */
+ public int $streamId;
+
+ public function __construct(
+ ViewProjection $view,
+ Instrument $instrument,
+ InstrumentationScopeInterface $instrumentationLibrary,
+ ResourceInfo $resource,
+ MetricStreamInterface $stream,
+ MetricCollectorInterface $metricCollector,
+ int $streamId
+ ) {
+ $this->view = $view;
+ $this->instrument = $instrument;
+ $this->instrumentationLibrary = $instrumentationLibrary;
+ $this->resource = $resource;
+ $this->stream = $stream;
+ $this->metricCollector = $metricCollector;
+ $this->streamId = $streamId;
+ }
+
+ public function create($temporality): MetricSourceInterface
+ {
+ return new StreamMetricSource($this, $this->stream->register($temporality));
+ }
+
+ public function instrumentType()
+ {
+ return $this->instrument->type;
+ }
+
+ public function name(): string
+ {
+ return $this->view->name;
+ }
+
+ public function unit(): ?string
+ {
+ return $this->view->unit;
+ }
+
+ public function description(): ?string
+ {
+ return $this->view->description;
+ }
+
+ public function temporality()
+ {
+ return $this->stream->temporality();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricFactoryInterface.php b/vendor/open-telemetry/sdk/Metrics/MetricFactoryInterface.php
new file mode 100644
index 000000000..a1e228eef
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricFactoryInterface.php
@@ -0,0 +1,41 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilterInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricRegistryInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+
+/**
+ * @internal
+ */
+interface MetricFactoryInterface
+{
+ /**
+ * @param iterable<array{ViewProjection, MetricRegistrationInterface}> $views
+ */
+ public function createAsynchronousObserver(
+ MetricRegistryInterface $registry,
+ ResourceInfo $resource,
+ InstrumentationScopeInterface $instrumentationScope,
+ Instrument $instrument,
+ int $timestamp,
+ iterable $views
+ ): array;
+
+ /**
+ * @param iterable<array{ViewProjection, MetricRegistrationInterface}> $views
+ */
+ public function createSynchronousWriter(
+ MetricRegistryInterface $registry,
+ ResourceInfo $resource,
+ InstrumentationScopeInterface $instrumentationScope,
+ Instrument $instrument,
+ int $timestamp,
+ iterable $views,
+ ?ExemplarFilterInterface $exemplarFilter = null
+ ): array;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricMetadataInterface.php b/vendor/open-telemetry/sdk/Metrics/MetricMetadataInterface.php
new file mode 100644
index 000000000..aa1a02d60
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricMetadataInterface.php
@@ -0,0 +1,28 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\SDK\Metrics\Data\Temporality;
+
+interface MetricMetadataInterface
+{
+ /**
+ * @return string|InstrumentType
+ */
+ public function instrumentType();
+
+ public function name(): string;
+
+ public function unit(): ?string;
+
+ public function description(): ?string;
+
+ /**
+ * Returns the underlying temporality of this metric.
+ *
+ * @return string|Temporality internal temporality
+ */
+ public function temporality();
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricReader/ExportingReader.php b/vendor/open-telemetry/sdk/Metrics/MetricReader/ExportingReader.php
new file mode 100644
index 000000000..3c2eff9f1
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricReader/ExportingReader.php
@@ -0,0 +1,156 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricReader;
+
+use function array_keys;
+use OpenTelemetry\SDK\Metrics\AggregationInterface;
+use OpenTelemetry\SDK\Metrics\AggregationTemporalitySelectorInterface;
+use OpenTelemetry\SDK\Metrics\DefaultAggregationProviderInterface;
+use OpenTelemetry\SDK\Metrics\DefaultAggregationProviderTrait;
+use OpenTelemetry\SDK\Metrics\MetricExporterInterface;
+use OpenTelemetry\SDK\Metrics\MetricFactory\StreamMetricSourceProvider;
+use OpenTelemetry\SDK\Metrics\MetricMetadataInterface;
+use OpenTelemetry\SDK\Metrics\MetricReaderInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricCollectorInterface;
+use OpenTelemetry\SDK\Metrics\MetricSourceInterface;
+use OpenTelemetry\SDK\Metrics\MetricSourceProviderInterface;
+use OpenTelemetry\SDK\Metrics\MetricSourceRegistryInterface;
+use OpenTelemetry\SDK\Metrics\PushMetricExporterInterface;
+use OpenTelemetry\SDK\Metrics\StalenessHandlerInterface;
+use function spl_object_id;
+
+final class ExportingReader implements MetricReaderInterface, MetricSourceRegistryInterface, DefaultAggregationProviderInterface
+{
+ use DefaultAggregationProviderTrait { defaultAggregation as private _defaultAggregation; }
+
+ private MetricExporterInterface $exporter;
+ /** @var array<int, MetricSourceInterface> */
+ private array $sources = [];
+
+ /** @var array<int, MetricCollectorInterface> */
+ private array $registries = [];
+ /** @var array<int, array<int, int>> */
+ private array $streamIds = [];
+
+ private bool $closed = false;
+
+ public function __construct(MetricExporterInterface $exporter)
+ {
+ $this->exporter = $exporter;
+ }
+
+ public function defaultAggregation($instrumentType): ?AggregationInterface
+ {
+ if ($this->exporter instanceof DefaultAggregationProviderInterface) {
+ return $this->exporter->defaultAggregation($instrumentType);
+ }
+
+ return $this->_defaultAggregation($instrumentType);
+ }
+
+ public function add(MetricSourceProviderInterface $provider, MetricMetadataInterface $metadata, StalenessHandlerInterface $stalenessHandler): void
+ {
+ if ($this->closed) {
+ return;
+ }
+ if (!$this->exporter instanceof AggregationTemporalitySelectorInterface) {
+ return;
+ }
+ if (!$temporality = $this->exporter->temporality($metadata)) {
+ return;
+ }
+
+ $source = $provider->create($temporality);
+ $sourceId = spl_object_id($source);
+
+ $this->sources[$sourceId] = $source;
+ $stalenessHandler->onStale(function () use ($sourceId): void {
+ unset($this->sources[$sourceId]);
+ });
+
+ if (!$provider instanceof StreamMetricSourceProvider) {
+ return;
+ }
+
+ $streamId = $provider->streamId;
+ $registry = $provider->metricCollector;
+ $registryId = spl_object_id($registry);
+
+ $this->registries[$registryId] = $registry;
+ $this->streamIds[$registryId][$streamId] ??= 0;
+ $this->streamIds[$registryId][$streamId]++;
+
+ $stalenessHandler->onStale(function () use ($streamId, $registryId): void {
+ if (!--$this->streamIds[$registryId][$streamId]) {
+ unset($this->streamIds[$registryId][$streamId]);
+ if (!$this->streamIds[$registryId]) {
+ unset(
+ $this->registries[$registryId],
+ $this->streamIds[$registryId],
+ );
+ }
+ }
+ });
+ }
+
+ private function doCollect(): bool
+ {
+ foreach ($this->registries as $registryId => $registry) {
+ $streamIds = $this->streamIds[$registryId] ?? [];
+ $registry->collectAndPush(array_keys($streamIds));
+ }
+
+ $metrics = [];
+ foreach ($this->sources as $source) {
+ $metrics[] = $source->collect();
+ }
+
+ if ($metrics === []) {
+ return true;
+ }
+
+ return $this->exporter->export($metrics);
+ }
+
+ public function collect(): bool
+ {
+ if ($this->closed) {
+ return false;
+ }
+
+ return $this->doCollect();
+ }
+
+ public function shutdown(): bool
+ {
+ if ($this->closed) {
+ return false;
+ }
+
+ $this->closed = true;
+
+ $collect = $this->doCollect();
+ $shutdown = $this->exporter->shutdown();
+
+ $this->sources = [];
+
+ return $collect && $shutdown;
+ }
+
+ public function forceFlush(): bool
+ {
+ if ($this->closed) {
+ return false;
+ }
+ if ($this->exporter instanceof PushMetricExporterInterface) {
+ $collect = $this->doCollect();
+ $forceFlush = $this->exporter->forceFlush();
+
+ return $collect && $forceFlush;
+ }
+
+ return true;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricReaderInterface.php b/vendor/open-telemetry/sdk/Metrics/MetricReaderInterface.php
new file mode 100644
index 000000000..f5900eef5
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricReaderInterface.php
@@ -0,0 +1,14 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+interface MetricReaderInterface
+{
+ public function collect(): bool;
+
+ public function shutdown(): bool;
+
+ public function forceFlush(): bool;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricRegistration/MultiRegistryRegistration.php b/vendor/open-telemetry/sdk/Metrics/MetricRegistration/MultiRegistryRegistration.php
new file mode 100644
index 000000000..2472c096f
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricRegistration/MultiRegistryRegistration.php
@@ -0,0 +1,36 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricRegistration;
+
+use OpenTelemetry\SDK\Metrics\MetricMetadataInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistrationInterface;
+use OpenTelemetry\SDK\Metrics\MetricSourceProviderInterface;
+use OpenTelemetry\SDK\Metrics\MetricSourceRegistryInterface;
+use OpenTelemetry\SDK\Metrics\StalenessHandlerInterface;
+
+/**
+ * @internal
+ */
+final class MultiRegistryRegistration implements MetricRegistrationInterface
+{
+ private iterable $registries;
+ private StalenessHandlerInterface $stalenessHandler;
+
+ /**
+ * @param iterable<MetricSourceRegistryInterface> $registries
+ */
+ public function __construct(iterable $registries, StalenessHandlerInterface $stalenessHandler)
+ {
+ $this->registries = $registries;
+ $this->stalenessHandler = $stalenessHandler;
+ }
+
+ public function register(MetricSourceProviderInterface $provider, MetricMetadataInterface $metadata): void
+ {
+ foreach ($this->registries as $registry) {
+ $registry->add($provider, $metadata, $this->stalenessHandler);
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricRegistration/RegistryRegistration.php b/vendor/open-telemetry/sdk/Metrics/MetricRegistration/RegistryRegistration.php
new file mode 100644
index 000000000..3c1108902
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricRegistration/RegistryRegistration.php
@@ -0,0 +1,31 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricRegistration;
+
+use OpenTelemetry\SDK\Metrics\MetricMetadataInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistrationInterface;
+use OpenTelemetry\SDK\Metrics\MetricSourceProviderInterface;
+use OpenTelemetry\SDK\Metrics\MetricSourceRegistryInterface;
+use OpenTelemetry\SDK\Metrics\StalenessHandlerInterface;
+
+/**
+ * @internal
+ */
+final class RegistryRegistration implements MetricRegistrationInterface
+{
+ private MetricSourceRegistryInterface $registry;
+ private StalenessHandlerInterface $stalenessHandler;
+
+ public function __construct(MetricSourceRegistryInterface $registry, StalenessHandlerInterface $stalenessHandler)
+ {
+ $this->registry = $registry;
+ $this->stalenessHandler = $stalenessHandler;
+ }
+
+ public function register(MetricSourceProviderInterface $provider, MetricMetadataInterface $metadata): void
+ {
+ $this->registry->add($provider, $metadata, $this->stalenessHandler);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricRegistrationInterface.php b/vendor/open-telemetry/sdk/Metrics/MetricRegistrationInterface.php
new file mode 100644
index 000000000..b0cc2484e
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricRegistrationInterface.php
@@ -0,0 +1,13 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+/**
+ * @internal
+ */
+interface MetricRegistrationInterface
+{
+ public function register(MetricSourceProviderInterface $provider, MetricMetadataInterface $metadata): void;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricCollectorInterface.php b/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricCollectorInterface.php
new file mode 100644
index 000000000..4e8e91ced
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricCollectorInterface.php
@@ -0,0 +1,13 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricRegistry;
+
+/**
+ * @internal
+ */
+interface MetricCollectorInterface
+{
+ public function collectAndPush(iterable $streamIds): void;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricRegistry.php b/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricRegistry.php
new file mode 100644
index 000000000..9a18d2a84
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricRegistry.php
@@ -0,0 +1,184 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricRegistry;
+
+use function array_key_last;
+use Closure;
+use OpenTelemetry\Context\Context;
+use OpenTelemetry\Context\ContextStorageInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesFactoryInterface;
+use OpenTelemetry\SDK\Common\Time\ClockInterface;
+use OpenTelemetry\SDK\Metrics\Instrument;
+use OpenTelemetry\SDK\Metrics\Stream\MetricAggregatorFactoryInterface;
+use OpenTelemetry\SDK\Metrics\Stream\MetricAggregatorInterface;
+use OpenTelemetry\SDK\Metrics\Stream\MetricStreamInterface;
+use function spl_object_id;
+
+/**
+ * @internal
+ */
+final class MetricRegistry implements MetricRegistryInterface, MetricWriterInterface
+{
+ private ?ContextStorageInterface $contextStorage;
+ private AttributesFactoryInterface $attributesFactory;
+ private ClockInterface $clock;
+
+ /** @var array<int, MetricStreamInterface> */
+ private array $streams = [];
+ /** @var array<int, MetricAggregatorInterface> */
+ private array $synchronousAggregators = [];
+ /** @var array<int, MetricAggregatorFactoryInterface> */
+ private array $asynchronousAggregatorFactories = [];
+
+ /** @var array<int, array<int, int>> */
+ private array $instrumentToStreams = [];
+ /** @var array<int, int> */
+ private array $streamToInstrument = [];
+ /** @var array<int, array<int, int>> */
+ private array $instrumentToCallbacks = [];
+ /** @var array<int, Closure> */
+ private array $asynchronousCallbacks = [];
+ /** @var array<int, list<int>> */
+ private array $asynchronousCallbackArguments = [];
+
+ public function __construct(
+ ?ContextStorageInterface $contextStorage,
+ AttributesFactoryInterface $attributesFactory,
+ ClockInterface $clock
+ ) {
+ $this->contextStorage = $contextStorage;
+ $this->attributesFactory = $attributesFactory;
+ $this->clock = $clock;
+ }
+
+ public function registerSynchronousStream(Instrument $instrument, MetricStreamInterface $stream, MetricAggregatorInterface $aggregator): int
+ {
+ $this->streams[] = $stream;
+ $streamId = array_key_last($this->streams);
+ $instrumentId = spl_object_id($instrument);
+
+ $this->synchronousAggregators[$streamId] = $aggregator;
+ $this->instrumentToStreams[$instrumentId][$streamId] = $streamId;
+ $this->streamToInstrument[$streamId] = $instrumentId;
+
+ return $streamId;
+ }
+
+ public function registerAsynchronousStream(Instrument $instrument, MetricStreamInterface $stream, MetricAggregatorFactoryInterface $aggregatorFactory): int
+ {
+ $this->streams[] = $stream;
+ $streamId = array_key_last($this->streams);
+ $instrumentId = spl_object_id($instrument);
+
+ $this->asynchronousAggregatorFactories[$streamId] = $aggregatorFactory;
+ $this->instrumentToStreams[$instrumentId][$streamId] = $streamId;
+ $this->streamToInstrument[$streamId] = $instrumentId;
+
+ return $streamId;
+ }
+
+ public function unregisterStream(int $streamId): void
+ {
+ $instrumentId = $this->streamToInstrument[$streamId];
+ unset(
+ $this->streams[$streamId],
+ $this->synchronousAggregators[$streamId],
+ $this->asynchronousAggregatorFactories[$streamId],
+ $this->instrumentToStreams[$instrumentId][$streamId],
+ $this->streamToInstrument[$streamId],
+ );
+ if (!$this->instrumentToStreams[$instrumentId]) {
+ unset($this->instrumentToStreams[$instrumentId]);
+ }
+ }
+
+ public function record(Instrument $instrument, $value, iterable $attributes = [], $context = null): void
+ {
+ $context = Context::resolve($context, $this->contextStorage);
+ $attributes = $this->attributesFactory->builder($attributes)->build();
+ $timestamp = $this->clock->now();
+ $instrumentId = spl_object_id($instrument);
+ foreach ($this->instrumentToStreams[$instrumentId] ?? [] as $streamId) {
+ if ($aggregator = $this->synchronousAggregators[$streamId] ?? null) {
+ $aggregator->record($value, $attributes, $context, $timestamp);
+ }
+ }
+ }
+
+ public function registerCallback(Closure $callback, Instrument $instrument, Instrument ...$instruments): int
+ {
+ $callbackId = array_key_last($this->asynchronousCallbacks) + 1;
+ $this->asynchronousCallbacks[$callbackId] = $callback;
+
+ $instrumentId = spl_object_id($instrument);
+ $this->asynchronousCallbackArguments[$callbackId] = [$instrumentId];
+ $this->instrumentToCallbacks[$instrumentId][$callbackId] = $callbackId;
+ foreach ($instruments as $instrument) {
+ $instrumentId = spl_object_id($instrument);
+ $this->asynchronousCallbackArguments[$callbackId][] = $instrumentId;
+ $this->instrumentToCallbacks[$instrumentId][$callbackId] = $callbackId;
+ }
+
+ return $callbackId;
+ }
+
+ public function unregisterCallback(int $callbackId): void
+ {
+ $instrumentIds = $this->asynchronousCallbackArguments[$callbackId];
+ unset(
+ $this->asynchronousCallbacks[$callbackId],
+ $this->asynchronousCallbackArguments[$callbackId],
+ );
+ foreach ($instrumentIds as $instrumentId) {
+ unset($this->instrumentToCallbacks[$instrumentId][$callbackId]);
+ if (!$this->instrumentToCallbacks[$instrumentId]) {
+ unset($this->instrumentToCallbacks[$instrumentId]);
+ }
+ }
+ }
+
+ public function collectAndPush(iterable $streamIds): void
+ {
+ $timestamp = $this->clock->now();
+ $aggregators = [];
+ $observers = [];
+ $callbackIds = [];
+ foreach ($streamIds as $streamId) {
+ if (!$aggregator = $this->synchronousAggregators[$streamId] ?? null) {
+ $aggregator = $this->asynchronousAggregatorFactories[$streamId]->create();
+
+ $instrumentId = $this->streamToInstrument[$streamId];
+ $observers[$instrumentId] ??= new MultiObserver($this->attributesFactory, $timestamp);
+ $observers[$instrumentId]->writers[] = $aggregator;
+ foreach ($this->instrumentToCallbacks[$instrumentId] ?? [] as $callbackId) {
+ $callbackIds[$callbackId] = $callbackId;
+ }
+ }
+
+ $aggregators[$streamId] = $aggregator;
+ }
+
+ $noopObserver = new NoopObserver();
+ $callbacks = [];
+ foreach ($callbackIds as $callbackId) {
+ $args = [];
+ foreach ($this->asynchronousCallbackArguments[$callbackId] as $instrumentId) {
+ $args[] = $observers[$instrumentId] ?? $noopObserver;
+ }
+ $callback = $this->asynchronousCallbacks[$callbackId];
+ $callbacks[] = static fn () => $callback(...$args);
+ }
+ foreach ($callbacks as $callback) {
+ $callback();
+ }
+
+ $timestamp = $this->clock->now();
+ foreach ($aggregators as $streamId => $aggregator) {
+ if ($stream = $this->streams[$streamId] ?? null) {
+ $stream->push($aggregator->collect($timestamp));
+ }
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricRegistryInterface.php b/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricRegistryInterface.php
new file mode 100644
index 000000000..e86731138
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricRegistryInterface.php
@@ -0,0 +1,22 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricRegistry;
+
+use OpenTelemetry\SDK\Metrics\Instrument;
+use OpenTelemetry\SDK\Metrics\Stream\MetricAggregatorFactoryInterface;
+use OpenTelemetry\SDK\Metrics\Stream\MetricAggregatorInterface;
+use OpenTelemetry\SDK\Metrics\Stream\MetricStreamInterface;
+
+/**
+ * @internal
+ */
+interface MetricRegistryInterface extends MetricCollectorInterface
+{
+ public function registerSynchronousStream(Instrument $instrument, MetricStreamInterface $stream, MetricAggregatorInterface $aggregator): int;
+
+ public function registerAsynchronousStream(Instrument $instrument, MetricStreamInterface $stream, MetricAggregatorFactoryInterface $aggregatorFactory): int;
+
+ public function unregisterStream(int $streamId): void;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricWriterInterface.php b/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricWriterInterface.php
new file mode 100644
index 000000000..e5ff7eb5c
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricWriterInterface.php
@@ -0,0 +1,20 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricRegistry;
+
+use Closure;
+use OpenTelemetry\SDK\Metrics\Instrument;
+
+/**
+ * @internal
+ */
+interface MetricWriterInterface
+{
+ public function record(Instrument $instrument, $value, iterable $attributes = [], $context = null): void;
+
+ public function registerCallback(Closure $callback, Instrument $instrument, Instrument ...$instruments): int;
+
+ public function unregisterCallback(int $callbackId): void;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MultiObserver.php b/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MultiObserver.php
new file mode 100644
index 000000000..f36f74a2a
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MultiObserver.php
@@ -0,0 +1,37 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricRegistry;
+
+use OpenTelemetry\API\Metrics\ObserverInterface;
+use OpenTelemetry\Context\Context;
+use OpenTelemetry\SDK\Common\Attribute\AttributesFactoryInterface;
+use OpenTelemetry\SDK\Metrics\Stream\WritableMetricStreamInterface;
+
+/**
+ * @internal
+ */
+final class MultiObserver implements ObserverInterface
+{
+ private AttributesFactoryInterface $attributesFactory;
+ private int $timestamp;
+
+ /** @var list<WritableMetricStreamInterface> */
+ public array $writers = [];
+
+ public function __construct(AttributesFactoryInterface $attributesFactory, int $timestamp)
+ {
+ $this->attributesFactory = $attributesFactory;
+ $this->timestamp = $timestamp;
+ }
+
+ public function observe($amount, iterable $attributes = []): void
+ {
+ $context = Context::getRoot();
+ $attributes = $this->attributesFactory->builder($attributes)->build();
+ foreach ($this->writers as $writer) {
+ $writer->record($amount, $attributes, $context, $this->timestamp);
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricRegistry/NoopObserver.php b/vendor/open-telemetry/sdk/Metrics/MetricRegistry/NoopObserver.php
new file mode 100644
index 000000000..efbd94dac
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricRegistry/NoopObserver.php
@@ -0,0 +1,18 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricRegistry;
+
+use OpenTelemetry\API\Metrics\ObserverInterface;
+
+/**
+ * @internal
+ */
+final class NoopObserver implements ObserverInterface
+{
+ public function observe($amount, iterable $attributes = []): void
+ {
+ // no-op
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricSourceInterface.php b/vendor/open-telemetry/sdk/Metrics/MetricSourceInterface.php
new file mode 100644
index 000000000..5f00a0717
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricSourceInterface.php
@@ -0,0 +1,24 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\SDK\Metrics\Data\Metric;
+
+interface MetricSourceInterface
+{
+ /**
+ * Returns the last metric collection timestamp.
+ *
+ * @return int last collection timestamp
+ */
+ public function collectionTimestamp(): int;
+
+ /**
+ * Collects metric data from the underlying provider.
+ *
+ * @return Metric collected metric
+ */
+ public function collect(): Metric;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricSourceProviderInterface.php b/vendor/open-telemetry/sdk/Metrics/MetricSourceProviderInterface.php
new file mode 100644
index 000000000..f8b6ea438
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricSourceProviderInterface.php
@@ -0,0 +1,15 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\SDK\Metrics\Data\Temporality;
+
+interface MetricSourceProviderInterface
+{
+ /**
+ * @param string|Temporality $temporality
+ */
+ public function create($temporality): MetricSourceInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricSourceRegistryInterface.php b/vendor/open-telemetry/sdk/Metrics/MetricSourceRegistryInterface.php
new file mode 100644
index 000000000..dd7ff53ac
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricSourceRegistryInterface.php
@@ -0,0 +1,10 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+interface MetricSourceRegistryInterface
+{
+ public function add(MetricSourceProviderInterface $provider, MetricMetadataInterface $metadata, StalenessHandlerInterface $stalenessHandler): void;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/NoopMeterProvider.php b/vendor/open-telemetry/sdk/Metrics/NoopMeterProvider.php
new file mode 100644
index 000000000..2efb484d3
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/NoopMeterProvider.php
@@ -0,0 +1,26 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\API\Metrics\MeterInterface;
+use OpenTelemetry\API\Metrics\Noop\NoopMeter;
+
+class NoopMeterProvider implements MeterProviderInterface
+{
+ public function shutdown(): bool
+ {
+ return true;
+ }
+
+ public function forceFlush(): bool
+ {
+ return true;
+ }
+
+ public function getMeter(string $name, ?string $version = null, ?string $schemaUrl = null, iterable $attributes = []): MeterInterface
+ {
+ return new NoopMeter();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/ObservableCallback.php b/vendor/open-telemetry/sdk/Metrics/ObservableCallback.php
new file mode 100644
index 000000000..ffe5ead87
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/ObservableCallback.php
@@ -0,0 +1,58 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\API\Metrics\ObservableCallbackInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricWriterInterface;
+
+/**
+ * @internal
+ */
+final class ObservableCallback implements ObservableCallbackInterface
+{
+ private MetricWriterInterface $writer;
+ private ReferenceCounterInterface $referenceCounter;
+ private ?int $callbackId;
+ private ?ObservableCallbackDestructor $callbackDestructor;
+ /** @phpstan-ignore-next-line */
+ private ?object $target;
+
+ public function __construct(MetricWriterInterface $writer, ReferenceCounterInterface $referenceCounter, int $callbackId, ?ObservableCallbackDestructor $callbackDestructor, ?object $target)
+ {
+ $this->writer = $writer;
+ $this->referenceCounter = $referenceCounter;
+ $this->callbackId = $callbackId;
+ $this->callbackDestructor = $callbackDestructor;
+ $this->target = $target;
+ }
+
+ public function detach(): void
+ {
+ if ($this->callbackId === null) {
+ return;
+ }
+
+ $this->writer->unregisterCallback($this->callbackId);
+ $this->referenceCounter->release();
+ if ($this->callbackDestructor !== null) {
+ unset($this->callbackDestructor->callbackIds[$this->callbackId]);
+ }
+
+ $this->callbackId = null;
+ }
+
+ public function __destruct()
+ {
+ if ($this->callbackDestructor !== null) {
+ return;
+ }
+ if ($this->callbackId === null) {
+ return;
+ }
+
+ $this->referenceCounter->acquire(true);
+ $this->referenceCounter->release();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/ObservableCallbackDestructor.php b/vendor/open-telemetry/sdk/Metrics/ObservableCallbackDestructor.php
new file mode 100644
index 000000000..0dfea3907
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/ObservableCallbackDestructor.php
@@ -0,0 +1,32 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricWriterInterface;
+
+/**
+ * @internal
+ */
+final class ObservableCallbackDestructor
+{
+ /** @var array<int, int> */
+ public array $callbackIds = [];
+ private MetricWriterInterface $writer;
+ private ReferenceCounterInterface $referenceCounter;
+
+ public function __construct(MetricWriterInterface $writer, ReferenceCounterInterface $referenceCounter)
+ {
+ $this->writer = $writer;
+ $this->referenceCounter = $referenceCounter;
+ }
+
+ public function __destruct()
+ {
+ foreach ($this->callbackIds as $callbackId) {
+ $this->writer->unregisterCallback($callbackId);
+ $this->referenceCounter->release();
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/ObservableCounter.php b/vendor/open-telemetry/sdk/Metrics/ObservableCounter.php
new file mode 100644
index 000000000..99ae43eee
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/ObservableCounter.php
@@ -0,0 +1,15 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\API\Metrics\ObservableCounterInterface;
+
+/**
+ * @internal
+ */
+final class ObservableCounter implements ObservableCounterInterface
+{
+ use ObservableInstrumentTrait;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/ObservableGauge.php b/vendor/open-telemetry/sdk/Metrics/ObservableGauge.php
new file mode 100644
index 000000000..88c1a546c
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/ObservableGauge.php
@@ -0,0 +1,15 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\API\Metrics\ObservableGaugeInterface;
+
+/**
+ * @internal
+ */
+final class ObservableGauge implements ObservableGaugeInterface
+{
+ use ObservableInstrumentTrait;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/ObservableInstrumentTrait.php b/vendor/open-telemetry/sdk/Metrics/ObservableInstrumentTrait.php
new file mode 100644
index 000000000..b7fdcf5f8
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/ObservableInstrumentTrait.php
@@ -0,0 +1,61 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use ArrayAccess;
+use OpenTelemetry\API\Metrics\ObservableCallbackInterface;
+use OpenTelemetry\API\Metrics\ObserverInterface;
+use function OpenTelemetry\SDK\Common\Util\closure;
+use function OpenTelemetry\SDK\Common\Util\weaken;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricWriterInterface;
+
+/**
+ * @internal
+ */
+trait ObservableInstrumentTrait
+{
+ private MetricWriterInterface $writer;
+ private Instrument $instrument;
+ private ReferenceCounterInterface $referenceCounter;
+ private ArrayAccess $destructors;
+
+ public function __construct(
+ MetricWriterInterface $writer,
+ Instrument $instrument,
+ ReferenceCounterInterface $referenceCounter,
+ ArrayAccess $destructors
+ ) {
+ $this->writer = $writer;
+ $this->instrument = $instrument;
+ $this->referenceCounter = $referenceCounter;
+ $this->destructors = $destructors;
+
+ $this->referenceCounter->acquire();
+ }
+
+ public function __destruct()
+ {
+ $this->referenceCounter->release();
+ }
+
+ /**
+ * @param callable(ObserverInterface): void $callback
+ */
+ public function observe(callable $callback): ObservableCallbackInterface
+ {
+ $callback = weaken(closure($callback), $target);
+
+ $callbackId = $this->writer->registerCallback($callback, $this->instrument);
+ $this->referenceCounter->acquire();
+
+ $destructor = null;
+ if ($target) {
+ $destructor = $this->destructors[$target] ??= new ObservableCallbackDestructor($this->writer, $this->referenceCounter);
+ $destructor->callbackIds[$callbackId] = $callbackId;
+ }
+
+ return new ObservableCallback($this->writer, $this->referenceCounter, $callbackId, $destructor, $target);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/ObservableUpDownCounter.php b/vendor/open-telemetry/sdk/Metrics/ObservableUpDownCounter.php
new file mode 100644
index 000000000..8d21be734
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/ObservableUpDownCounter.php
@@ -0,0 +1,15 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\API\Metrics\ObservableUpDownCounterInterface;
+
+/**
+ * @internal
+ */
+final class ObservableUpDownCounter implements ObservableUpDownCounterInterface
+{
+ use ObservableInstrumentTrait;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/PushMetricExporterInterface.php b/vendor/open-telemetry/sdk/Metrics/PushMetricExporterInterface.php
new file mode 100644
index 000000000..d24b0e396
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/PushMetricExporterInterface.php
@@ -0,0 +1,12 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\SDK\Metrics;
+
+interface PushMetricExporterInterface extends Metrics\MetricExporterInterface
+{
+ public function forceFlush(): bool;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/ReferenceCounterInterface.php b/vendor/open-telemetry/sdk/Metrics/ReferenceCounterInterface.php
new file mode 100644
index 000000000..f7e70b644
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/ReferenceCounterInterface.php
@@ -0,0 +1,15 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+/**
+ * @internal
+ */
+interface ReferenceCounterInterface
+{
+ public function acquire(bool $persistent = false): void;
+
+ public function release(): void;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/StalenessHandler/DelayedStalenessHandler.php b/vendor/open-telemetry/sdk/Metrics/StalenessHandler/DelayedStalenessHandler.php
new file mode 100644
index 000000000..66b271018
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/StalenessHandler/DelayedStalenessHandler.php
@@ -0,0 +1,71 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\StalenessHandler;
+
+use function assert;
+use Closure;
+use OpenTelemetry\SDK\Metrics\ReferenceCounterInterface;
+use OpenTelemetry\SDK\Metrics\StalenessHandlerInterface;
+
+/**
+ * @internal
+ */
+final class DelayedStalenessHandler implements StalenessHandlerInterface, ReferenceCounterInterface
+{
+ private Closure $stale;
+ private Closure $freshen;
+
+ /** @var Closure[]|null */
+ private ?array $onStale = [];
+ private int $count = 0;
+
+ public function __construct(Closure $stale, Closure $freshen)
+ {
+ $this->stale = $stale;
+ $this->freshen = $freshen;
+ }
+
+ public function acquire(bool $persistent = false): void
+ {
+ if ($this->count === 0) {
+ ($this->freshen)($this);
+ }
+
+ $this->count++;
+
+ if ($persistent) {
+ $this->onStale = null;
+ }
+ }
+
+ public function release(): void
+ {
+ if (--$this->count || $this->onStale === null) {
+ return;
+ }
+
+ ($this->stale)($this);
+ }
+
+ public function onStale(Closure $callback): void
+ {
+ if ($this->onStale === null) {
+ return;
+ }
+
+ $this->onStale[] = $callback;
+ }
+
+ public function triggerStale(): void
+ {
+ assert($this->onStale !== null);
+
+ $callbacks = $this->onStale;
+ $this->onStale = [];
+ foreach ($callbacks as $callback) {
+ $callback();
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/StalenessHandler/DelayedStalenessHandlerFactory.php b/vendor/open-telemetry/sdk/Metrics/StalenessHandler/DelayedStalenessHandlerFactory.php
new file mode 100644
index 000000000..0d719c74f
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/StalenessHandler/DelayedStalenessHandlerFactory.php
@@ -0,0 +1,64 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\StalenessHandler;
+
+use ArrayAccess;
+use Closure;
+use OpenTelemetry\SDK\Common\Time\ClockInterface;
+use OpenTelemetry\SDK\Common\Util\WeakMap;
+use OpenTelemetry\SDK\Metrics\StalenessHandlerFactoryInterface;
+use OpenTelemetry\SDK\Metrics\StalenessHandlerInterface;
+use Traversable;
+
+final class DelayedStalenessHandlerFactory implements StalenessHandlerFactoryInterface
+{
+ private ClockInterface $clock;
+ private int $nanoDelay;
+
+ private Closure $stale;
+ private Closure $freshen;
+
+ /** @var ArrayAccess<DelayedStalenessHandler, int>&Traversable<DelayedStalenessHandler, int> */
+ private $staleHandlers;
+
+ /**
+ * @param float $delay delay in seconds
+ */
+ public function __construct(ClockInterface $clock, float $delay)
+ {
+ $this->clock = $clock;
+ $this->nanoDelay = (int) ($delay * 1e9);
+
+ $this->stale = function (DelayedStalenessHandler $handler): void {
+ $this->staleHandlers[$handler] = $this->clock->now();
+ };
+ $this->freshen = function (DelayedStalenessHandler $handler): void {
+ unset($this->staleHandlers[$handler]);
+ };
+
+ $this->staleHandlers = WeakMap::create();
+ }
+
+ public function create(): StalenessHandlerInterface
+ {
+ $this->triggerStaleHandlers();
+
+ return new DelayedStalenessHandler($this->stale, $this->freshen);
+ }
+
+ private function triggerStaleHandlers(): void
+ {
+ $expired = $this->clock->now() - $this->nanoDelay;
+ foreach ($this->staleHandlers as $handler => $timestamp) {
+ if ($timestamp > $expired) {
+ break;
+ }
+
+ /** @var DelayedStalenessHandler $handler */
+ unset($this->staleHandlers[$handler]);
+ $handler->triggerStale();
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/StalenessHandler/ImmediateStalenessHandler.php b/vendor/open-telemetry/sdk/Metrics/StalenessHandler/ImmediateStalenessHandler.php
new file mode 100644
index 000000000..a5b32d5c4
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/StalenessHandler/ImmediateStalenessHandler.php
@@ -0,0 +1,50 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\StalenessHandler;
+
+use Closure;
+use OpenTelemetry\SDK\Metrics\ReferenceCounterInterface;
+use OpenTelemetry\SDK\Metrics\StalenessHandlerInterface;
+
+/**
+ * @internal
+ */
+final class ImmediateStalenessHandler implements StalenessHandlerInterface, ReferenceCounterInterface
+{
+ /** @var Closure[]|null */
+ private ?array $onStale = [];
+ private int $count = 0;
+
+ public function acquire(bool $persistent = false): void
+ {
+ $this->count++;
+
+ if ($persistent) {
+ $this->onStale = null;
+ }
+ }
+
+ public function release(): void
+ {
+ if (--$this->count !== 0 || !$this->onStale) {
+ return;
+ }
+
+ $callbacks = $this->onStale;
+ $this->onStale = [];
+ foreach ($callbacks as $callback) {
+ $callback();
+ }
+ }
+
+ public function onStale(Closure $callback): void
+ {
+ if ($this->onStale === null) {
+ return;
+ }
+
+ $this->onStale[] = $callback;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/StalenessHandler/ImmediateStalenessHandlerFactory.php b/vendor/open-telemetry/sdk/Metrics/StalenessHandler/ImmediateStalenessHandlerFactory.php
new file mode 100644
index 000000000..899615dea
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/StalenessHandler/ImmediateStalenessHandlerFactory.php
@@ -0,0 +1,16 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\StalenessHandler;
+
+use OpenTelemetry\SDK\Metrics\StalenessHandlerFactoryInterface;
+use OpenTelemetry\SDK\Metrics\StalenessHandlerInterface;
+
+final class ImmediateStalenessHandlerFactory implements StalenessHandlerFactoryInterface
+{
+ public function create(): StalenessHandlerInterface
+ {
+ return new ImmediateStalenessHandler();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/StalenessHandler/NoopStalenessHandler.php b/vendor/open-telemetry/sdk/Metrics/StalenessHandler/NoopStalenessHandler.php
new file mode 100644
index 000000000..00d432b6b
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/StalenessHandler/NoopStalenessHandler.php
@@ -0,0 +1,30 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\StalenessHandler;
+
+use Closure;
+use OpenTelemetry\SDK\Metrics\ReferenceCounterInterface;
+use OpenTelemetry\SDK\Metrics\StalenessHandlerInterface;
+
+/**
+ * @internal
+ */
+final class NoopStalenessHandler implements StalenessHandlerInterface, ReferenceCounterInterface
+{
+ public function acquire(bool $persistent = false): void
+ {
+ // no-op
+ }
+
+ public function release(): void
+ {
+ // no-op
+ }
+
+ public function onStale(Closure $callback): void
+ {
+ // no-op
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/StalenessHandler/NoopStalenessHandlerFactory.php b/vendor/open-telemetry/sdk/Metrics/StalenessHandler/NoopStalenessHandlerFactory.php
new file mode 100644
index 000000000..07f34e3b0
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/StalenessHandler/NoopStalenessHandlerFactory.php
@@ -0,0 +1,18 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\StalenessHandler;
+
+use OpenTelemetry\SDK\Metrics\StalenessHandlerFactoryInterface;
+use OpenTelemetry\SDK\Metrics\StalenessHandlerInterface;
+
+final class NoopStalenessHandlerFactory implements StalenessHandlerFactoryInterface
+{
+ public function create(): StalenessHandlerInterface
+ {
+ static $instance;
+
+ return $instance ??= new NoopStalenessHandler();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/StalenessHandlerFactoryInterface.php b/vendor/open-telemetry/sdk/Metrics/StalenessHandlerFactoryInterface.php
new file mode 100644
index 000000000..e22385420
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/StalenessHandlerFactoryInterface.php
@@ -0,0 +1,13 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+interface StalenessHandlerFactoryInterface
+{
+ /**
+ * @return StalenessHandlerInterface&ReferenceCounterInterface
+ */
+ public function create(): StalenessHandlerInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/StalenessHandlerInterface.php b/vendor/open-telemetry/sdk/Metrics/StalenessHandlerInterface.php
new file mode 100644
index 000000000..c85d86f8e
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/StalenessHandlerInterface.php
@@ -0,0 +1,12 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use Closure;
+
+interface StalenessHandlerInterface
+{
+ public function onStale(Closure $callback): void;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Stream/AsynchronousMetricStream.php b/vendor/open-telemetry/sdk/Metrics/Stream/AsynchronousMetricStream.php
new file mode 100644
index 000000000..cb32f94df
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Stream/AsynchronousMetricStream.php
@@ -0,0 +1,111 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Stream;
+
+use function array_search;
+use function count;
+use OpenTelemetry\SDK\Metrics\AggregationInterface;
+use OpenTelemetry\SDK\Metrics\Data\DataInterface;
+use OpenTelemetry\SDK\Metrics\Data\Exemplar;
+use OpenTelemetry\SDK\Metrics\Data\Temporality;
+
+/**
+ * @internal
+ */
+final class AsynchronousMetricStream implements MetricStreamInterface
+{
+ private AggregationInterface $aggregation;
+
+ private int $startTimestamp;
+ private Metric $metric;
+
+ /** @var array<int, Metric|null> */
+ private array $lastReads = [];
+
+ public function __construct(AggregationInterface $aggregation, int $startTimestamp)
+ {
+ $this->aggregation = $aggregation;
+ $this->startTimestamp = $startTimestamp;
+ $this->metric = new Metric([], [], $startTimestamp);
+ }
+
+ public function temporality()
+ {
+ return Temporality::CUMULATIVE;
+ }
+
+ public function timestamp(): int
+ {
+ return $this->metric->timestamp;
+ }
+
+ public function push(Metric $metric): void
+ {
+ $this->metric = $metric;
+ }
+
+ public function register($temporality): int
+ {
+ if ($temporality === Temporality::CUMULATIVE) {
+ return -1;
+ }
+
+ if (($reader = array_search(null, $this->lastReads, true)) === false) {
+ $reader = count($this->lastReads);
+ }
+
+ $this->lastReads[$reader] = $this->metric;
+
+ return $reader;
+ }
+
+ public function unregister(int $reader): void
+ {
+ if (!isset($this->lastReads[$reader])) {
+ return;
+ }
+
+ $this->lastReads[$reader] = null;
+ }
+
+ public function collect(int $reader): DataInterface
+ {
+ $metric = $this->metric;
+
+ if (($lastRead = $this->lastReads[$reader] ?? null) === null) {
+ $temporality = Temporality::CUMULATIVE;
+ $startTimestamp = $this->startTimestamp;
+ } else {
+ $temporality = Temporality::DELTA;
+ $startTimestamp = $lastRead->timestamp;
+
+ $this->lastReads[$reader] = $metric;
+ $metric = $this->diff($lastRead, $metric);
+ }
+
+ return $this->aggregation->toData(
+ $metric->attributes,
+ $metric->summaries,
+ Exemplar::groupByIndex($metric->exemplars),
+ $startTimestamp,
+ $metric->timestamp,
+ $temporality,
+ );
+ }
+
+ private function diff(Metric $lastRead, Metric $metric): Metric
+ {
+ $diff = clone $metric;
+ foreach ($metric->summaries as $k => $summary) {
+ if (!isset($lastRead->summaries[$k])) {
+ continue;
+ }
+
+ $diff->summaries[$k] = $this->aggregation->diff($lastRead->summaries[$k], $summary);
+ }
+
+ return $diff;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Stream/Delta.php b/vendor/open-telemetry/sdk/Metrics/Stream/Delta.php
new file mode 100644
index 000000000..a4ff56d71
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Stream/Delta.php
@@ -0,0 +1,33 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Stream;
+
+use GMP;
+
+/**
+ * @internal
+ */
+final class Delta
+{
+ public Metric $metric;
+ /**
+ * @psalm-suppress UndefinedDocblockClass
+ * @phan-suppress PhanUndeclaredTypeProperty
+ * @var int|GMP
+ */
+ public $readers;
+ public ?self $prev;
+ /**
+ * @psalm-suppress UndefinedDocblockClass
+ * @phan-suppress PhanUndeclaredTypeParameter
+ * @param int|GMP $readers
+ */
+ public function __construct(Metric $metric, $readers, ?self $prev = null)
+ {
+ $this->metric = $metric;
+ $this->readers = $readers;
+ $this->prev = $prev;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Stream/DeltaStorage.php b/vendor/open-telemetry/sdk/Metrics/Stream/DeltaStorage.php
new file mode 100644
index 000000000..b46a28d65
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Stream/DeltaStorage.php
@@ -0,0 +1,110 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Stream;
+
+use function assert;
+use GMP;
+use OpenTelemetry\SDK\Metrics\AggregationInterface;
+
+/**
+ * @internal
+ */
+final class DeltaStorage
+{
+ private AggregationInterface $aggregation;
+ private Delta $head;
+
+ public function __construct(AggregationInterface $aggregation)
+ {
+ $this->aggregation = $aggregation;
+ $this->head = new Delta(new Metric([], [], 0), 0);
+
+ /** @phan-suppress-next-line PhanTypeObjectUnsetDeclaredProperty */
+ unset($this->head->metric);
+ }
+
+ /**
+ * @psalm-suppress UndefinedDocblockClass
+ * @phan-suppress PhanUndeclaredTypeParameter
+ * @param int|GMP $readers
+ */
+ public function add(Metric $metric, $readers): void
+ {
+ /** @phpstan-ignore-next-line */
+ if ($readers == 0) {
+ return;
+ }
+
+ if (($this->head->prev->readers ?? null) != $readers) {
+ $this->head->prev = new Delta($metric, $readers, $this->head->prev);
+ } else {
+ assert($this->head->prev !== null);
+ $this->mergeInto($this->head->prev->metric, $metric);
+ }
+ }
+
+ public function collect(int $reader, bool $retain = false): ?Metric
+ {
+ $n = null;
+ for ($d = $this->head; $d->prev; $d = $d->prev) {
+ if (($d->prev->readers >> $reader & 1) != 0) {
+ if ($n !== null) {
+ assert($n->prev !== null);
+ $n->prev->readers ^= $d->prev->readers;
+ $this->mergeInto($d->prev->metric, $n->prev->metric);
+ $this->tryUnlink($n);
+
+ if ($n->prev === $d->prev) {
+ continue;
+ }
+ }
+
+ $n = $d;
+ }
+ }
+
+ $metric = $n->prev->metric ?? null;
+
+ if (!$retain && $n) {
+ assert($n->prev !== null);
+ $n->prev->readers ^= ($n->prev->readers & 1 | 1) << $reader;
+ $this->tryUnlink($n);
+ }
+
+ return $metric;
+ }
+
+ private function tryUnlink(Delta $n): void
+ {
+ assert($n->prev !== null);
+ /** @phpstan-ignore-next-line */
+ if ($n->prev->readers == 0) {
+ $n->prev = $n->prev->prev;
+
+ return;
+ }
+
+ for ($c = $n->prev->prev;
+ $c && ($n->prev->readers & $c->readers) == 0;
+ $c = $c->prev) {
+ }
+
+ if ($c && $n->prev->readers === $c->readers) {
+ $this->mergeInto($c->metric, $n->prev->metric);
+ $n->prev = $n->prev->prev;
+ }
+ }
+
+ private function mergeInto(Metric $into, Metric $metric): void
+ {
+ foreach ($metric->summaries as $k => $summary) {
+ $into->attributes[$k] ??= $metric->attributes[$k];
+ $into->summaries[$k] = isset($into->summaries[$k])
+ ? $this->aggregation->merge($into->summaries[$k], $summary)
+ : $summary;
+ }
+ $into->exemplars += $metric->exemplars;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Stream/Metric.php b/vendor/open-telemetry/sdk/Metrics/Stream/Metric.php
new file mode 100644
index 000000000..6b1db9eef
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Stream/Metric.php
@@ -0,0 +1,44 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Stream;
+
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Metrics\Data\Exemplar;
+
+/**
+ * @internal
+ *
+ * @template T
+ */
+final class Metric
+{
+
+ /**
+ * @var array<AttributesInterface>
+ */
+ public array $attributes;
+ /**
+ * @var array<T>
+ */
+ public array $summaries;
+ public int $timestamp;
+ /**
+ * @var array<Exemplar>
+ */
+ public array $exemplars;
+
+ /**
+ * @param array<AttributesInterface> $attributes
+ * @param array<T> $summaries
+ * @param array<Exemplar> $exemplars
+ */
+ public function __construct(array $attributes, array $summaries, int $timestamp, array $exemplars = [])
+ {
+ $this->attributes = $attributes;
+ $this->summaries = $summaries;
+ $this->timestamp = $timestamp;
+ $this->exemplars = $exemplars;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregator.php b/vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregator.php
new file mode 100644
index 000000000..b1328eb07
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregator.php
@@ -0,0 +1,73 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Stream;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Metrics\AggregationInterface;
+use OpenTelemetry\SDK\Metrics\AttributeProcessorInterface;
+use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarReservoirInterface;
+use function serialize;
+
+/**
+ * @internal
+ */
+final class MetricAggregator implements MetricAggregatorInterface
+{
+ private ?AttributeProcessorInterface $attributeProcessor;
+ private AggregationInterface $aggregation;
+ private ?ExemplarReservoirInterface $exemplarReservoir;
+
+ /** @var array<AttributesInterface> */
+ private array $attributes = [];
+ private array $summaries = [];
+
+ public function __construct(
+ ?AttributeProcessorInterface $attributeProcessor,
+ AggregationInterface $aggregation,
+ ?ExemplarReservoirInterface $exemplarReservoir = null
+ ) {
+ $this->attributeProcessor = $attributeProcessor;
+ $this->aggregation = $aggregation;
+ $this->exemplarReservoir = $exemplarReservoir;
+ }
+
+ /**
+ * @param float|int $value
+ */
+ public function record($value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): void
+ {
+ $filteredAttributes = $this->attributeProcessor !== null
+ ? $this->attributeProcessor->process($attributes, $context)
+ : $attributes;
+ $raw = $filteredAttributes->toArray();
+ $index = $raw !== [] ? serialize($raw) : 0;
+ $this->attributes[$index] ??= $filteredAttributes;
+ $this->aggregation->record(
+ $this->summaries[$index] ??= $this->aggregation->initialize(),
+ $value,
+ $attributes,
+ $context,
+ $timestamp,
+ );
+
+ if ($this->exemplarReservoir !== null) {
+ $this->exemplarReservoir->offer($index, $value, $attributes, $context, $timestamp);
+ }
+ }
+
+ public function collect(int $timestamp): Metric
+ {
+ $exemplars = $this->exemplarReservoir
+ ? $this->exemplarReservoir->collect($this->attributes)
+ : [];
+ $metric = new Metric($this->attributes, $this->summaries, $timestamp, $exemplars);
+
+ $this->attributes = [];
+ $this->summaries = [];
+
+ return $metric;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregatorFactory.php b/vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregatorFactory.php
new file mode 100644
index 000000000..5866a72b7
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregatorFactory.php
@@ -0,0 +1,28 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Stream;
+
+use OpenTelemetry\SDK\Metrics\AggregationInterface;
+use OpenTelemetry\SDK\Metrics\AttributeProcessorInterface;
+
+/**
+ * @internal
+ */
+final class MetricAggregatorFactory implements MetricAggregatorFactoryInterface
+{
+ private ?AttributeProcessorInterface $attributeProcessor;
+ private AggregationInterface $aggregation;
+
+ public function __construct(?AttributeProcessorInterface $attributeProcessor, AggregationInterface $aggregation)
+ {
+ $this->attributeProcessor = $attributeProcessor;
+ $this->aggregation = $aggregation;
+ }
+
+ public function create(): MetricAggregatorInterface
+ {
+ return new MetricAggregator($this->attributeProcessor, $this->aggregation);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregatorFactoryInterface.php b/vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregatorFactoryInterface.php
new file mode 100644
index 000000000..356f682f2
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregatorFactoryInterface.php
@@ -0,0 +1,13 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Stream;
+
+/**
+ * @internal
+ */
+interface MetricAggregatorFactoryInterface
+{
+ public function create(): MetricAggregatorInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregatorInterface.php b/vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregatorInterface.php
new file mode 100644
index 000000000..2f5cfbf15
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregatorInterface.php
@@ -0,0 +1,12 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Stream;
+
+/**
+ * @internal
+ */
+interface MetricAggregatorInterface extends WritableMetricStreamInterface, MetricCollectorInterface
+{
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Stream/MetricCollectorInterface.php b/vendor/open-telemetry/sdk/Metrics/Stream/MetricCollectorInterface.php
new file mode 100644
index 000000000..51a728df7
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Stream/MetricCollectorInterface.php
@@ -0,0 +1,13 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Stream;
+
+/**
+ * @internal
+ */
+interface MetricCollectorInterface
+{
+ public function collect(int $timestamp): Metric;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Stream/MetricStreamInterface.php b/vendor/open-telemetry/sdk/Metrics/Stream/MetricStreamInterface.php
new file mode 100644
index 000000000..1373a1c93
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Stream/MetricStreamInterface.php
@@ -0,0 +1,58 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Stream;
+
+use OpenTelemetry\SDK\Metrics\Data\DataInterface;
+use OpenTelemetry\SDK\Metrics\Data\Temporality;
+
+/**
+ * @internal
+ */
+interface MetricStreamInterface
+{
+ /**
+ * Returns the internal temporality of this stream.
+ *
+ * @return string|Temporality internal temporality
+ */
+ public function temporality();
+
+ /**
+ * Returns the last metric timestamp.
+ *
+ * @return int metric timestamp
+ */
+ public function timestamp(): int;
+
+ /**
+ * Pushes metric data to the stream.
+ *
+ * @param Metric $metric metric data to push
+ */
+ public function push(Metric $metric): void;
+
+ /**
+ * Registers a new reader with the given temporality.
+ *
+ * @param string|Temporality $temporality temporality to use
+ * @return int reader id
+ */
+ public function register($temporality): int;
+
+ /**
+ * Unregisters the given reader.
+ *
+ * @param int $reader reader id
+ */
+ public function unregister(int $reader): void;
+
+ /**
+ * Collects metric data for the given reader.
+ *
+ * @param int $reader reader id
+ * @return DataInterface metric data
+ */
+ public function collect(int $reader): DataInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Stream/SynchronousMetricStream.php b/vendor/open-telemetry/sdk/Metrics/Stream/SynchronousMetricStream.php
new file mode 100644
index 000000000..52645504c
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Stream/SynchronousMetricStream.php
@@ -0,0 +1,126 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Stream;
+
+use function assert;
+use const E_USER_WARNING;
+use function extension_loaded;
+use GMP;
+use function gmp_init;
+use function is_int;
+use OpenTelemetry\SDK\Metrics\AggregationInterface;
+use OpenTelemetry\SDK\Metrics\Data\DataInterface;
+use OpenTelemetry\SDK\Metrics\Data\Exemplar;
+use OpenTelemetry\SDK\Metrics\Data\Temporality;
+use const PHP_INT_SIZE;
+use function sprintf;
+use function trigger_error;
+
+/**
+ * @internal
+ */
+final class SynchronousMetricStream implements MetricStreamInterface
+{
+ private AggregationInterface $aggregation;
+
+ private int $timestamp;
+
+ private DeltaStorage $delta;
+ /**
+ * @psalm-suppress UndefinedDocblockClass
+ * @phan-suppress PhanUndeclaredTypeProperty
+ * @var int|GMP
+ */
+ private $readers = 0;
+ /**
+ * @psalm-suppress UndefinedDocblockClass
+ * @phan-suppress PhanUndeclaredTypeProperty
+ * @var int|GMP
+ */
+ private $cumulative = 0;
+
+ public function __construct(AggregationInterface $aggregation, int $startTimestamp)
+ {
+ $this->aggregation = $aggregation;
+ $this->timestamp = $startTimestamp;
+ $this->delta = new DeltaStorage($aggregation);
+ }
+
+ public function temporality()
+ {
+ return Temporality::DELTA;
+ }
+
+ public function timestamp(): int
+ {
+ return $this->timestamp;
+ }
+
+ public function push(Metric $metric): void
+ {
+ [$this->timestamp, $metric->timestamp] = [$metric->timestamp, $this->timestamp];
+ $this->delta->add($metric, $this->readers);
+ }
+
+ public function register($temporality): int
+ {
+ $reader = 0;
+ for ($r = $this->readers; ($r & 1) != 0; $r >>= 1, $reader++) {
+ }
+
+ if ($reader === (PHP_INT_SIZE << 3) - 1 && is_int($this->readers)) {
+ if (!extension_loaded('gmp')) {
+ trigger_error(sprintf('GMP extension required to register over %d readers', (PHP_INT_SIZE << 3) - 1), E_USER_WARNING);
+ $reader = PHP_INT_SIZE << 3;
+ } else {
+ assert(is_int($this->cumulative));
+ $this->readers = gmp_init($this->readers);
+ $this->cumulative = gmp_init($this->cumulative);
+ }
+ }
+
+ $readerMask = ($this->readers & 1 | 1) << $reader;
+ $this->readers ^= $readerMask;
+ if ($temporality === Temporality::CUMULATIVE) {
+ $this->cumulative ^= $readerMask;
+ }
+
+ return $reader;
+ }
+
+ public function unregister(int $reader): void
+ {
+ $readerMask = ($this->readers & 1 | 1) << $reader;
+ if (($this->readers & $readerMask) == 0) {
+ return;
+ }
+
+ $this->delta->collect($reader);
+
+ $this->readers ^= $readerMask;
+ if (($this->cumulative & $readerMask) != 0) {
+ $this->cumulative ^= $readerMask;
+ }
+ }
+
+ public function collect(int $reader): DataInterface
+ {
+ $cumulative = ($this->cumulative >> $reader & 1) != 0;
+ $metric = $this->delta->collect($reader, $cumulative) ?? new Metric([], [], $this->timestamp);
+
+ $temporality = $cumulative
+ ? Temporality::CUMULATIVE
+ : Temporality::DELTA;
+
+ return $this->aggregation->toData(
+ $metric->attributes,
+ $metric->summaries,
+ Exemplar::groupByIndex($metric->exemplars),
+ $metric->timestamp,
+ $this->timestamp,
+ $temporality,
+ );
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Stream/WritableMetricStreamInterface.php b/vendor/open-telemetry/sdk/Metrics/Stream/WritableMetricStreamInterface.php
new file mode 100644
index 000000000..9fd425a44
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Stream/WritableMetricStreamInterface.php
@@ -0,0 +1,19 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Stream;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+/**
+ * @internal
+ */
+interface WritableMetricStreamInterface
+{
+ /**
+ * @param float|int $value
+ */
+ public function record($value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): void;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/UpDownCounter.php b/vendor/open-telemetry/sdk/Metrics/UpDownCounter.php
new file mode 100644
index 000000000..1adf67f8a
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/UpDownCounter.php
@@ -0,0 +1,37 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\API\Metrics\UpDownCounterInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricWriterInterface;
+
+/**
+ * @internal
+ */
+final class UpDownCounter implements UpDownCounterInterface
+{
+ private MetricWriterInterface $writer;
+ private Instrument $instrument;
+ private ReferenceCounterInterface $referenceCounter;
+
+ public function __construct(MetricWriterInterface $writer, Instrument $instrument, ReferenceCounterInterface $referenceCounter)
+ {
+ $this->writer = $writer;
+ $this->instrument = $instrument;
+ $this->referenceCounter = $referenceCounter;
+
+ $this->referenceCounter->acquire();
+ }
+
+ public function __destruct()
+ {
+ $this->referenceCounter->release();
+ }
+
+ public function add($amount, iterable $attributes = [], $context = null): void
+ {
+ $this->writer->record($this->instrument, $amount, $attributes, $context);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/View/CriteriaViewRegistry.php b/vendor/open-telemetry/sdk/Metrics/View/CriteriaViewRegistry.php
new file mode 100644
index 000000000..f387abf9c
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/View/CriteriaViewRegistry.php
@@ -0,0 +1,40 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\View;
+
+use Generator;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Metrics\Instrument;
+use OpenTelemetry\SDK\Metrics\ViewRegistryInterface;
+
+final class CriteriaViewRegistry implements ViewRegistryInterface
+{
+ /** @var list<SelectionCriteriaInterface> */
+ private array $criteria = [];
+ /** @var list<ViewTemplate> */
+ private array $views = [];
+
+ public function register(SelectionCriteriaInterface $criteria, ViewTemplate $view): void
+ {
+ $this->criteria[] = $criteria;
+ $this->views[] = $view;
+ }
+
+ public function find(Instrument $instrument, InstrumentationScopeInterface $instrumentationScope): ?iterable
+ {
+ $views = $this->generateViews($instrument, $instrumentationScope);
+
+ return $views->valid() ? $views : null;
+ }
+
+ private function generateViews(Instrument $instrument, InstrumentationScopeInterface $instrumentationScope): Generator
+ {
+ foreach ($this->criteria as $i => $criteria) {
+ if ($criteria->accepts($instrument, $instrumentationScope)) {
+ yield $this->views[$i]->project($instrument);
+ }
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/AllCriteria.php b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/AllCriteria.php
new file mode 100644
index 000000000..438297324
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/AllCriteria.php
@@ -0,0 +1,33 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\View\SelectionCriteria;
+
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Metrics\Instrument;
+use OpenTelemetry\SDK\Metrics\View\SelectionCriteriaInterface;
+
+final class AllCriteria implements SelectionCriteriaInterface
+{
+ private iterable $criteria;
+
+ /**
+ * @param iterable<SelectionCriteriaInterface> $criteria
+ */
+ public function __construct(iterable $criteria)
+ {
+ $this->criteria = $criteria;
+ }
+
+ public function accepts(Instrument $instrument, InstrumentationScopeInterface $instrumentationScope): bool
+ {
+ foreach ($this->criteria as $criterion) {
+ if (!$criterion->accepts($instrument, $instrumentationScope)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentNameCriteria.php b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentNameCriteria.php
new file mode 100644
index 000000000..ed6034755
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentNameCriteria.php
@@ -0,0 +1,28 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\View\SelectionCriteria;
+
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Metrics\Instrument;
+use OpenTelemetry\SDK\Metrics\View\SelectionCriteriaInterface;
+use function preg_match;
+use function preg_quote;
+use function sprintf;
+use function strtr;
+
+final class InstrumentNameCriteria implements SelectionCriteriaInterface
+{
+ private string $pattern;
+
+ public function __construct(string $name)
+ {
+ $this->pattern = sprintf('/^%s$/', strtr(preg_quote($name, '/'), ['\\?' => '.', '\\*' => '.*']));
+ }
+
+ public function accepts(Instrument $instrument, InstrumentationScopeInterface $instrumentationScope): bool
+ {
+ return (bool) preg_match($this->pattern, $instrument->name);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentTypeCriteria.php b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentTypeCriteria.php
new file mode 100644
index 000000000..46a88def0
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentTypeCriteria.php
@@ -0,0 +1,29 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\View\SelectionCriteria;
+
+use function in_array;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Metrics\Instrument;
+use OpenTelemetry\SDK\Metrics\InstrumentType;
+use OpenTelemetry\SDK\Metrics\View\SelectionCriteriaInterface;
+
+final class InstrumentTypeCriteria implements SelectionCriteriaInterface
+{
+ private array $instrumentTypes;
+
+ /**
+ * @param string|InstrumentType|string[]|InstrumentType[] $instrumentType
+ */
+ public function __construct($instrumentType)
+ {
+ $this->instrumentTypes = (array) $instrumentType;
+ }
+
+ public function accepts(Instrument $instrument, InstrumentationScopeInterface $instrumentationScope): bool
+ {
+ return in_array($instrument->type, $this->instrumentTypes, true);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentationScopeNameCriteria.php b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentationScopeNameCriteria.php
new file mode 100644
index 000000000..201d1a7b2
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentationScopeNameCriteria.php
@@ -0,0 +1,24 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\View\SelectionCriteria;
+
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Metrics\Instrument;
+use OpenTelemetry\SDK\Metrics\View\SelectionCriteriaInterface;
+
+final class InstrumentationScopeNameCriteria implements SelectionCriteriaInterface
+{
+ private string $name;
+
+ public function __construct(string $name)
+ {
+ $this->name = $name;
+ }
+
+ public function accepts(Instrument $instrument, InstrumentationScopeInterface $instrumentationScope): bool
+ {
+ return $this->name === $instrumentationScope->getName();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentationScopeSchemaUrlCriteria.php b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentationScopeSchemaUrlCriteria.php
new file mode 100644
index 000000000..a11a1d589
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentationScopeSchemaUrlCriteria.php
@@ -0,0 +1,24 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\View\SelectionCriteria;
+
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Metrics\Instrument;
+use OpenTelemetry\SDK\Metrics\View\SelectionCriteriaInterface;
+
+final class InstrumentationScopeSchemaUrlCriteria implements SelectionCriteriaInterface
+{
+ private ?string $schemaUrl;
+
+ public function __construct(?string $schemaUrl)
+ {
+ $this->schemaUrl = $schemaUrl;
+ }
+
+ public function accepts(Instrument $instrument, InstrumentationScopeInterface $instrumentationScope): bool
+ {
+ return $this->schemaUrl === $instrumentationScope->getSchemaUrl();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentationScopeVersionCriteria.php b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentationScopeVersionCriteria.php
new file mode 100644
index 000000000..37d180f99
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentationScopeVersionCriteria.php
@@ -0,0 +1,24 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\View\SelectionCriteria;
+
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Metrics\Instrument;
+use OpenTelemetry\SDK\Metrics\View\SelectionCriteriaInterface;
+
+final class InstrumentationScopeVersionCriteria implements SelectionCriteriaInterface
+{
+ private ?string $version;
+
+ public function __construct(?string $version)
+ {
+ $this->version = $version;
+ }
+
+ public function accepts(Instrument $instrument, InstrumentationScopeInterface $instrumentationScope): bool
+ {
+ return $this->version === $instrumentationScope->getVersion();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteriaInterface.php b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteriaInterface.php
new file mode 100644
index 000000000..8abd6fa69
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteriaInterface.php
@@ -0,0 +1,13 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\View;
+
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Metrics\Instrument;
+
+interface SelectionCriteriaInterface
+{
+ public function accepts(Instrument $instrument, InstrumentationScopeInterface $instrumentationScope): bool;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/View/ViewTemplate.php b/vendor/open-telemetry/sdk/Metrics/View/ViewTemplate.php
new file mode 100644
index 000000000..302ed83ae
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/View/ViewTemplate.php
@@ -0,0 +1,77 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\View;
+
+use OpenTelemetry\SDK\Metrics\AggregationInterface;
+use OpenTelemetry\SDK\Metrics\Instrument;
+use OpenTelemetry\SDK\Metrics\ViewProjection;
+
+final class ViewTemplate
+{
+ private ?string $name = null;
+ private ?string $description = null;
+ /**
+ * @var list<string>
+ */
+ private ?array $attributeKeys = null;
+ private ?AggregationInterface $aggregation = null;
+
+ private function __construct()
+ {
+ }
+
+ public static function create(): self
+ {
+ static $instance;
+
+ return $instance ??= new self();
+ }
+
+ public function withName(string $name): self
+ {
+ $self = clone $this;
+ $self->name = $name;
+
+ return $self;
+ }
+
+ public function withDescription(string $description): self
+ {
+ $self = clone $this;
+ $self->description = $description;
+
+ return $self;
+ }
+
+ /**
+ * @param list<string> $attributeKeys
+ */
+ public function withAttributeKeys(array $attributeKeys): self
+ {
+ $self = clone $this;
+ $self->attributeKeys = $attributeKeys;
+
+ return $self;
+ }
+
+ public function withAggregation(?AggregationInterface $aggregation): self
+ {
+ $self = clone $this;
+ $self->aggregation = $aggregation;
+
+ return $self;
+ }
+
+ public function project(Instrument $instrument): ViewProjection
+ {
+ return new ViewProjection(
+ $this->name ?? $instrument->name,
+ $instrument->unit,
+ $this->description ?? $instrument->description,
+ $this->attributeKeys,
+ $this->aggregation,
+ );
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/ViewProjection.php b/vendor/open-telemetry/sdk/Metrics/ViewProjection.php
new file mode 100644
index 000000000..046bd6bb1
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/ViewProjection.php
@@ -0,0 +1,47 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+final class ViewProjection
+{
+ /**
+ * @readonly
+ */
+ public string $name;
+ /**
+ * @readonly
+ */
+ public ?string $unit;
+ /**
+ * @readonly
+ */
+ public ?string $description;
+ /**
+ * @readonly
+ * @var list<string>|null
+ */
+ public ?array $attributeKeys;
+ /**
+ * @readonly
+ */
+ public ?AggregationInterface $aggregation;
+
+ /**
+ * @param list<string>|null $attributeKeys
+ */
+ public function __construct(
+ string $name,
+ ?string $unit,
+ ?string $description,
+ ?array $attributeKeys,
+ ?AggregationInterface $aggregation
+ ) {
+ $this->name = $name;
+ $this->unit = $unit;
+ $this->description = $description;
+ $this->attributeKeys = $attributeKeys;
+ $this->aggregation = $aggregation;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/ViewRegistryInterface.php b/vendor/open-telemetry/sdk/Metrics/ViewRegistryInterface.php
new file mode 100644
index 000000000..19d8f9ffd
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/ViewRegistryInterface.php
@@ -0,0 +1,15 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+
+interface ViewRegistryInterface
+{
+ /**
+ * @return iterable<ViewProjection>|null
+ */
+ public function find(Instrument $instrument, InstrumentationScopeInterface $instrumentationScope): ?iterable;
+}