summaryrefslogtreecommitdiff
path: root/vendor/open-telemetry/sdk/Metrics/Stream/SynchronousMetricStream.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/open-telemetry/sdk/Metrics/Stream/SynchronousMetricStream.php')
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Stream/SynchronousMetricStream.php126
1 files changed, 126 insertions, 0 deletions
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,
+ );
+ }
+}