summaryrefslogtreecommitdiff
path: root/vendor/open-telemetry/sdk/Trace
diff options
context:
space:
mode:
authorAndrew Dolgov <[email protected]>2023-10-20 17:12:29 +0300
committerAndrew Dolgov <[email protected]>2023-10-20 21:13:39 +0300
commitcdd7ad020e165fe680703b6d3319b908b682fb7a (patch)
treeb51eb09b7b4587e8fbc5624ac8d88d28cfcd0b04 /vendor/open-telemetry/sdk/Trace
parent45a9ff0c88cbd33892ff16ab837e9059937d656e (diff)
jaeger-client -> opentelemetry
Diffstat (limited to 'vendor/open-telemetry/sdk/Trace')
-rw-r--r--vendor/open-telemetry/sdk/Trace/Behavior/LoggerAwareTrait.php48
-rw-r--r--vendor/open-telemetry/sdk/Trace/Behavior/SpanExporterDecoratorTrait.php47
-rw-r--r--vendor/open-telemetry/sdk/Trace/Behavior/SpanExporterTrait.php47
-rw-r--r--vendor/open-telemetry/sdk/Trace/Behavior/UsesSpanConverterTrait.php41
-rw-r--r--vendor/open-telemetry/sdk/Trace/Event.php47
-rw-r--r--vendor/open-telemetry/sdk/Trace/EventInterface.php15
-rw-r--r--vendor/open-telemetry/sdk/Trace/ExporterFactory.php32
-rw-r--r--vendor/open-telemetry/sdk/Trace/IdGeneratorInterface.php12
-rw-r--r--vendor/open-telemetry/sdk/Trace/ImmutableSpan.php153
-rw-r--r--vendor/open-telemetry/sdk/Trace/Link.php30
-rw-r--r--vendor/open-telemetry/sdk/Trace/LinkInterface.php14
-rw-r--r--vendor/open-telemetry/sdk/Trace/NoopTracerProvider.php21
-rw-r--r--vendor/open-telemetry/sdk/Trace/RandomIdGenerator.php49
-rw-r--r--vendor/open-telemetry/sdk/Trace/ReadWriteSpanInterface.php11
-rw-r--r--vendor/open-telemetry/sdk/Trace/ReadableSpanInterface.php48
-rw-r--r--vendor/open-telemetry/sdk/Trace/Sampler/AlwaysOffSampler.php50
-rw-r--r--vendor/open-telemetry/sdk/Trace/Sampler/AlwaysOnSampler.php50
-rw-r--r--vendor/open-telemetry/sdk/Trace/Sampler/ParentBased.php100
-rw-r--r--vendor/open-telemetry/sdk/Trace/Sampler/TraceIdRatioBasedSampler.php70
-rw-r--r--vendor/open-telemetry/sdk/Trace/SamplerFactory.php48
-rw-r--r--vendor/open-telemetry/sdk/Trace/SamplerInterface.php46
-rw-r--r--vendor/open-telemetry/sdk/Trace/SamplingResult.php71
-rw-r--r--vendor/open-telemetry/sdk/Trace/Span.php359
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanBuilder.php191
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanConverterInterface.php10
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanDataInterface.php46
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanExporter/AbstractDecorator.php12
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanExporter/ConsoleSpanExporter.php57
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanExporter/ConsoleSpanExporterFactory.php18
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanExporter/FriendlySpanConverter.php173
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanExporter/InMemoryExporter.php40
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanExporter/InMemorySpanExporterFactory.php15
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanExporter/LoggerDecorator.php58
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanExporter/LoggerExporter.php96
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanExporter/NullSpanConverter.php15
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanExporter/SpanExporterFactoryInterface.php12
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanExporter/_register.php7
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanExporterInterface.php29
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanLimits.php67
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanLimitsBuilder.php148
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanProcessor/BatchSpanProcessor.php290
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanProcessor/BatchSpanProcessorBuilder.php41
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanProcessor/MultiSpanProcessor.php79
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanProcessor/NoopSpanProcessor.php47
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanProcessor/SimpleSpanProcessor.php120
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanProcessorFactory.php48
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanProcessorInterface.php38
-rw-r--r--vendor/open-telemetry/sdk/Trace/StatusData.php84
-rw-r--r--vendor/open-telemetry/sdk/Trace/StatusDataInterface.php18
-rw-r--r--vendor/open-telemetry/sdk/Trace/Tracer.php52
-rw-r--r--vendor/open-telemetry/sdk/Trace/TracerProvider.php99
-rw-r--r--vendor/open-telemetry/sdk/Trace/TracerProviderBuilder.php45
-rw-r--r--vendor/open-telemetry/sdk/Trace/TracerProviderFactory.php60
-rw-r--r--vendor/open-telemetry/sdk/Trace/TracerProviderInterface.php15
-rw-r--r--vendor/open-telemetry/sdk/Trace/TracerSharedState.php100
55 files changed, 3539 insertions, 0 deletions
diff --git a/vendor/open-telemetry/sdk/Trace/Behavior/LoggerAwareTrait.php b/vendor/open-telemetry/sdk/Trace/Behavior/LoggerAwareTrait.php
new file mode 100644
index 000000000..24f5e56a8
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/Behavior/LoggerAwareTrait.php
@@ -0,0 +1,48 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\Behavior;
+
+use Psr\Log\LoggerAwareTrait as PsrTrait;
+use Psr\Log\LoggerInterface;
+use Psr\Log\LogLevel;
+use Psr\Log\NullLogger;
+
+trait LoggerAwareTrait
+{
+ use PsrTrait;
+
+ private string $defaultLogLevel = LogLevel::INFO;
+
+ /**
+ * @param string $logLevel
+ */
+ public function setDefaultLogLevel(string $logLevel): void
+ {
+ $this->defaultLogLevel = $logLevel;
+ }
+
+ /**
+ * @param string $message
+ * @param array $context
+ * @param string|null $level
+ */
+ protected function log(string $message, array $context = [], ?string $level = null): void
+ {
+ $this->getLogger()->log(
+ $level ?? $this->defaultLogLevel,
+ $message,
+ $context
+ );
+ }
+
+ protected function getLogger(): LoggerInterface
+ {
+ if ($this->logger !== null) {
+ return $this->logger;
+ }
+
+ return new NullLogger();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/Behavior/SpanExporterDecoratorTrait.php b/vendor/open-telemetry/sdk/Trace/Behavior/SpanExporterDecoratorTrait.php
new file mode 100644
index 000000000..97839ec5b
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/Behavior/SpanExporterDecoratorTrait.php
@@ -0,0 +1,47 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\Behavior;
+
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Common\Future\FutureInterface;
+use OpenTelemetry\SDK\Trace\SpanDataInterface;
+use OpenTelemetry\SDK\Trace\SpanExporterInterface;
+
+trait SpanExporterDecoratorTrait
+{
+ protected SpanExporterInterface $decorated;
+
+ /**
+ * @param iterable<SpanDataInterface> $batch
+ * @return FutureInterface<bool>
+ */
+ public function export(iterable $batch, ?CancellationInterface $cancellation = null): FutureInterface
+ {
+ $batch = $this->beforeExport($batch);
+ $response = $this->decorated->export($batch, $cancellation);
+ $response->map(fn (bool $result) => $this->afterExport($batch, $result));
+
+ return $response;
+ }
+
+ abstract protected function beforeExport(iterable $spans): iterable;
+
+ abstract protected function afterExport(iterable $spans, bool $exportSuccess): void;
+
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ return $this->decorated->shutdown($cancellation);
+ }
+
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ return $this->decorated->forceFlush($cancellation);
+ }
+
+ public function setDecorated(SpanExporterInterface $decorated): void
+ {
+ $this->decorated = $decorated;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/Behavior/SpanExporterTrait.php b/vendor/open-telemetry/sdk/Trace/Behavior/SpanExporterTrait.php
new file mode 100644
index 000000000..339fecc1d
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/Behavior/SpanExporterTrait.php
@@ -0,0 +1,47 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\Behavior;
+
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Common\Future\CompletedFuture;
+use OpenTelemetry\SDK\Common\Future\FutureInterface;
+use OpenTelemetry\SDK\Trace\SpanDataInterface;
+
+trait SpanExporterTrait
+{
+ private bool $running = true;
+
+ /** @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/specification/trace/sdk.md#shutdown-2 */
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ $this->running = false;
+
+ return true;
+ }
+
+ /** @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/specification/trace/sdk.md#forceflush-2 */
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ return true;
+ }
+
+ /**
+ * @param iterable<SpanDataInterface> $batch
+ * @return FutureInterface<bool>
+ */
+ public function export(iterable $batch, ?CancellationInterface $cancellation = null): FutureInterface
+ {
+ if (!$this->running) {
+ return new CompletedFuture(false);
+ }
+
+ return new CompletedFuture($this->doExport($batch)); /** @phpstan-ignore-line */
+ }
+
+ /**
+ * @param iterable<SpanDataInterface> $spans Batch of spans to export
+ */
+ abstract protected function doExport(iterable $spans): bool; /** @phpstan-ignore-line */
+}
diff --git a/vendor/open-telemetry/sdk/Trace/Behavior/UsesSpanConverterTrait.php b/vendor/open-telemetry/sdk/Trace/Behavior/UsesSpanConverterTrait.php
new file mode 100644
index 000000000..4802cd15b
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/Behavior/UsesSpanConverterTrait.php
@@ -0,0 +1,41 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\Behavior;
+
+use OpenTelemetry\SDK\Trace\SpanConverterInterface;
+use OpenTelemetry\SDK\Trace\SpanDataInterface;
+use OpenTelemetry\SDK\Trace\SpanExporter\NullSpanConverter;
+
+trait UsesSpanConverterTrait
+{
+ private ?SpanConverterInterface $converter = null;
+
+ /**
+ * @param SpanConverterInterface $converter
+ */
+ protected function setSpanConverter(SpanConverterInterface $converter): void
+ {
+ $this->converter = $converter;
+ }
+
+ public function getSpanConverter(): SpanConverterInterface
+ {
+ if (null === $this->converter) {
+ $this->converter = new NullSpanConverter();
+ }
+
+ return $this->converter;
+ }
+
+ /**
+ * @param SpanDataInterface $span
+ * @return array
+ * @psalm-suppress PossiblyNullReference
+ */
+ protected function convertSpan(SpanDataInterface $span): array
+ {
+ return $this->getSpanConverter()->convert([$span]);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/Event.php b/vendor/open-telemetry/sdk/Trace/Event.php
new file mode 100644
index 000000000..28cb39bb1
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/Event.php
@@ -0,0 +1,47 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use function count;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+final class Event implements EventInterface
+{
+ private string $name;
+ private int $timestamp;
+ private AttributesInterface $attributes;
+
+ public function __construct(string $name, int $timestamp, AttributesInterface $attributes)
+ {
+ $this->name = $name;
+ $this->timestamp = $timestamp;
+ $this->attributes = $attributes;
+ }
+
+ public function getAttributes(): AttributesInterface
+ {
+ return $this->attributes;
+ }
+
+ public function getName(): string
+ {
+ return $this->name;
+ }
+
+ public function getEpochNanos(): int
+ {
+ return $this->timestamp;
+ }
+
+ public function getTotalAttributeCount(): int
+ {
+ return count($this->attributes);
+ }
+
+ public function getDroppedAttributesCount(): int
+ {
+ return $this->attributes->getDroppedAttributesCount();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/EventInterface.php b/vendor/open-telemetry/sdk/Trace/EventInterface.php
new file mode 100644
index 000000000..8b5ee2af6
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/EventInterface.php
@@ -0,0 +1,15 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+interface EventInterface
+{
+ public function getName(): string;
+ public function getAttributes(): AttributesInterface;
+ public function getEpochNanos(): int;
+ public function getTotalAttributeCount(): int;
+}
diff --git a/vendor/open-telemetry/sdk/Trace/ExporterFactory.php b/vendor/open-telemetry/sdk/Trace/ExporterFactory.php
new file mode 100644
index 000000000..9b652cc2f
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/ExporterFactory.php
@@ -0,0 +1,32 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use InvalidArgumentException;
+use OpenTelemetry\SDK\Common\Configuration\Configuration;
+use OpenTelemetry\SDK\Common\Configuration\Variables;
+use OpenTelemetry\SDK\Registry;
+use RuntimeException;
+
+class ExporterFactory
+{
+ /**
+ * @throws RuntimeException
+ */
+ public function create(): ?SpanExporterInterface
+ {
+ $exporters = Configuration::getList(Variables::OTEL_TRACES_EXPORTER);
+ if (1 !== count($exporters)) {
+ throw new InvalidArgumentException(sprintf('Configuration %s requires exactly 1 exporter', Variables::OTEL_TRACES_EXPORTER));
+ }
+ $exporter = $exporters[0];
+ if ($exporter === 'none') {
+ return null;
+ }
+ $factory = Registry::spanExporterFactory($exporter);
+
+ return $factory->create();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/IdGeneratorInterface.php b/vendor/open-telemetry/sdk/Trace/IdGeneratorInterface.php
new file mode 100644
index 000000000..ad622dccc
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/IdGeneratorInterface.php
@@ -0,0 +1,12 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+interface IdGeneratorInterface
+{
+ public function generateTraceId(): string;
+
+ public function generateSpanId(): string;
+}
diff --git a/vendor/open-telemetry/sdk/Trace/ImmutableSpan.php b/vendor/open-telemetry/sdk/Trace/ImmutableSpan.php
new file mode 100644
index 000000000..57836d4c3
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/ImmutableSpan.php
@@ -0,0 +1,153 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use function max;
+use OpenTelemetry\API\Trace as API;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+
+/**
+ * @psalm-immutable
+ */
+final class ImmutableSpan implements SpanDataInterface
+{
+ private Span $span;
+
+ /** @var non-empty-string */
+ private string $name;
+
+ /** @var list<EventInterface> */
+ private array $events;
+
+ /** @var list<LinkInterface> */
+ private array $links;
+
+ private AttributesInterface $attributes;
+ private int $totalRecordedEvents;
+ private StatusDataInterface $status;
+ private int $endEpochNanos;
+ private bool $hasEnded;
+
+ /**
+ * @param non-empty-string $name
+ * @param list<LinkInterface> $links
+ * @param list<EventInterface> $events
+ */
+ public function __construct(
+ Span $span,
+ string $name,
+ array $links,
+ array $events,
+ AttributesInterface $attributes,
+ int $totalRecordedEvents,
+ StatusDataInterface $status,
+ int $endEpochNanos,
+ bool $hasEnded
+ ) {
+ $this->span = $span;
+ $this->name = $name;
+ $this->links = $links;
+ $this->events = $events;
+ $this->attributes = $attributes;
+ $this->totalRecordedEvents = $totalRecordedEvents;
+ $this->status = $status;
+ $this->endEpochNanos = $endEpochNanos;
+ $this->hasEnded = $hasEnded;
+ }
+
+ public function getKind(): int
+ {
+ return $this->span->getKind();
+ }
+
+ public function getContext(): API\SpanContextInterface
+ {
+ return $this->span->getContext();
+ }
+
+ public function getParentContext(): API\SpanContextInterface
+ {
+ return $this->span->getParentContext();
+ }
+
+ public function getTraceId(): string
+ {
+ return $this->getContext()->getTraceId();
+ }
+
+ public function getSpanId(): string
+ {
+ return $this->getContext()->getSpanId();
+ }
+
+ public function getParentSpanId(): string
+ {
+ return $this->getParentContext()->getSpanId();
+ }
+
+ public function getStartEpochNanos(): int
+ {
+ return $this->span->getStartEpochNanos();
+ }
+
+ public function getEndEpochNanos(): int
+ {
+ return $this->endEpochNanos;
+ }
+
+ public function getInstrumentationScope(): InstrumentationScopeInterface
+ {
+ return $this->span->getInstrumentationScope();
+ }
+
+ public function getResource(): ResourceInfo
+ {
+ return $this->span->getResource();
+ }
+
+ public function getName(): string
+ {
+ return $this->name;
+ }
+
+ /** @inheritDoc */
+ public function getLinks(): array
+ {
+ return $this->links;
+ }
+
+ /** @inheritDoc */
+ public function getEvents(): array
+ {
+ return $this->events;
+ }
+
+ public function getAttributes(): AttributesInterface
+ {
+ return $this->attributes;
+ }
+
+ public function getTotalDroppedEvents(): int
+ {
+ return max(0, $this->totalRecordedEvents - count($this->events));
+ }
+
+ public function getTotalDroppedLinks(): int
+ {
+ return max(0, $this->span->getTotalRecordedLinks() - count($this->links));
+ }
+
+ public function getStatus(): StatusDataInterface
+ {
+ return $this->status;
+ }
+
+ public function hasEnded(): bool
+ {
+ return $this->hasEnded;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/Link.php b/vendor/open-telemetry/sdk/Trace/Link.php
new file mode 100644
index 000000000..9927839e7
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/Link.php
@@ -0,0 +1,30 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\API\Trace as API;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+final class Link implements LinkInterface
+{
+ private AttributesInterface $attributes;
+ private API\SpanContextInterface $context;
+
+ public function __construct(API\SpanContextInterface $context, AttributesInterface $attributes)
+ {
+ $this->context = $context;
+ $this->attributes = $attributes;
+ }
+
+ public function getSpanContext(): API\SpanContextInterface
+ {
+ return $this->context;
+ }
+
+ public function getAttributes(): AttributesInterface
+ {
+ return $this->attributes;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/LinkInterface.php b/vendor/open-telemetry/sdk/Trace/LinkInterface.php
new file mode 100644
index 000000000..8090fa1a5
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/LinkInterface.php
@@ -0,0 +1,14 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\API\Trace\SpanContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+interface LinkInterface
+{
+ public function getSpanContext(): SpanContextInterface;
+ public function getAttributes(): AttributesInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Trace/NoopTracerProvider.php b/vendor/open-telemetry/sdk/Trace/NoopTracerProvider.php
new file mode 100644
index 000000000..7cd4d4e7d
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/NoopTracerProvider.php
@@ -0,0 +1,21 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\API;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+
+class NoopTracerProvider extends API\Trace\NoopTracerProvider implements TracerProviderInterface
+{
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ return true;
+ }
+
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ return true;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/RandomIdGenerator.php b/vendor/open-telemetry/sdk/Trace/RandomIdGenerator.php
new file mode 100644
index 000000000..39767fb0f
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/RandomIdGenerator.php
@@ -0,0 +1,49 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\API\Trace\SpanContextValidator;
+use Throwable;
+
+class RandomIdGenerator implements IdGeneratorInterface
+{
+ private const TRACE_ID_HEX_LENGTH = 32;
+ private const SPAN_ID_HEX_LENGTH = 16;
+
+ public function generateTraceId(): string
+ {
+ do {
+ $traceId = $this->randomHex(self::TRACE_ID_HEX_LENGTH);
+ } while (!SpanContextValidator::isValidTraceId($traceId));
+
+ return $traceId;
+ }
+
+ public function generateSpanId(): string
+ {
+ do {
+ $spanId = $this->randomHex(self::SPAN_ID_HEX_LENGTH);
+ } while (!SpanContextValidator::isValidSpanId($spanId));
+
+ return $spanId;
+ }
+
+ /**
+ * @psalm-suppress ArgumentTypeCoercion $hexLength is always a positive integer
+ */
+ private function randomHex(int $hexLength): string
+ {
+ try {
+ return bin2hex(random_bytes(intdiv($hexLength, 2)));
+ } catch (Throwable $e) {
+ return $this->fallbackAlgorithm($hexLength);
+ }
+ }
+
+ private function fallbackAlgorithm(int $hexLength): string
+ {
+ return substr(str_shuffle(str_repeat('0123456789abcdef', $hexLength)), 1, $hexLength);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/ReadWriteSpanInterface.php b/vendor/open-telemetry/sdk/Trace/ReadWriteSpanInterface.php
new file mode 100644
index 000000000..60940ac01
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/ReadWriteSpanInterface.php
@@ -0,0 +1,11 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\API\Trace as API;
+
+interface ReadWriteSpanInterface extends API\SpanInterface, ReadableSpanInterface
+{
+}
diff --git a/vendor/open-telemetry/sdk/Trace/ReadableSpanInterface.php b/vendor/open-telemetry/sdk/Trace/ReadableSpanInterface.php
new file mode 100644
index 000000000..40704ab4e
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/ReadableSpanInterface.php
@@ -0,0 +1,48 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\API\Trace as API;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+
+/**
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.1/specification/trace/sdk.md#additional-span-interfaces
+ */
+interface ReadableSpanInterface
+{
+ public function getName(): string;
+
+ public function getContext(): API\SpanContextInterface;
+
+ public function getParentContext(): API\SpanContextInterface;
+
+ public function getInstrumentationScope(): InstrumentationScopeInterface;
+
+ public function hasEnded(): bool;
+
+ /**
+ * Returns an immutable representation of this instance.
+ */
+ public function toSpanData(): SpanDataInterface;
+
+ /**
+ * Returns the duration of the {@see API\SpanInterface} in nanoseconds.
+ * If still active, returns `now() - start`.
+ */
+ public function getDuration(): int;
+
+ /**
+ * @see API\SpanKind
+ */
+ public function getKind(): int;
+
+ /**
+ * Returns the value of the attribute with the provided *key*.
+ * Returns `null` if there are no attributes set, or no attribute with that key exists.
+ *
+ * @return mixed
+ */
+ public function getAttribute(string $key);
+}
diff --git a/vendor/open-telemetry/sdk/Trace/Sampler/AlwaysOffSampler.php b/vendor/open-telemetry/sdk/Trace/Sampler/AlwaysOffSampler.php
new file mode 100644
index 000000000..ee7e70a56
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/Sampler/AlwaysOffSampler.php
@@ -0,0 +1,50 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\Sampler;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Trace\SamplerInterface;
+use OpenTelemetry\SDK\Trace\SamplingResult;
+use OpenTelemetry\SDK\Trace\Span;
+
+/**
+ * This implementation of the SamplerInterface always skips record.
+ * Example:
+ * ```
+ * use OpenTelemetry\Sdk\Trace\AlwaysOffSampler;
+ * $sampler = new AlwaysOffSampler();
+ * ```
+ */
+class AlwaysOffSampler implements SamplerInterface
+{
+ /**
+ * Returns false because we never want to sample.
+ * {@inheritdoc}
+ */
+ public function shouldSample(
+ ContextInterface $parentContext,
+ string $traceId,
+ string $spanName,
+ int $spanKind,
+ AttributesInterface $attributes,
+ array $links
+ ): SamplingResult {
+ $parentSpan = Span::fromContext($parentContext);
+ $parentSpanContext = $parentSpan->getContext();
+ $traceState = $parentSpanContext->getTraceState();
+
+ return new SamplingResult(
+ SamplingResult::DROP,
+ [],
+ $traceState
+ );
+ }
+
+ public function getDescription(): string
+ {
+ return 'AlwaysOffSampler';
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/Sampler/AlwaysOnSampler.php b/vendor/open-telemetry/sdk/Trace/Sampler/AlwaysOnSampler.php
new file mode 100644
index 000000000..df61d1aee
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/Sampler/AlwaysOnSampler.php
@@ -0,0 +1,50 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\Sampler;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Trace\SamplerInterface;
+use OpenTelemetry\SDK\Trace\SamplingResult;
+use OpenTelemetry\SDK\Trace\Span;
+
+/**
+ * This implementation of the SamplerInterface always records.
+ * Example:
+ * ```
+ * use OpenTelemetry\Sdk\Trace\AlwaysOnSampler;
+ * $sampler = new AlwaysOnSampler();
+ * ```
+ */
+class AlwaysOnSampler implements SamplerInterface
+{
+ /**
+ * Returns true because we always want to sample.
+ * {@inheritdoc}
+ */
+ public function shouldSample(
+ ContextInterface $parentContext,
+ string $traceId,
+ string $spanName,
+ int $spanKind,
+ AttributesInterface $attributes,
+ array $links
+ ): SamplingResult {
+ $parentSpan = Span::fromContext($parentContext);
+ $parentSpanContext = $parentSpan->getContext();
+ $traceState = $parentSpanContext->getTraceState();
+
+ return new SamplingResult(
+ SamplingResult::RECORD_AND_SAMPLE,
+ [],
+ $traceState
+ );
+ }
+
+ public function getDescription(): string
+ {
+ return 'AlwaysOnSampler';
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/Sampler/ParentBased.php b/vendor/open-telemetry/sdk/Trace/Sampler/ParentBased.php
new file mode 100644
index 000000000..db801d3d8
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/Sampler/ParentBased.php
@@ -0,0 +1,100 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\Sampler;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Trace\SamplerInterface;
+use OpenTelemetry\SDK\Trace\SamplingResult;
+use OpenTelemetry\SDK\Trace\Span;
+
+/**
+ * Phan seems to struggle with the variadic arguments in the latest version
+ * @phan-file-suppress PhanParamTooFewUnpack
+ */
+
+/**
+ * This implementation of the SamplerInterface that respects parent context's sampling decision
+ * and delegates for the root span.
+ * Example:
+ * ```
+ * use OpenTelemetry\API\Trace\ParentBased;
+ * use OpenTelemetry\API\Trace\AlwaysOnSampler
+ *
+ * $rootSampler = new AlwaysOnSampler();
+ * $sampler = new ParentBased($rootSampler);
+ * ```
+ */
+class ParentBased implements SamplerInterface
+{
+ private SamplerInterface $root;
+
+ private SamplerInterface $remoteParentSampler;
+
+ private SamplerInterface $remoteParentNotSampler;
+
+ private SamplerInterface $localParentSampler;
+
+ private SamplerInterface $localParentNotSampler;
+
+ /**
+ * ParentBased sampler delegates the sampling decision based on the parent context.
+ *
+ * @param SamplerInterface $root Sampler called for the span with no parent (root span).
+ * @param SamplerInterface|null $remoteParentSampler Sampler called for the span with the remote sampled parent. When null, `AlwaysOnSampler` is used.
+ * @param SamplerInterface|null $remoteParentNotSampler Sampler called for the span with the remote not sampled parent. When null, `AlwaysOffSampler` is used.
+ * @param SamplerInterface|null $localParentSampler Sampler called for the span with local the sampled parent. When null, `AlwaysOnSampler` is used.
+ * @param SamplerInterface|null $localParentNotSampler Sampler called for the span with the local not sampled parent. When null, `AlwaysOffSampler` is used.
+ */
+ public function __construct(
+ SamplerInterface $root,
+ ?SamplerInterface $remoteParentSampler = null,
+ ?SamplerInterface $remoteParentNotSampler = null,
+ ?SamplerInterface $localParentSampler = null,
+ ?SamplerInterface $localParentNotSampler = null
+ ) {
+ $this->root = $root;
+ $this->remoteParentSampler = $remoteParentSampler ?? new AlwaysOnSampler();
+ $this->remoteParentNotSampler = $remoteParentNotSampler ?? new AlwaysOffSampler();
+ $this->localParentSampler = $localParentSampler ?? new AlwaysOnSampler();
+ $this->localParentNotSampler = $localParentNotSampler ?? new AlwaysOffSampler();
+ }
+
+ /**
+ * Invokes the respective delegate sampler when parent is set or uses root sampler for the root span.
+ * {@inheritdoc}
+ */
+ public function shouldSample(
+ ContextInterface $parentContext,
+ string $traceId,
+ string $spanName,
+ int $spanKind,
+ AttributesInterface $attributes,
+ array $links
+ ): SamplingResult {
+ $parentSpan = Span::fromContext($parentContext);
+ $parentSpanContext = $parentSpan->getContext();
+
+ // Invalid parent SpanContext indicates root span is being created
+ if (!$parentSpanContext->isValid()) {
+ return $this->root->shouldSample(...func_get_args());
+ }
+
+ if ($parentSpanContext->isRemote()) {
+ return $parentSpanContext->isSampled()
+ ? $this->remoteParentSampler->shouldSample(...func_get_args())
+ : $this->remoteParentNotSampler->shouldSample(...func_get_args());
+ }
+
+ return $parentSpanContext->isSampled()
+ ? $this->localParentSampler->shouldSample(...func_get_args())
+ : $this->localParentNotSampler->shouldSample(...func_get_args());
+ }
+
+ public function getDescription(): string
+ {
+ return 'ParentBased+' . $this->root->getDescription();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/Sampler/TraceIdRatioBasedSampler.php b/vendor/open-telemetry/sdk/Trace/Sampler/TraceIdRatioBasedSampler.php
new file mode 100644
index 000000000..c11a90d5d
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/Sampler/TraceIdRatioBasedSampler.php
@@ -0,0 +1,70 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\Sampler;
+
+use InvalidArgumentException;
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Trace\SamplerInterface;
+use OpenTelemetry\SDK\Trace\SamplingResult;
+use OpenTelemetry\SDK\Trace\Span;
+
+/**
+ * This implementation of the SamplerInterface records with given probability.
+ * Example:
+ * ```
+ * use OpenTelemetry\API\Trace\TraceIdRatioBasedSampler;
+ * $sampler = new TraceIdRatioBasedSampler(0.01);
+ * ```
+ */
+class TraceIdRatioBasedSampler implements SamplerInterface
+{
+ private float $probability;
+
+ /**
+ * TraceIdRatioBasedSampler constructor.
+ * @param float $probability Probability float value between 0.0 and 1.0.
+ */
+ public function __construct(float $probability)
+ {
+ if ($probability < 0.0 || $probability > 1.0) {
+ throw new InvalidArgumentException('probability should be be between 0.0 and 1.0.');
+ }
+ $this->probability = $probability;
+ }
+
+ /**
+ * Returns `SamplingResult` based on probability. Respects the parent `SampleFlag`
+ * {@inheritdoc}
+ */
+ public function shouldSample(
+ ContextInterface $parentContext,
+ string $traceId,
+ string $spanName,
+ int $spanKind,
+ AttributesInterface $attributes,
+ array $links
+ ): SamplingResult {
+ // TODO: Add config to adjust which spans get sampled (only default from specification is implemented)
+ $parentSpan = Span::fromContext($parentContext);
+ $parentSpanContext = $parentSpan->getContext();
+ $traceState = $parentSpanContext->getTraceState();
+
+ /**
+ * Since php can only store up to 63 bit positive integers
+ */
+ $traceIdLimit = (1 << 60) - 1;
+ $lowerOrderBytes = hexdec(substr($traceId, strlen($traceId) - 15, 15));
+ $traceIdCondition = $lowerOrderBytes < round($this->probability * $traceIdLimit);
+ $decision = $traceIdCondition ? SamplingResult::RECORD_AND_SAMPLE : SamplingResult::DROP;
+
+ return new SamplingResult($decision, [], $traceState);
+ }
+
+ public function getDescription(): string
+ {
+ return sprintf('%s{%.6F}', 'TraceIdRatioBasedSampler', $this->probability);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SamplerFactory.php b/vendor/open-telemetry/sdk/Trace/SamplerFactory.php
new file mode 100644
index 000000000..f99674d79
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SamplerFactory.php
@@ -0,0 +1,48 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use InvalidArgumentException;
+use OpenTelemetry\SDK\Common\Configuration\Configuration;
+use OpenTelemetry\SDK\Common\Configuration\KnownValues as Values;
+use OpenTelemetry\SDK\Common\Configuration\Variables as Env;
+use OpenTelemetry\SDK\Trace\Sampler\AlwaysOffSampler;
+use OpenTelemetry\SDK\Trace\Sampler\AlwaysOnSampler;
+use OpenTelemetry\SDK\Trace\Sampler\ParentBased;
+use OpenTelemetry\SDK\Trace\Sampler\TraceIdRatioBasedSampler;
+
+class SamplerFactory
+{
+ private const TRACEIDRATIO_PREFIX = 'traceidratio';
+
+ public function create(): SamplerInterface
+ {
+ $name = Configuration::getString(Env::OTEL_TRACES_SAMPLER);
+
+ if (strpos($name, self::TRACEIDRATIO_PREFIX) !== false) {
+ $arg = Configuration::getRatio(Env::OTEL_TRACES_SAMPLER_ARG);
+
+ switch ($name) {
+ case Values::VALUE_TRACE_ID_RATIO:
+ return new TraceIdRatioBasedSampler($arg);
+ case Values::VALUE_PARENT_BASED_TRACE_ID_RATIO:
+ return new ParentBased(new TraceIdRatioBasedSampler($arg));
+ }
+ }
+
+ switch ($name) {
+ case Values::VALUE_ALWAYS_ON:
+ return new AlwaysOnSampler();
+ case Values::VALUE_ALWAYS_OFF:
+ return new AlwaysOffSampler();
+ case Values::VALUE_PARENT_BASED_ALWAYS_ON:
+ return new ParentBased(new AlwaysOnSampler());
+ case Values::VALUE_PARENT_BASED_ALWAYS_OFF:
+ return new ParentBased(new AlwaysOffSampler());
+ default:
+ throw new InvalidArgumentException(sprintf('Unknown sampler: %s', $name));
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SamplerInterface.php b/vendor/open-telemetry/sdk/Trace/SamplerInterface.php
new file mode 100644
index 000000000..de1147fa6
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SamplerInterface.php
@@ -0,0 +1,46 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+/**
+ * This interface is used to organize sampling logic.
+ *
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md#sampler
+ */
+interface SamplerInterface
+{
+ /**
+ * Returns SamplingResult.
+ *
+ * @param ContextInterface $parentContext Context with parent Span. The Span's SpanContext may be invalid to indicate a root span.
+ * @param string $traceId TraceId of the Span to be created. It can be different from the TraceId in the SpanContext.
+ * Typically in situations when the Span to be created starts a new Trace.
+ * @param string $spanName Name of the Span to be created.
+ * @param int $spanKind Span kind.
+ * @param AttributesInterface $attributes Initial set of Attributes for the Span being constructed.
+ * @param list<LinkInterface> $links Collection of links that will be associated with the Span to be created.
+ * Typically, useful for batch operations.
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/overview.md#links-between-spans
+ * @return SamplingResult
+ */
+ public function shouldSample(
+ ContextInterface $parentContext,
+ string $traceId,
+ string $spanName,
+ int $spanKind,
+ AttributesInterface $attributes,
+ array $links
+ ): SamplingResult;
+
+ /**
+ * Returns the sampler name or short description with the configuration.
+ * This may be displayed on debug pages or in the logs.
+ * Example: "TraceIdRatioBasedSampler{0.000100}"
+ */
+ public function getDescription(): string;
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SamplingResult.php b/vendor/open-telemetry/sdk/Trace/SamplingResult.php
new file mode 100644
index 000000000..5701b7bc6
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SamplingResult.php
@@ -0,0 +1,71 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\API\Trace as API;
+
+final class SamplingResult
+{
+ /**
+ * Span will not be recorded and all events and attributes will be dropped.
+ */
+ public const DROP = 0;
+
+ /**
+ * Span will be recorded but SpanExporters will not receive this Span.
+ */
+ public const RECORD_ONLY = 1;
+
+ /**
+ * Span will be recorder and exported.
+ */
+ public const RECORD_AND_SAMPLE = 2;
+
+ /**
+ * @var int A sampling Decision.
+ */
+ private int $decision;
+
+ /**
+ * @var iterable A set of span Attributes that will also be added to the Span.
+ */
+ private iterable $attributes;
+
+ /**
+ * @var ?API\TraceStateInterface A Tracestate that will be associated with the Span through the new SpanContext.
+ */
+ private ?API\TraceStateInterface $traceState;
+
+ public function __construct(int $decision, iterable $attributes = [], ?API\TraceStateInterface $traceState = null)
+ {
+ $this->decision = $decision;
+ $this->attributes = $attributes;
+ $this->traceState = $traceState;
+ }
+
+ /**
+ * Return sampling decision whether span should be recorded or not.
+ */
+ public function getDecision(): int
+ {
+ return $this->decision;
+ }
+
+ /**
+ * Return attributes which will be attached to the span.
+ */
+ public function getAttributes(): iterable
+ {
+ return $this->attributes;
+ }
+
+ /**
+ * Return a collection of links that will be associated with the Span to be created.
+ */
+ public function getTraceState(): ?API\TraceStateInterface
+ {
+ return $this->traceState;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/Span.php b/vendor/open-telemetry/sdk/Trace/Span.php
new file mode 100644
index 000000000..f72ec1bd7
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/Span.php
@@ -0,0 +1,359 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use function get_class;
+use OpenTelemetry\API\Trace as API;
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesBuilderInterface;
+use OpenTelemetry\SDK\Common\Dev\Compatibility\Util as BcUtil;
+use OpenTelemetry\SDK\Common\Exception\StackTraceFormatter;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Common\Time\ClockFactory;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+use Throwable;
+
+final class Span extends API\Span implements ReadWriteSpanInterface
+{
+
+ /** @readonly */
+ private API\SpanContextInterface $context;
+
+ /** @readonly */
+ private API\SpanContextInterface $parentSpanContext;
+
+ /** @readonly */
+ private SpanLimits $spanLimits;
+
+ /** @readonly */
+ private SpanProcessorInterface $spanProcessor;
+
+ /**
+ * @readonly
+ *
+ * @var list<LinkInterface>
+ */
+ private array $links;
+
+ /** @readonly */
+ private int $totalRecordedLinks;
+
+ /** @readonly */
+ private int $kind;
+
+ /** @readonly */
+ private ResourceInfo $resource;
+
+ /** @readonly */
+ private InstrumentationScopeInterface $instrumentationScope;
+
+ /** @readonly */
+ private int $startEpochNanos;
+
+ /** @var non-empty-string */
+ private string $name;
+
+ /** @var list<EventInterface> */
+ private array $events = [];
+
+ private AttributesBuilderInterface $attributesBuilder;
+ private int $totalRecordedEvents = 0;
+ private StatusDataInterface $status;
+ private int $endEpochNanos = 0;
+ private bool $hasEnded = false;
+
+ /**
+ * @param non-empty-string $name
+ * @param list<LinkInterface> $links
+ */
+ private function __construct(
+ string $name,
+ API\SpanContextInterface $context,
+ InstrumentationScopeInterface $instrumentationScope,
+ int $kind,
+ API\SpanContextInterface $parentSpanContext,
+ SpanLimits $spanLimits,
+ SpanProcessorInterface $spanProcessor,
+ ResourceInfo $resource,
+ AttributesBuilderInterface $attributesBuilder,
+ array $links,
+ int $totalRecordedLinks,
+ int $startEpochNanos
+ ) {
+ $this->context = $context;
+ $this->instrumentationScope = $instrumentationScope;
+ $this->parentSpanContext = $parentSpanContext;
+ $this->links = $links;
+ $this->totalRecordedLinks = $totalRecordedLinks;
+ $this->name = $name;
+ $this->kind = $kind;
+ $this->spanProcessor = $spanProcessor;
+ $this->resource = $resource;
+ $this->startEpochNanos = $startEpochNanos;
+ $this->attributesBuilder = $attributesBuilder;
+ $this->status = StatusData::unset();
+ $this->spanLimits = $spanLimits;
+ }
+
+ /**
+ * This method _MUST_ not be used directly.
+ * End users should use a {@see API\TracerInterface} in order to create spans.
+ *
+ * @param non-empty-string $name
+ * @psalm-param API\SpanKind::KIND_* $kind
+ * @param list<LinkInterface> $links
+ *
+ * @internal
+ * @psalm-internal OpenTelemetry
+ */
+ public static function startSpan(
+ string $name,
+ API\SpanContextInterface $context,
+ InstrumentationScopeInterface $instrumentationScope,
+ int $kind,
+ API\SpanInterface $parentSpan,
+ ContextInterface $parentContext,
+ SpanLimits $spanLimits,
+ SpanProcessorInterface $spanProcessor,
+ ResourceInfo $resource,
+ AttributesBuilderInterface $attributesBuilder,
+ array $links,
+ int $totalRecordedLinks,
+ int $startEpochNanos
+ ): self {
+ $span = new self(
+ $name,
+ $context,
+ $instrumentationScope,
+ $kind,
+ $parentSpan->getContext(),
+ $spanLimits,
+ $spanProcessor,
+ $resource,
+ $attributesBuilder,
+ $links,
+ $totalRecordedLinks,
+ $startEpochNanos !== 0 ? $startEpochNanos : ClockFactory::getDefault()->now()
+ );
+
+ // Call onStart here to ensure the span is fully initialized.
+ $spanProcessor->onStart($span, $parentContext);
+
+ return $span;
+ }
+
+ /**
+ * Backward compatibility methods
+ *
+ * @codeCoverageIgnore
+ */
+ public static function formatStackTrace(Throwable $e, array &$seen = null): string
+ {
+ BcUtil::triggerMethodDeprecationNotice(
+ __METHOD__,
+ 'format',
+ StackTraceFormatter::class
+ );
+
+ return StackTraceFormatter::format($e);
+ }
+
+ /** @inheritDoc */
+ public function getContext(): API\SpanContextInterface
+ {
+ return $this->context;
+ }
+
+ /** @inheritDoc */
+ public function isRecording(): bool
+ {
+ return !$this->hasEnded;
+ }
+
+ /** @inheritDoc */
+ public function setAttribute(string $key, $value): self
+ {
+ if ($this->hasEnded) {
+ return $this;
+ }
+
+ $this->attributesBuilder[$key] = $value;
+
+ return $this;
+ }
+
+ /** @inheritDoc */
+ public function setAttributes(iterable $attributes): self
+ {
+ foreach ($attributes as $key => $value) {
+ $this->attributesBuilder[$key] = $value;
+ }
+
+ return $this;
+ }
+
+ /** @inheritDoc */
+ public function addEvent(string $name, iterable $attributes = [], ?int $timestamp = null): self
+ {
+ if ($this->hasEnded) {
+ return $this;
+ }
+ if (++$this->totalRecordedEvents > $this->spanLimits->getEventCountLimit()) {
+ return $this;
+ }
+
+ $timestamp ??= ClockFactory::getDefault()->now();
+ $eventAttributesBuilder = $this->spanLimits->getEventAttributesFactory()->builder($attributes);
+
+ $this->events[] = new Event($name, $timestamp, $eventAttributesBuilder->build());
+
+ return $this;
+ }
+
+ /** @inheritDoc */
+ public function recordException(Throwable $exception, iterable $attributes = [], ?int $timestamp = null): self
+ {
+ if ($this->hasEnded) {
+ return $this;
+ }
+ if (++$this->totalRecordedEvents > $this->spanLimits->getEventCountLimit()) {
+ return $this;
+ }
+
+ $timestamp ??= ClockFactory::getDefault()->now();
+ $eventAttributesBuilder = $this->spanLimits->getEventAttributesFactory()->builder([
+ 'exception.type' => get_class($exception),
+ 'exception.message' => $exception->getMessage(),
+ 'exception.stacktrace' => StackTraceFormatter::format($exception),
+ ]);
+
+ foreach ($attributes as $key => $value) {
+ $eventAttributesBuilder[$key] = $value;
+ }
+
+ $this->events[] = new Event('exception', $timestamp, $eventAttributesBuilder->build());
+
+ return $this;
+ }
+
+ /** @inheritDoc */
+ public function updateName(string $name): self
+ {
+ if ($this->hasEnded) {
+ return $this;
+ }
+ $this->name = $name;
+
+ return $this;
+ }
+
+ /** @inheritDoc */
+ public function setStatus(string $code, string $description = null): self
+ {
+ if ($this->hasEnded) {
+ return $this;
+ }
+
+ // An attempt to set value Unset SHOULD be ignored.
+ if ($code === API\StatusCode::STATUS_UNSET) {
+ return $this;
+ }
+
+ // When span status is set to Ok it SHOULD be considered final and any further attempts to change it SHOULD be ignored.
+ if ($this->status->getCode() === API\StatusCode::STATUS_OK) {
+ return $this;
+ }
+ $this->status = StatusData::create($code, $description);
+
+ return $this;
+ }
+
+ /** @inheritDoc */
+ public function end(int $endEpochNanos = null): void
+ {
+ if ($this->hasEnded) {
+ return;
+ }
+
+ $this->endEpochNanos = $endEpochNanos ?? ClockFactory::getDefault()->now();
+ $this->hasEnded = true;
+
+ $this->spanProcessor->onEnd($this);
+ }
+
+ /** @inheritDoc */
+ public function getName(): string
+ {
+ return $this->name;
+ }
+
+ public function getParentContext(): API\SpanContextInterface
+ {
+ return $this->parentSpanContext;
+ }
+
+ public function getInstrumentationScope(): InstrumentationScopeInterface
+ {
+ return $this->instrumentationScope;
+ }
+
+ public function hasEnded(): bool
+ {
+ return $this->hasEnded;
+ }
+
+ public function toSpanData(): SpanDataInterface
+ {
+ return new ImmutableSpan(
+ $this,
+ $this->name,
+ $this->links,
+ $this->events,
+ $this->attributesBuilder->build(),
+ $this->totalRecordedEvents,
+ $this->status,
+ $this->endEpochNanos,
+ $this->hasEnded
+ );
+ }
+
+ /** @inheritDoc */
+ public function getDuration(): int
+ {
+ return ($this->hasEnded ? $this->endEpochNanos : ClockFactory::getDefault()->now()) - $this->startEpochNanos;
+ }
+
+ /** @inheritDoc */
+ public function getKind(): int
+ {
+ return $this->kind;
+ }
+
+ /** @inheritDoc */
+ public function getAttribute(string $key)
+ {
+ return $this->attributesBuilder[$key];
+ }
+
+ public function getStartEpochNanos(): int
+ {
+ return $this->startEpochNanos;
+ }
+
+ public function getTotalRecordedLinks(): int
+ {
+ return $this->totalRecordedLinks;
+ }
+
+ public function getTotalRecordedEvents(): int
+ {
+ return $this->totalRecordedEvents;
+ }
+
+ public function getResource(): ResourceInfo
+ {
+ return $this->resource;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanBuilder.php b/vendor/open-telemetry/sdk/Trace/SpanBuilder.php
new file mode 100644
index 000000000..2867c01c8
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanBuilder.php
@@ -0,0 +1,191 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use function in_array;
+use OpenTelemetry\API\Trace as API;
+use OpenTelemetry\Context\Context;
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesBuilderInterface;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+
+final class SpanBuilder implements API\SpanBuilderInterface
+{
+ /**
+ * @var non-empty-string
+ * @readonly
+ */
+ private string $spanName;
+
+ /** @readonly */
+ private InstrumentationScopeInterface $instrumentationScope;
+
+ /** @readonly */
+ private TracerSharedState $tracerSharedState;
+
+ /** @var ContextInterface|false|null */
+ private $parentContext = null;
+
+ /**
+ * @psalm-var API\SpanKind::KIND_*
+ */
+ private int $spanKind = API\SpanKind::KIND_INTERNAL;
+
+ /** @var list<LinkInterface> */
+ private array $links = [];
+
+ private AttributesBuilderInterface $attributesBuilder;
+ private int $totalNumberOfLinksAdded = 0;
+ private int $startEpochNanos = 0;
+
+ /** @param non-empty-string $spanName */
+ public function __construct(
+ string $spanName,
+ InstrumentationScopeInterface $instrumentationScope,
+ TracerSharedState $tracerSharedState
+ ) {
+ $this->spanName = $spanName;
+ $this->instrumentationScope = $instrumentationScope;
+ $this->tracerSharedState = $tracerSharedState;
+ $this->attributesBuilder = $tracerSharedState->getSpanLimits()->getAttributesFactory()->builder();
+ }
+
+ /** @inheritDoc */
+ public function setParent($context): API\SpanBuilderInterface
+ {
+ $this->parentContext = $context;
+
+ return $this;
+ }
+
+ /** @inheritDoc */
+ public function addLink(API\SpanContextInterface $context, iterable $attributes = []): API\SpanBuilderInterface
+ {
+ if (!$context->isValid()) {
+ return $this;
+ }
+
+ $this->totalNumberOfLinksAdded++;
+
+ if (count($this->links) === $this->tracerSharedState->getSpanLimits()->getLinkCountLimit()) {
+ return $this;
+ }
+
+ $this->links[] = new Link(
+ $context,
+ $this->tracerSharedState
+ ->getSpanLimits()
+ ->getLinkAttributesFactory()
+ ->builder($attributes)
+ ->build(),
+ );
+
+ return $this;
+ }
+
+ /** @inheritDoc */
+ public function setAttribute(string $key, $value): API\SpanBuilderInterface
+ {
+ $this->attributesBuilder[$key] = $value;
+
+ return $this;
+ }
+
+ /** @inheritDoc */
+ public function setAttributes(iterable $attributes): API\SpanBuilderInterface
+ {
+ foreach ($attributes as $key => $value) {
+ $this->attributesBuilder[$key] = $value;
+ }
+
+ return $this;
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * @psalm-param API\SpanKind::KIND_* $spanKind
+ */
+ public function setSpanKind(int $spanKind): API\SpanBuilderInterface
+ {
+ $this->spanKind = $spanKind;
+
+ return $this;
+ }
+
+ /** @inheritDoc */
+ public function setStartTimestamp(int $timestampNanos): API\SpanBuilderInterface
+ {
+ if (0 > $timestampNanos) {
+ return $this;
+ }
+
+ $this->startEpochNanos = $timestampNanos;
+
+ return $this;
+ }
+
+ /** @inheritDoc */
+ public function startSpan(): API\SpanInterface
+ {
+ $parentContext = Context::resolve($this->parentContext);
+ $parentSpan = Span::fromContext($parentContext);
+ $parentSpanContext = $parentSpan->getContext();
+
+ $spanId = $this->tracerSharedState->getIdGenerator()->generateSpanId();
+
+ if (!$parentSpanContext->isValid()) {
+ $traceId = $this->tracerSharedState->getIdGenerator()->generateTraceId();
+ } else {
+ $traceId = $parentSpanContext->getTraceId();
+ }
+
+ $samplingResult = $this
+ ->tracerSharedState
+ ->getSampler()
+ ->shouldSample(
+ $parentContext,
+ $traceId,
+ $this->spanName,
+ $this->spanKind,
+ $this->attributesBuilder->build(),
+ $this->links,
+ );
+ $samplingDecision = $samplingResult->getDecision();
+ $samplingResultTraceState = $samplingResult->getTraceState();
+
+ $spanContext = API\SpanContext::create(
+ $traceId,
+ $spanId,
+ SamplingResult::RECORD_AND_SAMPLE === $samplingDecision ? API\TraceFlags::SAMPLED : API\TraceFlags::DEFAULT,
+ $samplingResultTraceState,
+ );
+
+ if (!in_array($samplingDecision, [SamplingResult::RECORD_AND_SAMPLE, SamplingResult::RECORD_ONLY], true)) {
+ return Span::wrap($spanContext);
+ }
+
+ $attributesBuilder = clone $this->attributesBuilder;
+ foreach ($samplingResult->getAttributes() as $key => $value) {
+ $attributesBuilder[$key] = $value;
+ }
+
+ return Span::startSpan(
+ $this->spanName,
+ $spanContext,
+ $this->instrumentationScope,
+ $this->spanKind,
+ $parentSpan,
+ $parentContext,
+ $this->tracerSharedState->getSpanLimits(),
+ $this->tracerSharedState->getSpanProcessor(),
+ $this->tracerSharedState->getResource(),
+ $attributesBuilder,
+ $this->links,
+ $this->totalNumberOfLinksAdded,
+ $this->startEpochNanos
+ );
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanConverterInterface.php b/vendor/open-telemetry/sdk/Trace/SpanConverterInterface.php
new file mode 100644
index 000000000..40552e440
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanConverterInterface.php
@@ -0,0 +1,10 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+interface SpanConverterInterface
+{
+ public function convert(iterable $spans): array;
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanDataInterface.php b/vendor/open-telemetry/sdk/Trace/SpanDataInterface.php
new file mode 100644
index 000000000..37132b9e5
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanDataInterface.php
@@ -0,0 +1,46 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\API\Trace as API;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+
+/**
+ * Represents an immutable snapshot of a {@see API\SpanInterface}.
+ *
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.1/specification/trace/sdk.md#additional-span-interfaces
+ */
+interface SpanDataInterface
+{
+ public function getName(): string;
+ public function getKind(): int;
+ public function getContext(): API\SpanContextInterface;
+ public function getParentContext(): API\SpanContextInterface;
+ public function getTraceId(): string;
+ public function getSpanId(): string;
+ public function getParentSpanId(): string;
+ public function getStatus(): StatusDataInterface;
+ public function getStartEpochNanos(): int;
+ public function getAttributes(): AttributesInterface;
+
+ /** @return list<EventInterface> */
+ public function getEvents(): array;
+
+ /** @return list<LinkInterface> */
+ public function getLinks(): array;
+
+ public function getEndEpochNanos(): int;
+ public function hasEnded(): bool;
+ public function getInstrumentationScope(): InstrumentationScopeInterface;
+ public function getResource(): ResourceInfo;
+
+ /** @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.1/specification/trace/sdk_exporters/non-otlp.md#dropped-events-count */
+ public function getTotalDroppedEvents(): int;
+
+ /** @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.1/specification/trace/sdk_exporters/non-otlp.md#dropped-links-count */
+ public function getTotalDroppedLinks(): int;
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanExporter/AbstractDecorator.php b/vendor/open-telemetry/sdk/Trace/SpanExporter/AbstractDecorator.php
new file mode 100644
index 000000000..42f49e815
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanExporter/AbstractDecorator.php
@@ -0,0 +1,12 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanExporter;
+
+use OpenTelemetry\SDK\Trace\Behavior\SpanExporterDecoratorTrait;
+
+abstract class AbstractDecorator
+{
+ use SpanExporterDecoratorTrait;
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanExporter/ConsoleSpanExporter.php b/vendor/open-telemetry/sdk/Trace/SpanExporter/ConsoleSpanExporter.php
new file mode 100644
index 000000000..482d122cc
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanExporter/ConsoleSpanExporter.php
@@ -0,0 +1,57 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanExporter;
+
+use JsonException;
+use OpenTelemetry\API\Behavior\LogsMessagesTrait;
+use OpenTelemetry\SDK\Common\Export\TransportInterface;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Common\Future\FutureInterface;
+use OpenTelemetry\SDK\Trace\Behavior\UsesSpanConverterTrait;
+use OpenTelemetry\SDK\Trace\SpanConverterInterface;
+use OpenTelemetry\SDK\Trace\SpanExporterInterface;
+
+class ConsoleSpanExporter implements SpanExporterInterface
+{
+ use UsesSpanConverterTrait;
+ use LogsMessagesTrait;
+
+ private TransportInterface $transport;
+
+ public function __construct(TransportInterface $transport, ?SpanConverterInterface $converter = null)
+ {
+ $this->transport = $transport;
+ $this->setSpanConverter($converter ?? new FriendlySpanConverter());
+ }
+
+ public function export(iterable $batch, ?CancellationInterface $cancellation = null): FutureInterface
+ {
+ $payload = '';
+ foreach ($batch as $span) {
+ try {
+ $payload .= json_encode(
+ $this->getSpanConverter()->convert([$span]),
+ JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT
+ ) . PHP_EOL;
+ } catch (JsonException $e) {
+ self::logWarning('Error converting span: ' . $e->getMessage());
+ }
+ }
+
+ return $this->transport->send($payload)
+ ->map(fn () => true)
+ ->catch(fn () => false);
+ }
+
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ return $this->transport->shutdown();
+ }
+
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ return $this->transport->forceFlush();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanExporter/ConsoleSpanExporterFactory.php b/vendor/open-telemetry/sdk/Trace/SpanExporter/ConsoleSpanExporterFactory.php
new file mode 100644
index 000000000..7e45fb549
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanExporter/ConsoleSpanExporterFactory.php
@@ -0,0 +1,18 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanExporter;
+
+use OpenTelemetry\SDK\Registry;
+use OpenTelemetry\SDK\Trace\SpanExporterInterface;
+
+class ConsoleSpanExporterFactory implements SpanExporterFactoryInterface
+{
+ public function create(): SpanExporterInterface
+ {
+ $transport = Registry::transportFactory('stream')->create('php://stdout', 'application/json');
+
+ return new ConsoleSpanExporter($transport);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanExporter/FriendlySpanConverter.php b/vendor/open-telemetry/sdk/Trace/SpanExporter/FriendlySpanConverter.php
new file mode 100644
index 000000000..1f8178e10
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanExporter/FriendlySpanConverter.php
@@ -0,0 +1,173 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanExporter;
+
+use OpenTelemetry\API\Trace\SpanContextInterface;
+use OpenTelemetry\API\Trace\SpanKind;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+use OpenTelemetry\SDK\Trace\EventInterface;
+use OpenTelemetry\SDK\Trace\LinkInterface;
+use OpenTelemetry\SDK\Trace\SpanConverterInterface;
+use OpenTelemetry\SDK\Trace\SpanDataInterface;
+use OpenTelemetry\SDK\Trace\StatusDataInterface;
+use ReflectionClass;
+
+class FriendlySpanConverter implements SpanConverterInterface
+{
+ private const NAME_ATTR = 'name';
+ private const CONTEXT_ATTR = 'context';
+ private const TRACE_ID_ATTR = 'trace_id';
+ private const SPAN_ID_ATTR = 'span_id';
+ private const TRACE_STATE_ATTR = 'trace_state';
+ private const RESOURCE_ATTR = 'resource';
+ private const PARENT_SPAN_ATTR = 'parent_span_id';
+ private const KIND_ATTR = 'kind';
+ private const START_ATTR = 'start';
+ private const END_ATTR = 'end';
+ private const ATTRIBUTES_ATTR = 'attributes';
+ private const STATUS_ATTR = 'status';
+ private const CODE_ATTR = 'code';
+ private const DESCRIPTION_ATTR = 'description';
+ private const EVENTS_ATTR = 'events';
+ private const TIMESTAMP_ATTR = 'timestamp';
+ private const LINKS_ATTR = 'links';
+
+ public function convert(iterable $spans): array
+ {
+ $aggregate = [];
+ foreach ($spans as $span) {
+ $aggregate[] = $this->convertSpan($span);
+ }
+
+ return $aggregate;
+ }
+
+ /**
+ * friendlySpan does the heavy lifting converting a span into an array
+ *
+ * @param SpanDataInterface $span
+ * @return array
+ */
+ private function convertSpan(SpanDataInterface $span): array
+ {
+ return [
+ self::NAME_ATTR => $span->getName(),
+ self::CONTEXT_ATTR => $this->convertContext($span->getContext()),
+ self::RESOURCE_ATTR => $this->convertResource($span->getResource()),
+ self::PARENT_SPAN_ATTR => $this->covertParentContext($span->getParentContext()),
+ self::KIND_ATTR => $this->convertKind($span->getKind()),
+ self::START_ATTR => $span->getStartEpochNanos(),
+ self::END_ATTR => $span->getEndEpochNanos(),
+ self::ATTRIBUTES_ATTR => $this->convertAttributes($span->getAttributes()),
+ self::STATUS_ATTR => $this->covertStatus($span->getStatus()),
+ self::EVENTS_ATTR => $this->convertEvents($span->getEvents()),
+ self::LINKS_ATTR => $this->convertLinks($span->getLinks()),
+ ];
+ }
+
+ /**
+ * @param SpanContextInterface $context
+ * @return array
+ */
+ private function convertContext(SpanContextInterface $context): array
+ {
+ return [
+ self::TRACE_ID_ATTR => $context->getTraceId(),
+ self::SPAN_ID_ATTR => $context->getSpanId(),
+ self::TRACE_STATE_ATTR => (string) $context->getTraceState(),
+ ];
+ }
+
+ /**
+ * @param ResourceInfo $resource
+ * @return array
+ */
+ private function convertResource(ResourceInfo $resource): array
+ {
+ return $resource->getAttributes()->toArray();
+ }
+
+ /**
+ * @param SpanContextInterface $context
+ * @return string
+ */
+ private function covertParentContext(SpanContextInterface $context): string
+ {
+ return $context->isValid() ? $context->getSpanId() : '';
+ }
+
+ /**
+ * Translates SpanKind from its integer representation to a more human friendly string.
+ *
+ * @param int $kind
+ * @return string
+ */
+ private function convertKind(int $kind): string
+ {
+ return array_flip(
+ (new ReflectionClass(SpanKind::class))
+ ->getConstants()
+ )[$kind];
+ }
+
+ /**
+ * @param \OpenTelemetry\SDK\Common\Attribute\AttributesInterface $attributes
+ * @return array
+ */
+ private function convertAttributes(AttributesInterface $attributes): array
+ {
+ return $attributes->toArray();
+ }
+
+ /**
+ * @param StatusDataInterface $status
+ * @return array
+ */
+ private function covertStatus(StatusDataInterface $status): array
+ {
+ return [
+ self::CODE_ATTR => $status->getCode(),
+ self::DESCRIPTION_ATTR => $status->getDescription(),
+ ];
+ }
+
+ /**
+ * @param array<EventInterface> $events
+ * @return array
+ */
+ private function convertEvents(array $events): array
+ {
+ $result = [];
+
+ foreach ($events as $event) {
+ $result[] = [
+ self::NAME_ATTR => $event->getName(),
+ self::TIMESTAMP_ATTR => $event->getEpochNanos(),
+ self::ATTRIBUTES_ATTR => $this->convertAttributes($event->getAttributes()),
+ ];
+ }
+
+ return $result;
+ }
+
+ /**
+ * @param array<LinkInterface> $links
+ * @return array
+ */
+ private function convertLinks(array $links): array
+ {
+ $result = [];
+
+ foreach ($links as $link) {
+ $result[] = [
+ self::CONTEXT_ATTR => $this->convertContext($link->getSpanContext()),
+ self::ATTRIBUTES_ATTR => $this->convertAttributes($link->getAttributes()),
+ ];
+ }
+
+ return $result;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanExporter/InMemoryExporter.php b/vendor/open-telemetry/sdk/Trace/SpanExporter/InMemoryExporter.php
new file mode 100644
index 000000000..ebb022595
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanExporter/InMemoryExporter.php
@@ -0,0 +1,40 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanExporter;
+
+use ArrayObject;
+use OpenTelemetry\SDK\Trace\Behavior\SpanExporterTrait;
+use OpenTelemetry\SDK\Trace\SpanExporterInterface;
+
+class InMemoryExporter implements SpanExporterInterface
+{
+ use SpanExporterTrait;
+
+ private ArrayObject $storage;
+
+ public function __construct(?ArrayObject $storage = null)
+ {
+ $this->storage = $storage ?? new ArrayObject();
+ }
+
+ protected function doExport(iterable $spans): bool
+ {
+ foreach ($spans as $span) {
+ $this->storage[] = $span;
+ }
+
+ return true;
+ }
+
+ public function getSpans(): array
+ {
+ return (array) $this->storage;
+ }
+
+ public function getStorage(): ArrayObject
+ {
+ return $this->storage;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanExporter/InMemorySpanExporterFactory.php b/vendor/open-telemetry/sdk/Trace/SpanExporter/InMemorySpanExporterFactory.php
new file mode 100644
index 000000000..c19686fac
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanExporter/InMemorySpanExporterFactory.php
@@ -0,0 +1,15 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanExporter;
+
+use OpenTelemetry\SDK\Trace\SpanExporterInterface;
+
+class InMemorySpanExporterFactory implements SpanExporterFactoryInterface
+{
+ public function create(): SpanExporterInterface
+ {
+ return new InMemoryExporter();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanExporter/LoggerDecorator.php b/vendor/open-telemetry/sdk/Trace/SpanExporter/LoggerDecorator.php
new file mode 100644
index 000000000..b7cf511a5
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanExporter/LoggerDecorator.php
@@ -0,0 +1,58 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanExporter;
+
+use OpenTelemetry\SDK\Trace\Behavior\LoggerAwareTrait;
+use OpenTelemetry\SDK\Trace\Behavior\SpanExporterDecoratorTrait;
+use OpenTelemetry\SDK\Trace\Behavior\UsesSpanConverterTrait;
+use OpenTelemetry\SDK\Trace\SpanConverterInterface;
+use OpenTelemetry\SDK\Trace\SpanExporterInterface;
+use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerInterface;
+use Psr\Log\LogLevel;
+use Psr\Log\NullLogger;
+
+class LoggerDecorator implements SpanExporterInterface, LoggerAwareInterface
+{
+ use SpanExporterDecoratorTrait;
+ use UsesSpanConverterTrait;
+ use LoggerAwareTrait;
+
+ public function __construct(
+ SpanExporterInterface $decorated,
+ ?LoggerInterface $logger = null,
+ ?SpanConverterInterface $converter = null
+ ) {
+ $this->setDecorated($decorated);
+ $this->setLogger($logger ?? new NullLogger());
+ $this->setSpanConverter($converter ?? new FriendlySpanConverter());
+ }
+
+ protected function beforeExport(iterable $spans): iterable
+ {
+ return $spans;
+ }
+
+ /**
+ * @param iterable $spans
+ * @param bool $exportSuccess
+ */
+ protected function afterExport(iterable $spans, bool $exportSuccess): void
+ {
+ if ($exportSuccess) {
+ $this->log(
+ 'Status Success',
+ $this->getSpanConverter()->convert($spans),
+ LogLevel::INFO,
+ );
+ } else {
+ $this->log(
+ 'Status Failed Retryable',
+ $this->getSpanConverter()->convert($spans),
+ LogLevel::ERROR,
+ );
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanExporter/LoggerExporter.php b/vendor/open-telemetry/sdk/Trace/SpanExporter/LoggerExporter.php
new file mode 100644
index 000000000..1969a5426
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanExporter/LoggerExporter.php
@@ -0,0 +1,96 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanExporter;
+
+use OpenTelemetry\SDK\Trace\Behavior\LoggerAwareTrait;
+use OpenTelemetry\SDK\Trace\Behavior\SpanExporterTrait;
+use OpenTelemetry\SDK\Trace\Behavior\UsesSpanConverterTrait;
+use OpenTelemetry\SDK\Trace\SpanConverterInterface;
+use OpenTelemetry\SDK\Trace\SpanExporterInterface;
+use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerInterface;
+use Psr\Log\LogLevel;
+use Psr\Log\NullLogger;
+use Throwable;
+
+class LoggerExporter implements SpanExporterInterface, LoggerAwareInterface
+{
+ use SpanExporterTrait;
+ use UsesSpanConverterTrait;
+ use LoggerAwareTrait;
+
+ public const GRANULARITY_AGGREGATE = 1;
+ public const GRANULARITY_SPAN = 2;
+
+ private string $serviceName;
+ private int $granularity = self::GRANULARITY_AGGREGATE;
+
+ /**
+ * @param string $serviceName
+ * @param LoggerInterface|null $logger
+ * @param string|null $defaultLogLevel
+ * @param SpanConverterInterface|null $converter
+ * @param int $granularity
+ */
+ public function __construct(
+ string $serviceName,
+ ?LoggerInterface $logger = null,
+ ?string $defaultLogLevel = LogLevel::DEBUG,
+ ?SpanConverterInterface $converter = null,
+ int $granularity = 1
+ ) {
+ $this->setServiceName($serviceName);
+ $this->setLogger($logger ?? new NullLogger());
+ $this->setDefaultLogLevel($defaultLogLevel ?? LogLevel::DEBUG);
+ $this->setSpanConverter($converter ?? new FriendlySpanConverter());
+ $this->setGranularity($granularity);
+ }
+
+ /** @inheritDoc */
+ public function doExport(iterable $spans): bool
+ {
+ try {
+ $this->doLog($spans);
+ } catch (Throwable $t) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * @param string $serviceName
+ */
+ private function setServiceName(string $serviceName): void
+ {
+ $this->serviceName = $serviceName;
+ }
+
+ /**
+ * @param int $granularity
+ */
+ public function setGranularity(int $granularity): void
+ {
+ $this->granularity = $granularity === self::GRANULARITY_SPAN
+ ? self::GRANULARITY_SPAN
+ : self::GRANULARITY_AGGREGATE;
+ }
+
+ /**
+ * @param iterable $spans
+ */
+ private function doLog(iterable $spans): void
+ {
+ if ($this->granularity === self::GRANULARITY_AGGREGATE) {
+ $this->log($this->serviceName, $this->getSpanConverter()->convert($spans));
+
+ return;
+ }
+
+ foreach ($spans as $span) {
+ $this->log($this->serviceName, $this->getSpanConverter()->convert([$span]));
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanExporter/NullSpanConverter.php b/vendor/open-telemetry/sdk/Trace/SpanExporter/NullSpanConverter.php
new file mode 100644
index 000000000..1e55431a8
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanExporter/NullSpanConverter.php
@@ -0,0 +1,15 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanExporter;
+
+use OpenTelemetry\SDK\Trace\SpanConverterInterface;
+
+class NullSpanConverter implements SpanConverterInterface
+{
+ public function convert(iterable $spans): array
+ {
+ return [[]];
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanExporter/SpanExporterFactoryInterface.php b/vendor/open-telemetry/sdk/Trace/SpanExporter/SpanExporterFactoryInterface.php
new file mode 100644
index 000000000..8d44b35eb
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanExporter/SpanExporterFactoryInterface.php
@@ -0,0 +1,12 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanExporter;
+
+use OpenTelemetry\SDK\Trace\SpanExporterInterface;
+
+interface SpanExporterFactoryInterface
+{
+ public function create(): SpanExporterInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanExporter/_register.php b/vendor/open-telemetry/sdk/Trace/SpanExporter/_register.php
new file mode 100644
index 000000000..aad07be42
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanExporter/_register.php
@@ -0,0 +1,7 @@
+<?php
+
+declare(strict_types=1);
+\OpenTelemetry\SDK\Registry::registerSpanExporterFactory('console', \OpenTelemetry\SDK\Trace\SpanExporter\ConsoleSpanExporterFactory::class);
+\OpenTelemetry\SDK\Registry::registerSpanExporterFactory('memory', \OpenTelemetry\SDK\Trace\SpanExporter\InMemorySpanExporterFactory::class);
+
+\OpenTelemetry\SDK\Registry::registerTransportFactory('stream', \OpenTelemetry\SDK\Common\Export\Stream\StreamTransportFactory::class);
diff --git a/vendor/open-telemetry/sdk/Trace/SpanExporterInterface.php b/vendor/open-telemetry/sdk/Trace/SpanExporterInterface.php
new file mode 100644
index 000000000..fca336896
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanExporterInterface.php
@@ -0,0 +1,29 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Common\Future\FutureInterface;
+
+/**
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/specification/trace/sdk.md#span-exporter
+ */
+interface SpanExporterInterface
+{
+ /**
+ * @param iterable<SpanDataInterface> $batch Batch of spans to export
+ *
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/specification/trace/sdk.md#exportbatch
+ *
+ * @psalm-return FutureInterface<bool>
+ */
+ public function export(iterable $batch, ?CancellationInterface $cancellation = null): FutureInterface;
+
+ /** @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/specification/trace/sdk.md#shutdown-2 */
+ public function shutdown(?CancellationInterface $cancellation = null): bool;
+
+ /** @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/specification/trace/sdk.md#forceflush-2 */
+ public function forceFlush(?CancellationInterface $cancellation = null): bool;
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanLimits.php b/vendor/open-telemetry/sdk/Trace/SpanLimits.php
new file mode 100644
index 000000000..4b07649fc
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanLimits.php
@@ -0,0 +1,67 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\SDK\Common\Attribute\AttributesFactoryInterface;
+
+final class SpanLimits
+{
+ public const DEFAULT_SPAN_ATTRIBUTE_LENGTH_LIMIT = PHP_INT_MAX;
+ public const DEFAULT_SPAN_ATTRIBUTE_COUNT_LIMIT = 128;
+ public const DEFAULT_SPAN_EVENT_COUNT_LIMIT = 128;
+ public const DEFAULT_SPAN_LINK_COUNT_LIMIT = 128;
+ public const DEFAULT_EVENT_ATTRIBUTE_COUNT_LIMIT = 128;
+ public const DEFAULT_LINK_ATTRIBUTE_COUNT_LIMIT = 128;
+
+ private AttributesFactoryInterface $attributesFactory;
+ private AttributesFactoryInterface $eventAttributesFactory;
+ private AttributesFactoryInterface $linkAttributesFactory;
+ private int $eventCountLimit;
+ private int $linkCountLimit;
+
+ public function getAttributesFactory(): AttributesFactoryInterface
+ {
+ return $this->attributesFactory;
+ }
+
+ public function getEventAttributesFactory(): AttributesFactoryInterface
+ {
+ return $this->eventAttributesFactory;
+ }
+
+ public function getLinkAttributesFactory(): AttributesFactoryInterface
+ {
+ return $this->linkAttributesFactory;
+ }
+
+ /** @return int Maximum allowed span event count */
+ public function getEventCountLimit(): int
+ {
+ return $this->eventCountLimit;
+ }
+
+ /** @return int Maximum allowed span link count */
+ public function getLinkCountLimit(): int
+ {
+ return $this->linkCountLimit;
+ }
+
+ /**
+ * @internal Use {@see SpanLimitsBuilder} to create {@see SpanLimits} instance.
+ */
+ public function __construct(
+ AttributesFactoryInterface $attributesFactory,
+ AttributesFactoryInterface $eventAttributesFactory,
+ AttributesFactoryInterface $linkAttributesFactory,
+ int $eventCountLimit,
+ int $linkCountLimit
+ ) {
+ $this->attributesFactory = $attributesFactory;
+ $this->eventAttributesFactory = $eventAttributesFactory;
+ $this->linkAttributesFactory = $linkAttributesFactory;
+ $this->eventCountLimit = $eventCountLimit;
+ $this->linkCountLimit = $linkCountLimit;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanLimitsBuilder.php b/vendor/open-telemetry/sdk/Trace/SpanLimitsBuilder.php
new file mode 100644
index 000000000..11ed5a82b
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanLimitsBuilder.php
@@ -0,0 +1,148 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\SDK\Common\Attribute\Attributes;
+use OpenTelemetry\SDK\Common\Attribute\FilteredAttributesFactory;
+use OpenTelemetry\SDK\Common\Configuration\Configuration;
+use OpenTelemetry\SDK\Common\Configuration\Variables as Env;
+use OpenTelemetry\SemConv\TraceAttributes;
+use const PHP_INT_MAX;
+
+class SpanLimitsBuilder
+{
+ /** @var ?int Maximum allowed attribute count per record */
+ private ?int $attributeCountLimit = null;
+
+ /** @var ?int Maximum allowed attribute value length */
+ private ?int $attributeValueLengthLimit = null;
+
+ /** @var ?int Maximum allowed span event count */
+ private ?int $eventCountLimit = null;
+
+ /** @var ?int Maximum allowed span link count */
+ private ?int $linkCountLimit = null;
+
+ /** @var ?int Maximum allowed attribute per span event count */
+ private ?int $attributePerEventCountLimit = null;
+
+ /** @var ?int Maximum allowed attribute per span link count */
+ private ?int $attributePerLinkCountLimit = null;
+
+ private bool $retainGeneralIdentityAttributes = false;
+
+ /**
+ * @param int $attributeCountLimit Maximum allowed attribute count per record
+ */
+ public function setAttributeCountLimit(int $attributeCountLimit): SpanLimitsBuilder
+ {
+ $this->attributeCountLimit = $attributeCountLimit;
+
+ return $this;
+ }
+
+ /**
+ * @param int $attributeValueLengthLimit Maximum allowed attribute value length
+ */
+ public function setAttributeValueLengthLimit(int $attributeValueLengthLimit): SpanLimitsBuilder
+ {
+ $this->attributeValueLengthLimit = $attributeValueLengthLimit;
+
+ return $this;
+ }
+
+ /**
+ * @param int $eventCountLimit Maximum allowed span event count
+ */
+ public function setEventCountLimit(int $eventCountLimit): SpanLimitsBuilder
+ {
+ $this->eventCountLimit = $eventCountLimit;
+
+ return $this;
+ }
+
+ /**
+ * @param int $linkCountLimit Maximum allowed span link count
+ */
+ public function setLinkCountLimit(int $linkCountLimit): SpanLimitsBuilder
+ {
+ $this->linkCountLimit = $linkCountLimit;
+
+ return $this;
+ }
+
+ /**
+ * @param int $attributePerEventCountLimit Maximum allowed attribute per span event count
+ */
+ public function setAttributePerEventCountLimit(int $attributePerEventCountLimit): SpanLimitsBuilder
+ {
+ $this->attributePerEventCountLimit = $attributePerEventCountLimit;
+
+ return $this;
+ }
+
+ /**
+ * @param int $attributePerLinkCountLimit Maximum allowed attribute per span link count
+ */
+ public function setAttributePerLinkCountLimit(int $attributePerLinkCountLimit): SpanLimitsBuilder
+ {
+ $this->attributePerLinkCountLimit = $attributePerLinkCountLimit;
+
+ return $this;
+ }
+
+ /**
+ * @param bool $retain whether general identity attributes should be retained
+ *
+ * @see https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/attributes.md#general-identity-attributes
+ */
+ public function retainGeneralIdentityAttributes(bool $retain = true): SpanLimitsBuilder
+ {
+ $this->retainGeneralIdentityAttributes = $retain;
+
+ return $this;
+ }
+
+ /**
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#span-limits
+ */
+ public function build(): SpanLimits
+ {
+ $attributeCountLimit = $this->attributeCountLimit
+ ?: Configuration::getInt(Env::OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT, SpanLimits::DEFAULT_SPAN_ATTRIBUTE_COUNT_LIMIT);
+ $attributeValueLengthLimit = $this->attributeValueLengthLimit
+ ?: Configuration::getInt(Env::OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT, SpanLimits::DEFAULT_SPAN_ATTRIBUTE_LENGTH_LIMIT);
+ $eventCountLimit = $this->eventCountLimit
+ ?: Configuration::getInt(Env::OTEL_SPAN_EVENT_COUNT_LIMIT, SpanLimits::DEFAULT_SPAN_EVENT_COUNT_LIMIT);
+ $linkCountLimit = $this->linkCountLimit
+ ?: Configuration::getInt(Env::OTEL_SPAN_LINK_COUNT_LIMIT, SpanLimits::DEFAULT_SPAN_LINK_COUNT_LIMIT);
+ $attributePerEventCountLimit = $this->attributePerEventCountLimit
+ ?: Configuration::getInt(Env::OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT, SpanLimits::DEFAULT_EVENT_ATTRIBUTE_COUNT_LIMIT);
+ $attributePerLinkCountLimit = $this->attributePerLinkCountLimit
+ ?: Configuration::getInt(Env::OTEL_LINK_ATTRIBUTE_COUNT_LIMIT, SpanLimits::DEFAULT_LINK_ATTRIBUTE_COUNT_LIMIT);
+
+ if ($attributeValueLengthLimit === PHP_INT_MAX) {
+ $attributeValueLengthLimit = null;
+ }
+
+ $spanAttributesFactory = Attributes::factory($attributeCountLimit, $attributeValueLengthLimit);
+
+ if (!$this->retainGeneralIdentityAttributes) {
+ $spanAttributesFactory = new FilteredAttributesFactory($spanAttributesFactory, [
+ TraceAttributes::ENDUSER_ID,
+ TraceAttributes::ENDUSER_ROLE,
+ TraceAttributes::ENDUSER_SCOPE,
+ ]);
+ }
+
+ return new SpanLimits(
+ $spanAttributesFactory,
+ Attributes::factory($attributePerEventCountLimit, $attributeValueLengthLimit),
+ Attributes::factory($attributePerLinkCountLimit, $attributeValueLengthLimit),
+ $eventCountLimit,
+ $linkCountLimit,
+ );
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanProcessor/BatchSpanProcessor.php b/vendor/open-telemetry/sdk/Trace/SpanProcessor/BatchSpanProcessor.php
new file mode 100644
index 000000000..58032749e
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanProcessor/BatchSpanProcessor.php
@@ -0,0 +1,290 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanProcessor;
+
+use function assert;
+use function count;
+use InvalidArgumentException;
+use OpenTelemetry\API\Behavior\LogsMessagesTrait;
+use OpenTelemetry\API\Metrics\MeterProviderInterface;
+use OpenTelemetry\API\Metrics\ObserverInterface;
+use OpenTelemetry\Context\Context;
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Common\Time\ClockInterface;
+use OpenTelemetry\SDK\Trace\ReadableSpanInterface;
+use OpenTelemetry\SDK\Trace\ReadWriteSpanInterface;
+use OpenTelemetry\SDK\Trace\SpanDataInterface;
+use OpenTelemetry\SDK\Trace\SpanExporterInterface;
+use OpenTelemetry\SDK\Trace\SpanProcessorInterface;
+use SplQueue;
+use function sprintf;
+use Throwable;
+
+class BatchSpanProcessor implements SpanProcessorInterface
+{
+ use LogsMessagesTrait;
+
+ public const DEFAULT_SCHEDULE_DELAY = 5000;
+ public const DEFAULT_EXPORT_TIMEOUT = 30000;
+ public const DEFAULT_MAX_QUEUE_SIZE = 2048;
+ public const DEFAULT_MAX_EXPORT_BATCH_SIZE = 512;
+
+ private const ATTRIBUTES_PROCESSOR = ['processor' => 'batching'];
+ private const ATTRIBUTES_QUEUED = self::ATTRIBUTES_PROCESSOR + ['state' => 'queued'];
+ private const ATTRIBUTES_PENDING = self::ATTRIBUTES_PROCESSOR + ['state' => 'pending'];
+ private const ATTRIBUTES_PROCESSED = self::ATTRIBUTES_PROCESSOR + ['state' => 'processed'];
+ private const ATTRIBUTES_DROPPED = self::ATTRIBUTES_PROCESSOR + ['state' => 'dropped'];
+ private const ATTRIBUTES_FREE = self::ATTRIBUTES_PROCESSOR + ['state' => 'free'];
+
+ private SpanExporterInterface $exporter;
+ private ClockInterface $clock;
+ private int $maxQueueSize;
+ private int $scheduledDelayNanos;
+ private int $maxExportBatchSize;
+ private bool $autoFlush;
+ private ContextInterface $exportContext;
+
+ private ?int $nextScheduledRun = null;
+ private bool $running = false;
+ private int $dropped = 0;
+ private int $processed = 0;
+ private int $batchId = 0;
+ private int $queueSize = 0;
+ /** @var list<SpanDataInterface> */
+ private array $batch = [];
+ /** @var SplQueue<list<SpanDataInterface>> */
+ private SplQueue $queue;
+ /** @var SplQueue<array{int, string, ?CancellationInterface, bool, ContextInterface}> */
+ private SplQueue $flush;
+
+ private bool $closed = false;
+
+ public function __construct(
+ SpanExporterInterface $exporter,
+ ClockInterface $clock,
+ int $maxQueueSize = self::DEFAULT_MAX_QUEUE_SIZE,
+ int $scheduledDelayMillis = self::DEFAULT_SCHEDULE_DELAY,
+ int $exportTimeoutMillis = self::DEFAULT_EXPORT_TIMEOUT,
+ int $maxExportBatchSize = self::DEFAULT_MAX_EXPORT_BATCH_SIZE,
+ bool $autoFlush = true,
+ ?MeterProviderInterface $meterProvider = null
+ ) {
+ if ($maxQueueSize <= 0) {
+ throw new InvalidArgumentException(sprintf('Maximum queue size (%d) must be greater than zero', $maxQueueSize));
+ }
+ if ($scheduledDelayMillis <= 0) {
+ throw new InvalidArgumentException(sprintf('Scheduled delay (%d) must be greater than zero', $scheduledDelayMillis));
+ }
+ if ($exportTimeoutMillis <= 0) {
+ throw new InvalidArgumentException(sprintf('Export timeout (%d) must be greater than zero', $exportTimeoutMillis));
+ }
+ if ($maxExportBatchSize <= 0) {
+ throw new InvalidArgumentException(sprintf('Maximum export batch size (%d) must be greater than zero', $maxExportBatchSize));
+ }
+ if ($maxExportBatchSize > $maxQueueSize) {
+ throw new InvalidArgumentException(sprintf('Maximum export batch size (%d) must be less than or equal to maximum queue size (%d)', $maxExportBatchSize, $maxQueueSize));
+ }
+
+ $this->exporter = $exporter;
+ $this->clock = $clock;
+ $this->maxQueueSize = $maxQueueSize;
+ $this->scheduledDelayNanos = $scheduledDelayMillis * 1_000_000;
+ $this->maxExportBatchSize = $maxExportBatchSize;
+ $this->autoFlush = $autoFlush;
+
+ $this->exportContext = Context::getCurrent();
+ $this->queue = new SplQueue();
+ $this->flush = new SplQueue();
+
+ if ($meterProvider === null) {
+ return;
+ }
+
+ $meter = $meterProvider->getMeter('io.opentelemetry.sdk');
+ $meter
+ ->createObservableUpDownCounter(
+ 'otel.trace.span_processor.spans',
+ '{spans}',
+ 'The number of sampled spans received by the span processor',
+ )
+ ->observe(function (ObserverInterface $observer): void {
+ $queued = $this->queue->count() * $this->maxExportBatchSize + count($this->batch);
+ $pending = $this->queueSize - $queued;
+ $processed = $this->processed;
+ $dropped = $this->dropped;
+
+ $observer->observe($queued, self::ATTRIBUTES_QUEUED);
+ $observer->observe($pending, self::ATTRIBUTES_PENDING);
+ $observer->observe($processed, self::ATTRIBUTES_PROCESSED);
+ $observer->observe($dropped, self::ATTRIBUTES_DROPPED);
+ });
+ $meter
+ ->createObservableUpDownCounter(
+ 'otel.trace.span_processor.queue.limit',
+ '{spans}',
+ 'The queue size limit',
+ )
+ ->observe(function (ObserverInterface $observer): void {
+ $observer->observe($this->maxQueueSize, self::ATTRIBUTES_PROCESSOR);
+ });
+ $meter
+ ->createObservableUpDownCounter(
+ 'otel.trace.span_processor.queue.usage',
+ '{spans}',
+ 'The current queue usage',
+ )
+ ->observe(function (ObserverInterface $observer): void {
+ $queued = $this->queue->count() * $this->maxExportBatchSize + count($this->batch);
+ $pending = $this->queueSize - $queued;
+ $free = $this->maxQueueSize - $this->queueSize;
+
+ $observer->observe($queued, self::ATTRIBUTES_QUEUED);
+ $observer->observe($pending, self::ATTRIBUTES_PENDING);
+ $observer->observe($free, self::ATTRIBUTES_FREE);
+ });
+ }
+
+ public function onStart(ReadWriteSpanInterface $span, ContextInterface $parentContext): void
+ {
+ }
+
+ public function onEnd(ReadableSpanInterface $span): void
+ {
+ if ($this->closed) {
+ return;
+ }
+ if (!$span->getContext()->isSampled()) {
+ return;
+ }
+
+ if ($this->queueSize === $this->maxQueueSize) {
+ $this->dropped++;
+
+ return;
+ }
+
+ $this->queueSize++;
+ $this->batch[] = $span->toSpanData();
+ $this->nextScheduledRun ??= $this->clock->now() + $this->scheduledDelayNanos;
+
+ if (count($this->batch) === $this->maxExportBatchSize) {
+ $this->enqueueBatch();
+ }
+ if ($this->autoFlush) {
+ $this->flush();
+ }
+ }
+
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ if ($this->closed) {
+ return false;
+ }
+
+ return $this->flush(__FUNCTION__, $cancellation);
+ }
+
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ if ($this->closed) {
+ return false;
+ }
+
+ $this->closed = true;
+
+ return $this->flush(__FUNCTION__, $cancellation);
+ }
+
+ public static function builder(SpanExporterInterface $exporter): BatchSpanProcessorBuilder
+ {
+ return new BatchSpanProcessorBuilder($exporter);
+ }
+
+ private function flush(?string $flushMethod = null, ?CancellationInterface $cancellation = null): bool
+ {
+ if ($flushMethod !== null) {
+ $flushId = $this->batchId + $this->queue->count() + (int) (bool) $this->batch;
+ $this->flush->enqueue([$flushId, $flushMethod, $cancellation, !$this->running, Context::getCurrent()]);
+ }
+
+ if ($this->running) {
+ return false;
+ }
+
+ $success = true;
+ $exception = null;
+ $this->running = true;
+
+ try {
+ for (;;) {
+ while (!$this->flush->isEmpty() && $this->flush->bottom()[0] <= $this->batchId) {
+ [, $flushMethod, $cancellation, $propagateResult, $context] = $this->flush->dequeue();
+ $scope = $context->activate();
+
+ try {
+ $result = $this->exporter->$flushMethod($cancellation);
+ if ($propagateResult) {
+ $success = $result;
+ }
+ } catch (Throwable $e) {
+ if ($propagateResult) {
+ $exception = $e;
+ } else {
+ self::logError(sprintf('Unhandled %s error', $flushMethod), ['exception' => $e]);
+ }
+ } finally {
+ $scope->detach();
+ }
+ }
+
+ if (!$this->shouldFlush()) {
+ break;
+ }
+
+ if ($this->queue->isEmpty()) {
+ $this->enqueueBatch();
+ }
+ $batchSize = count($this->queue->bottom());
+ $this->batchId++;
+ $scope = $this->exportContext->activate();
+
+ try {
+ $this->exporter->export($this->queue->dequeue())->await();
+ } catch (Throwable $e) {
+ self::logError('Unhandled export error', ['exception' => $e]);
+ } finally {
+ $this->processed += $batchSize;
+ $this->queueSize -= $batchSize;
+ $scope->detach();
+ }
+ }
+ } finally {
+ $this->running = false;
+ }
+
+ if ($exception !== null) {
+ throw $exception;
+ }
+
+ return $success;
+ }
+
+ private function shouldFlush(): bool
+ {
+ return !$this->flush->isEmpty()
+ || $this->autoFlush && !$this->queue->isEmpty()
+ || $this->autoFlush && $this->nextScheduledRun !== null && $this->clock->now() > $this->nextScheduledRun;
+ }
+
+ private function enqueueBatch(): void
+ {
+ assert($this->batch !== []);
+
+ $this->queue->enqueue($this->batch);
+ $this->batch = [];
+ $this->nextScheduledRun = null;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanProcessor/BatchSpanProcessorBuilder.php b/vendor/open-telemetry/sdk/Trace/SpanProcessor/BatchSpanProcessorBuilder.php
new file mode 100644
index 000000000..8e81e7dd6
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanProcessor/BatchSpanProcessorBuilder.php
@@ -0,0 +1,41 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanProcessor;
+
+use OpenTelemetry\SDK\Common\Time\ClockFactory;
+use OpenTelemetry\SDK\Metrics\MeterProviderInterface;
+use OpenTelemetry\SDK\Trace\SpanExporterInterface;
+
+class BatchSpanProcessorBuilder
+{
+ private SpanExporterInterface $exporter;
+ private ?MeterProviderInterface $meterProvider = null;
+
+ public function __construct(SpanExporterInterface $exporter)
+ {
+ $this->exporter = $exporter;
+ }
+
+ public function setMeterProvider(MeterProviderInterface $meterProvider): self
+ {
+ $this->meterProvider = $meterProvider;
+
+ return $this;
+ }
+
+ public function build(): BatchSpanProcessor
+ {
+ return new BatchSpanProcessor(
+ $this->exporter,
+ ClockFactory::getDefault(),
+ BatchSpanProcessor::DEFAULT_MAX_QUEUE_SIZE,
+ BatchSpanProcessor::DEFAULT_SCHEDULE_DELAY,
+ BatchSpanProcessor::DEFAULT_EXPORT_TIMEOUT,
+ BatchSpanProcessor::DEFAULT_MAX_EXPORT_BATCH_SIZE,
+ true,
+ $this->meterProvider
+ );
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanProcessor/MultiSpanProcessor.php b/vendor/open-telemetry/sdk/Trace/SpanProcessor/MultiSpanProcessor.php
new file mode 100644
index 000000000..e690791f2
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanProcessor/MultiSpanProcessor.php
@@ -0,0 +1,79 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanProcessor;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Trace\ReadableSpanInterface;
+use OpenTelemetry\SDK\Trace\ReadWriteSpanInterface;
+use OpenTelemetry\SDK\Trace\SpanProcessorInterface;
+
+/**
+ * Class SpanMultiProcessor is a SpanProcessor that forwards all events to an
+ * array of SpanProcessors.
+ */
+final class MultiSpanProcessor implements SpanProcessorInterface
+{
+ /** @var list<SpanProcessorInterface> */
+ private array $processors = [];
+
+ public function __construct(SpanProcessorInterface ...$spanProcessors)
+ {
+ foreach ($spanProcessors as $processor) {
+ $this->addSpanProcessor($processor);
+ }
+ }
+
+ public function addSpanProcessor(SpanProcessorInterface $processor): void
+ {
+ $this->processors[] = $processor;
+ }
+
+ /** @return list<SpanProcessorInterface> */
+ public function getSpanProcessors(): array
+ {
+ return $this->processors;
+ }
+
+ /** @inheritDoc */
+ public function onStart(ReadWriteSpanInterface $span, ContextInterface $parentContext): void
+ {
+ foreach ($this->processors as $processor) {
+ $processor->onStart($span, $parentContext);
+ }
+ }
+
+ /** @inheritDoc */
+ public function onEnd(ReadableSpanInterface $span): void
+ {
+ foreach ($this->processors as $processor) {
+ $processor->onEnd($span);
+ }
+ }
+
+ /** @inheritDoc */
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ $result = true;
+
+ foreach ($this->processors as $processor) {
+ $result = $result && $processor->shutdown();
+ }
+
+ return $result;
+ }
+
+ /** @inheritDoc */
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ $result = true;
+
+ foreach ($this->processors as $processor) {
+ $result = $result && $processor->forceFlush();
+ }
+
+ return $result;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanProcessor/NoopSpanProcessor.php b/vendor/open-telemetry/sdk/Trace/SpanProcessor/NoopSpanProcessor.php
new file mode 100644
index 000000000..9c4d1eabe
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanProcessor/NoopSpanProcessor.php
@@ -0,0 +1,47 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanProcessor;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Trace\ReadableSpanInterface;
+use OpenTelemetry\SDK\Trace\ReadWriteSpanInterface;
+use OpenTelemetry\SDK\Trace\SpanProcessorInterface;
+
+class NoopSpanProcessor implements SpanProcessorInterface
+{
+ private static ?SpanProcessorInterface $instance = null;
+
+ public static function getInstance(): SpanProcessorInterface
+ {
+ if (null === self::$instance) {
+ self::$instance = new self();
+ }
+
+ return self::$instance;
+ }
+
+ /** @inheritDoc */
+ public function onStart(ReadWriteSpanInterface $span, ContextInterface $parentContext): void
+ {
+ } //@codeCoverageIgnore
+
+ /** @inheritDoc */
+ public function onEnd(ReadableSpanInterface $span): void
+ {
+ } //@codeCoverageIgnore
+
+ /** @inheritDoc */
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ return true;
+ }
+
+ /** @inheritDoc */
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ return $this->forceFlush();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanProcessor/SimpleSpanProcessor.php b/vendor/open-telemetry/sdk/Trace/SpanProcessor/SimpleSpanProcessor.php
new file mode 100644
index 000000000..4e86e79ab
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanProcessor/SimpleSpanProcessor.php
@@ -0,0 +1,120 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanProcessor;
+
+use Closure;
+use OpenTelemetry\API\Behavior\LogsMessagesTrait;
+use OpenTelemetry\Context\Context;
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Trace\ReadableSpanInterface;
+use OpenTelemetry\SDK\Trace\ReadWriteSpanInterface;
+use OpenTelemetry\SDK\Trace\SpanExporterInterface;
+use OpenTelemetry\SDK\Trace\SpanProcessorInterface;
+use SplQueue;
+use function sprintf;
+use Throwable;
+
+class SimpleSpanProcessor implements SpanProcessorInterface
+{
+ use LogsMessagesTrait;
+
+ private SpanExporterInterface $exporter;
+ private ContextInterface $exportContext;
+
+ private bool $running = false;
+ /** @var SplQueue<array{Closure, string, bool, ContextInterface}> */
+ private SplQueue $queue;
+
+ private bool $closed = false;
+
+ public function __construct(SpanExporterInterface $exporter)
+ {
+ $this->exporter = $exporter;
+
+ $this->exportContext = Context::getCurrent();
+ $this->queue = new SplQueue();
+ }
+
+ public function onStart(ReadWriteSpanInterface $span, ContextInterface $parentContext): void
+ {
+ }
+
+ public function onEnd(ReadableSpanInterface $span): void
+ {
+ if ($this->closed) {
+ return;
+ }
+ if (!$span->getContext()->isSampled()) {
+ return;
+ }
+
+ $spanData = $span->toSpanData();
+ $this->flush(fn () => $this->exporter->export([$spanData])->await(), 'export', false, $this->exportContext);
+ }
+
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ if ($this->closed) {
+ return false;
+ }
+
+ return $this->flush(fn (): bool => $this->exporter->forceFlush($cancellation), __FUNCTION__, true, Context::getCurrent());
+ }
+
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ if ($this->closed) {
+ return false;
+ }
+
+ $this->closed = true;
+
+ return $this->flush(fn (): bool => $this->exporter->shutdown($cancellation), __FUNCTION__, true, Context::getCurrent());
+ }
+
+ private function flush(Closure $task, string $taskName, bool $propagateResult, ContextInterface $context): bool
+ {
+ $this->queue->enqueue([$task, $taskName, $propagateResult && !$this->running, $context]);
+
+ if ($this->running) {
+ return false;
+ }
+
+ $success = true;
+ $exception = null;
+ $this->running = true;
+
+ try {
+ while (!$this->queue->isEmpty()) {
+ [$task, $taskName, $propagateResult, $context] = $this->queue->dequeue();
+ $scope = $context->activate();
+
+ try {
+ $result = $task();
+ if ($propagateResult) {
+ $success = $result;
+ }
+ } catch (Throwable $e) {
+ if ($propagateResult) {
+ $exception = $e;
+ } else {
+ self::logError(sprintf('Unhandled %s error', $taskName), ['exception' => $e]);
+ }
+ } finally {
+ $scope->detach();
+ }
+ }
+ } finally {
+ $this->running = false;
+ }
+
+ if ($exception !== null) {
+ throw $exception;
+ }
+
+ return $success;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanProcessorFactory.php b/vendor/open-telemetry/sdk/Trace/SpanProcessorFactory.php
new file mode 100644
index 000000000..39144cdf6
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanProcessorFactory.php
@@ -0,0 +1,48 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use InvalidArgumentException;
+use OpenTelemetry\SDK\Common\Configuration\Configuration;
+use OpenTelemetry\SDK\Common\Configuration\KnownValues as Values;
+use OpenTelemetry\SDK\Common\Configuration\Variables as Env;
+use OpenTelemetry\SDK\Common\Time\ClockFactory;
+use OpenTelemetry\SDK\Metrics\MeterProviderInterface;
+use OpenTelemetry\SDK\Metrics\NoopMeterProvider;
+use OpenTelemetry\SDK\Trace\SpanProcessor\BatchSpanProcessor;
+use OpenTelemetry\SDK\Trace\SpanProcessor\NoopSpanProcessor;
+use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
+
+class SpanProcessorFactory
+{
+ public function create(?SpanExporterInterface $exporter = null, ?MeterProviderInterface $meterProvider = null): SpanProcessorInterface
+ {
+ if ($exporter === null) {
+ return new NoopSpanProcessor();
+ }
+
+ $name = Configuration::getEnum(Env::OTEL_PHP_TRACES_PROCESSOR);
+ switch ($name) {
+ case Values::VALUE_BATCH:
+ return new BatchSpanProcessor(
+ $exporter,
+ ClockFactory::getDefault(),
+ Configuration::getInt(Env::OTEL_BSP_MAX_QUEUE_SIZE, BatchSpanProcessor::DEFAULT_MAX_QUEUE_SIZE),
+ Configuration::getInt(Env::OTEL_BSP_SCHEDULE_DELAY, BatchSpanProcessor::DEFAULT_SCHEDULE_DELAY),
+ Configuration::getInt(Env::OTEL_BSP_EXPORT_TIMEOUT, BatchSpanProcessor::DEFAULT_EXPORT_TIMEOUT),
+ Configuration::getInt(Env::OTEL_BSP_MAX_EXPORT_BATCH_SIZE, BatchSpanProcessor::DEFAULT_MAX_EXPORT_BATCH_SIZE),
+ true, //autoflush
+ $meterProvider ?? new NoopMeterProvider(),
+ );
+ case Values::VALUE_SIMPLE:
+ return new SimpleSpanProcessor($exporter);
+ case Values::VALUE_NOOP:
+ case Values::VALUE_NONE:
+ return NoopSpanProcessor::getInstance();
+ default:
+ throw new InvalidArgumentException('Unknown processor: ' . $name);
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanProcessorInterface.php b/vendor/open-telemetry/sdk/Trace/SpanProcessorInterface.php
new file mode 100644
index 000000000..24bcea2dd
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanProcessorInterface.php
@@ -0,0 +1,38 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+
+/** @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.1/specification/trace/sdk.md#span-processor */
+interface SpanProcessorInterface
+{
+ /**
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/specification/trace/sdk.md#onstart
+ */
+ public function onStart(ReadWriteSpanInterface $span, ContextInterface $parentContext): void;
+
+ /**
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/specification/trace/sdk.md#onendspan
+ */
+ public function onEnd(ReadableSpanInterface $span): void;
+
+ /**
+ * Export all ended spans to the configured Exporter that have not yet been exported.
+ * Returns `true` if the flush was successful, otherwise `false`.
+ *
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/specification/trace/sdk.md#forceflush-1
+ */
+ public function forceFlush(?CancellationInterface $cancellation = null): bool;
+
+ /**
+ * Cleanup; after shutdown, calling onStart, onEnd, or forceFlush is invalid
+ * Returns `false` is the processor is already shutdown, otherwise `true`.
+ *
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/specification/trace/sdk.md#shutdown-1
+ */
+ public function shutdown(?CancellationInterface $cancellation = null): bool;
+}
diff --git a/vendor/open-telemetry/sdk/Trace/StatusData.php b/vendor/open-telemetry/sdk/Trace/StatusData.php
new file mode 100644
index 000000000..c28ea22ab
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/StatusData.php
@@ -0,0 +1,84 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\API\Trace as API;
+
+final class StatusData implements StatusDataInterface
+{
+ private static ?self $ok = null;
+ private static ?self $unset = null;
+ private static ?self $error = null;
+ private string $code;
+ private string $description;
+
+ /** @psalm-param API\StatusCode::STATUS_* $code */
+ public function __construct(
+ string $code,
+ string $description
+ ) {
+ $this->code = $code;
+ $this->description = $description;
+ }
+
+ /** @psalm-param API\StatusCode::STATUS_* $code */
+ public static function create(string $code, ?string $description = null): self
+ {
+ if (empty($description)) {
+ switch ($code) {
+ case API\StatusCode::STATUS_UNSET:
+ return self::unset();
+ case API\StatusCode::STATUS_ERROR:
+ return self::error();
+ case API\StatusCode::STATUS_OK:
+ return self::ok();
+ }
+ }
+
+ // Ignore description for non Error statuses.
+ if (API\StatusCode::STATUS_ERROR !== $code) {
+ $description = '';
+ }
+
+ return new self($code, $description); /** @phan-suppress-current-line PhanTypeMismatchArgumentNullable */
+ }
+
+ public static function ok(): self
+ {
+ if (null === self::$ok) {
+ self::$ok = new self(API\StatusCode::STATUS_OK, '');
+ }
+
+ return self::$ok;
+ }
+
+ public static function error(): self
+ {
+ if (null === self::$error) {
+ self::$error = new self(API\StatusCode::STATUS_ERROR, '');
+ }
+
+ return self::$error;
+ }
+
+ public static function unset(): self
+ {
+ if (null === self::$unset) {
+ self::$unset = new self(API\StatusCode::STATUS_UNSET, '');
+ }
+
+ return self::$unset;
+ }
+
+ public function getCode(): string
+ {
+ return $this->code;
+ }
+
+ public function getDescription(): string
+ {
+ return $this->description;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/StatusDataInterface.php b/vendor/open-telemetry/sdk/Trace/StatusDataInterface.php
new file mode 100644
index 000000000..973d2b519
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/StatusDataInterface.php
@@ -0,0 +1,18 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+interface StatusDataInterface
+{
+ public static function ok(): self;
+
+ public static function error(): self;
+
+ public static function unset(): self;
+
+ public function getCode(): string;
+
+ public function getDescription(): string;
+}
diff --git a/vendor/open-telemetry/sdk/Trace/Tracer.php b/vendor/open-telemetry/sdk/Trace/Tracer.php
new file mode 100644
index 000000000..913773f60
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/Tracer.php
@@ -0,0 +1,52 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use function ctype_space;
+use OpenTelemetry\API\Trace as API;
+use OpenTelemetry\Context\Context;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+
+class Tracer implements API\TracerInterface
+{
+ public const FALLBACK_SPAN_NAME = 'empty';
+
+ /** @readonly */
+ private TracerSharedState $tracerSharedState;
+
+ /** @readonly */
+ private InstrumentationScopeInterface $instrumentationScope;
+
+ public function __construct(
+ TracerSharedState $tracerSharedState,
+ InstrumentationScopeInterface $instrumentationScope
+ ) {
+ $this->tracerSharedState = $tracerSharedState;
+ $this->instrumentationScope = $instrumentationScope;
+ }
+
+ /** @inheritDoc */
+ public function spanBuilder(string $spanName): API\SpanBuilderInterface
+ {
+ if (ctype_space($spanName)) {
+ $spanName = self::FALLBACK_SPAN_NAME;
+ }
+
+ if ($this->tracerSharedState->hasShutdown()) {
+ return new API\NoopSpanBuilder(Context::storage());
+ }
+
+ return new SpanBuilder(
+ $spanName,
+ $this->instrumentationScope,
+ $this->tracerSharedState,
+ );
+ }
+
+ public function getInstrumentationScope(): InstrumentationScopeInterface
+ {
+ return $this->instrumentationScope;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/TracerProvider.php b/vendor/open-telemetry/sdk/Trace/TracerProvider.php
new file mode 100644
index 000000000..fdae4aea2
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/TracerProvider.php
@@ -0,0 +1,99 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use function is_array;
+use OpenTelemetry\API\Trace as API;
+use OpenTelemetry\API\Trace\NoopTracer;
+use OpenTelemetry\SDK\Common\Attribute\Attributes;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeFactory;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeFactoryInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+use OpenTelemetry\SDK\Resource\ResourceInfoFactory;
+use OpenTelemetry\SDK\Trace\Sampler\AlwaysOnSampler;
+use OpenTelemetry\SDK\Trace\Sampler\ParentBased;
+
+final class TracerProvider implements TracerProviderInterface
+{
+ /** @readonly */
+ private TracerSharedState $tracerSharedState;
+ private InstrumentationScopeFactoryInterface $instrumentationScopeFactory;
+
+ /** @param list<SpanProcessorInterface>|SpanProcessorInterface|null $spanProcessors */
+ public function __construct(
+ $spanProcessors = [],
+ SamplerInterface $sampler = null,
+ ResourceInfo $resource = null,
+ SpanLimits $spanLimits = null,
+ IdGeneratorInterface $idGenerator = null,
+ ?InstrumentationScopeFactoryInterface $instrumentationScopeFactory = null
+ ) {
+ if (null === $spanProcessors) {
+ $spanProcessors = [];
+ }
+
+ $spanProcessors = is_array($spanProcessors) ? $spanProcessors : [$spanProcessors];
+ $resource ??= ResourceInfoFactory::defaultResource();
+ $sampler ??= new ParentBased(new AlwaysOnSampler());
+ $idGenerator ??= new RandomIdGenerator();
+ $spanLimits ??= (new SpanLimitsBuilder())->build();
+
+ $this->tracerSharedState = new TracerSharedState(
+ $idGenerator,
+ $resource,
+ $spanLimits,
+ $sampler,
+ $spanProcessors
+ );
+ $this->instrumentationScopeFactory = $instrumentationScopeFactory ?? new InstrumentationScopeFactory(Attributes::factory());
+ }
+
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ return $this->tracerSharedState->getSpanProcessor()->forceFlush($cancellation);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getTracer(
+ string $name,
+ ?string $version = null,
+ ?string $schemaUrl = null,
+ iterable $attributes = []
+ ): API\TracerInterface {
+ if ($this->tracerSharedState->hasShutdown()) {
+ return NoopTracer::getInstance();
+ }
+
+ return new Tracer(
+ $this->tracerSharedState,
+ $this->instrumentationScopeFactory->create($name, $version, $schemaUrl, $attributes),
+ );
+ }
+
+ public function getSampler(): SamplerInterface
+ {
+ return $this->tracerSharedState->getSampler();
+ }
+
+ /**
+ * Returns `false` is the provider is already shutdown, otherwise `true`.
+ */
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ if ($this->tracerSharedState->hasShutdown()) {
+ return true;
+ }
+
+ return $this->tracerSharedState->shutdown($cancellation);
+ }
+
+ public static function builder(): TracerProviderBuilder
+ {
+ return new TracerProviderBuilder();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/TracerProviderBuilder.php b/vendor/open-telemetry/sdk/Trace/TracerProviderBuilder.php
new file mode 100644
index 000000000..8dcfdc700
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/TracerProviderBuilder.php
@@ -0,0 +1,45 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+
+class TracerProviderBuilder
+{
+ // @var array<SpanProcessorInterface>
+ private ?array $spanProcessors = [];
+ private ?ResourceInfo $resource = null;
+ private ?SamplerInterface $sampler = null;
+
+ public function addSpanProcessor(SpanProcessorInterface $spanProcessor): self
+ {
+ $this->spanProcessors[] = $spanProcessor;
+
+ return $this;
+ }
+
+ public function setResource(ResourceInfo $resource): self
+ {
+ $this->resource = $resource;
+
+ return $this;
+ }
+
+ public function setSampler(SamplerInterface $sampler): self
+ {
+ $this->sampler = $sampler;
+
+ return $this;
+ }
+
+ public function build(): TracerProviderInterface
+ {
+ return new TracerProvider(
+ $this->spanProcessors,
+ $this->sampler,
+ $this->resource,
+ );
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/TracerProviderFactory.php b/vendor/open-telemetry/sdk/Trace/TracerProviderFactory.php
new file mode 100644
index 000000000..a545319b6
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/TracerProviderFactory.php
@@ -0,0 +1,60 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\API\Behavior\LogsMessagesTrait;
+use OpenTelemetry\SDK\Sdk;
+
+final class TracerProviderFactory
+{
+ use LogsMessagesTrait;
+
+ private ExporterFactory $exporterFactory;
+ private SamplerFactory $samplerFactory;
+ private SpanProcessorFactory $spanProcessorFactory;
+
+ public function __construct(
+ ?ExporterFactory $exporterFactory = null,
+ ?SamplerFactory $samplerFactory = null,
+ ?SpanProcessorFactory $spanProcessorFactory = null
+ ) {
+ $this->exporterFactory = $exporterFactory ?: new ExporterFactory();
+ $this->samplerFactory = $samplerFactory ?: new SamplerFactory();
+ $this->spanProcessorFactory = $spanProcessorFactory ?: new SpanProcessorFactory();
+ }
+
+ public function create(): TracerProviderInterface
+ {
+ if (Sdk::isDisabled()) {
+ return new NoopTracerProvider();
+ }
+
+ try {
+ $exporter = $this->exporterFactory->create();
+ } catch (\Throwable $t) {
+ self::logWarning('Unable to create exporter', ['exception' => $t]);
+ $exporter = null;
+ }
+
+ try {
+ $sampler = $this->samplerFactory->create();
+ } catch (\Throwable $t) {
+ self::logWarning('Unable to create sampler', ['exception' => $t]);
+ $sampler = null;
+ }
+
+ try {
+ $spanProcessor = $this->spanProcessorFactory->create($exporter);
+ } catch (\Throwable $t) {
+ self::logWarning('Unable to create span processor', ['exception' => $t]);
+ $spanProcessor = null;
+ }
+
+ return new TracerProvider(
+ $spanProcessor,
+ $sampler,
+ );
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/TracerProviderInterface.php b/vendor/open-telemetry/sdk/Trace/TracerProviderInterface.php
new file mode 100644
index 000000000..d61c1ea8f
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/TracerProviderInterface.php
@@ -0,0 +1,15 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\API\Trace as API;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+
+interface TracerProviderInterface extends API\TracerProviderInterface
+{
+ public function forceFlush(?CancellationInterface $cancellation = null): bool;
+
+ public function shutdown(?CancellationInterface $cancellation = null): bool;
+}
diff --git a/vendor/open-telemetry/sdk/Trace/TracerSharedState.php b/vendor/open-telemetry/sdk/Trace/TracerSharedState.php
new file mode 100644
index 000000000..d0540cc1f
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/TracerSharedState.php
@@ -0,0 +1,100 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\API\Trace as API; /** @phan-suppress-current-line PhanUnreferencedUseNormal */
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+use OpenTelemetry\SDK\Trace\SpanProcessor\MultiSpanProcessor;
+use OpenTelemetry\SDK\Trace\SpanProcessor\NoopSpanProcessor;
+
+/**
+ * Stores shared state/config between all {@see API\TracerInterface} created via the same {@see API\TracerProviderInterface}.
+ */
+final class TracerSharedState
+{
+ /** @readonly */
+ private IdGeneratorInterface $idGenerator;
+
+ /** @readonly */
+ private ResourceInfo $resource;
+
+ /** @readonly */
+ private SpanLimits $spanLimits;
+
+ /** @readonly */
+ private SamplerInterface $sampler;
+
+ /** @readonly */
+ private SpanProcessorInterface $spanProcessor;
+
+ private ?bool $shutdownResult = null;
+
+ public function __construct(
+ IdGeneratorInterface $idGenerator,
+ ResourceInfo $resource,
+ SpanLimits $spanLimits,
+ SamplerInterface $sampler,
+ array $spanProcessors
+ ) {
+ $this->idGenerator = $idGenerator;
+ $this->resource = $resource;
+ $this->spanLimits = $spanLimits;
+ $this->sampler = $sampler;
+
+ switch (count($spanProcessors)) {
+ case 0:
+ $this->spanProcessor = NoopSpanProcessor::getInstance();
+
+ break;
+ case 1:
+ $this->spanProcessor = $spanProcessors[0];
+
+ break;
+ default:
+ $this->spanProcessor = new MultiSpanProcessor(...$spanProcessors);
+
+ break;
+ }
+ }
+
+ public function hasShutdown(): bool
+ {
+ return null !== $this->shutdownResult;
+ }
+
+ public function getIdGenerator(): IdGeneratorInterface
+ {
+ return $this->idGenerator;
+ }
+
+ public function getResource(): ResourceInfo
+ {
+ return $this->resource;
+ }
+
+ public function getSpanLimits(): SpanLimits
+ {
+ return $this->spanLimits;
+ }
+
+ public function getSampler(): SamplerInterface
+ {
+ return $this->sampler;
+ }
+
+ public function getSpanProcessor(): SpanProcessorInterface
+ {
+ return $this->spanProcessor;
+ }
+
+ /**
+ * Returns `false` is the provider is already shutdown, otherwise `true`.
+ */
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ return $this->shutdownResult ?? ($this->shutdownResult = $this->spanProcessor->shutdown($cancellation));
+ }
+}