From cdd7ad020e165fe680703b6d3319b908b682fb7a Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Fri, 20 Oct 2023 17:12:29 +0300 Subject: jaeger-client -> opentelemetry --- .../sdk/Trace/Behavior/LoggerAwareTrait.php | 48 +++ .../Trace/Behavior/SpanExporterDecoratorTrait.php | 47 +++ .../sdk/Trace/Behavior/SpanExporterTrait.php | 47 +++ .../sdk/Trace/Behavior/UsesSpanConverterTrait.php | 41 +++ vendor/open-telemetry/sdk/Trace/Event.php | 47 +++ vendor/open-telemetry/sdk/Trace/EventInterface.php | 15 + .../open-telemetry/sdk/Trace/ExporterFactory.php | 32 ++ .../sdk/Trace/IdGeneratorInterface.php | 12 + vendor/open-telemetry/sdk/Trace/ImmutableSpan.php | 153 +++++++++ vendor/open-telemetry/sdk/Trace/Link.php | 30 ++ vendor/open-telemetry/sdk/Trace/LinkInterface.php | 14 + .../sdk/Trace/NoopTracerProvider.php | 21 ++ .../open-telemetry/sdk/Trace/RandomIdGenerator.php | 49 +++ .../sdk/Trace/ReadWriteSpanInterface.php | 11 + .../sdk/Trace/ReadableSpanInterface.php | 48 +++ .../sdk/Trace/Sampler/AlwaysOffSampler.php | 50 +++ .../sdk/Trace/Sampler/AlwaysOnSampler.php | 50 +++ .../sdk/Trace/Sampler/ParentBased.php | 100 ++++++ .../sdk/Trace/Sampler/TraceIdRatioBasedSampler.php | 70 ++++ vendor/open-telemetry/sdk/Trace/SamplerFactory.php | 48 +++ .../open-telemetry/sdk/Trace/SamplerInterface.php | 46 +++ vendor/open-telemetry/sdk/Trace/SamplingResult.php | 71 ++++ vendor/open-telemetry/sdk/Trace/Span.php | 359 +++++++++++++++++++++ vendor/open-telemetry/sdk/Trace/SpanBuilder.php | 191 +++++++++++ .../sdk/Trace/SpanConverterInterface.php | 10 + .../open-telemetry/sdk/Trace/SpanDataInterface.php | 46 +++ .../sdk/Trace/SpanExporter/AbstractDecorator.php | 12 + .../sdk/Trace/SpanExporter/ConsoleSpanExporter.php | 57 ++++ .../SpanExporter/ConsoleSpanExporterFactory.php | 18 ++ .../Trace/SpanExporter/FriendlySpanConverter.php | 173 ++++++++++ .../sdk/Trace/SpanExporter/InMemoryExporter.php | 40 +++ .../SpanExporter/InMemorySpanExporterFactory.php | 15 + .../sdk/Trace/SpanExporter/LoggerDecorator.php | 58 ++++ .../sdk/Trace/SpanExporter/LoggerExporter.php | 96 ++++++ .../sdk/Trace/SpanExporter/NullSpanConverter.php | 15 + .../SpanExporter/SpanExporterFactoryInterface.php | 12 + .../sdk/Trace/SpanExporter/_register.php | 7 + .../sdk/Trace/SpanExporterInterface.php | 29 ++ vendor/open-telemetry/sdk/Trace/SpanLimits.php | 67 ++++ .../open-telemetry/sdk/Trace/SpanLimitsBuilder.php | 148 +++++++++ .../sdk/Trace/SpanProcessor/BatchSpanProcessor.php | 290 +++++++++++++++++ .../SpanProcessor/BatchSpanProcessorBuilder.php | 41 +++ .../sdk/Trace/SpanProcessor/MultiSpanProcessor.php | 79 +++++ .../sdk/Trace/SpanProcessor/NoopSpanProcessor.php | 47 +++ .../Trace/SpanProcessor/SimpleSpanProcessor.php | 120 +++++++ .../sdk/Trace/SpanProcessorFactory.php | 48 +++ .../sdk/Trace/SpanProcessorInterface.php | 38 +++ vendor/open-telemetry/sdk/Trace/StatusData.php | 84 +++++ .../sdk/Trace/StatusDataInterface.php | 18 ++ vendor/open-telemetry/sdk/Trace/Tracer.php | 52 +++ vendor/open-telemetry/sdk/Trace/TracerProvider.php | 99 ++++++ .../sdk/Trace/TracerProviderBuilder.php | 45 +++ .../sdk/Trace/TracerProviderFactory.php | 60 ++++ .../sdk/Trace/TracerProviderInterface.php | 15 + .../open-telemetry/sdk/Trace/TracerSharedState.php | 100 ++++++ 55 files changed, 3539 insertions(+) create mode 100644 vendor/open-telemetry/sdk/Trace/Behavior/LoggerAwareTrait.php create mode 100644 vendor/open-telemetry/sdk/Trace/Behavior/SpanExporterDecoratorTrait.php create mode 100644 vendor/open-telemetry/sdk/Trace/Behavior/SpanExporterTrait.php create mode 100644 vendor/open-telemetry/sdk/Trace/Behavior/UsesSpanConverterTrait.php create mode 100644 vendor/open-telemetry/sdk/Trace/Event.php create mode 100644 vendor/open-telemetry/sdk/Trace/EventInterface.php create mode 100644 vendor/open-telemetry/sdk/Trace/ExporterFactory.php create mode 100644 vendor/open-telemetry/sdk/Trace/IdGeneratorInterface.php create mode 100644 vendor/open-telemetry/sdk/Trace/ImmutableSpan.php create mode 100644 vendor/open-telemetry/sdk/Trace/Link.php create mode 100644 vendor/open-telemetry/sdk/Trace/LinkInterface.php create mode 100644 vendor/open-telemetry/sdk/Trace/NoopTracerProvider.php create mode 100644 vendor/open-telemetry/sdk/Trace/RandomIdGenerator.php create mode 100644 vendor/open-telemetry/sdk/Trace/ReadWriteSpanInterface.php create mode 100644 vendor/open-telemetry/sdk/Trace/ReadableSpanInterface.php create mode 100644 vendor/open-telemetry/sdk/Trace/Sampler/AlwaysOffSampler.php create mode 100644 vendor/open-telemetry/sdk/Trace/Sampler/AlwaysOnSampler.php create mode 100644 vendor/open-telemetry/sdk/Trace/Sampler/ParentBased.php create mode 100644 vendor/open-telemetry/sdk/Trace/Sampler/TraceIdRatioBasedSampler.php create mode 100644 vendor/open-telemetry/sdk/Trace/SamplerFactory.php create mode 100644 vendor/open-telemetry/sdk/Trace/SamplerInterface.php create mode 100644 vendor/open-telemetry/sdk/Trace/SamplingResult.php create mode 100644 vendor/open-telemetry/sdk/Trace/Span.php create mode 100644 vendor/open-telemetry/sdk/Trace/SpanBuilder.php create mode 100644 vendor/open-telemetry/sdk/Trace/SpanConverterInterface.php create mode 100644 vendor/open-telemetry/sdk/Trace/SpanDataInterface.php create mode 100644 vendor/open-telemetry/sdk/Trace/SpanExporter/AbstractDecorator.php create mode 100644 vendor/open-telemetry/sdk/Trace/SpanExporter/ConsoleSpanExporter.php create mode 100644 vendor/open-telemetry/sdk/Trace/SpanExporter/ConsoleSpanExporterFactory.php create mode 100644 vendor/open-telemetry/sdk/Trace/SpanExporter/FriendlySpanConverter.php create mode 100644 vendor/open-telemetry/sdk/Trace/SpanExporter/InMemoryExporter.php create mode 100644 vendor/open-telemetry/sdk/Trace/SpanExporter/InMemorySpanExporterFactory.php create mode 100644 vendor/open-telemetry/sdk/Trace/SpanExporter/LoggerDecorator.php create mode 100644 vendor/open-telemetry/sdk/Trace/SpanExporter/LoggerExporter.php create mode 100644 vendor/open-telemetry/sdk/Trace/SpanExporter/NullSpanConverter.php create mode 100644 vendor/open-telemetry/sdk/Trace/SpanExporter/SpanExporterFactoryInterface.php create mode 100644 vendor/open-telemetry/sdk/Trace/SpanExporter/_register.php create mode 100644 vendor/open-telemetry/sdk/Trace/SpanExporterInterface.php create mode 100644 vendor/open-telemetry/sdk/Trace/SpanLimits.php create mode 100644 vendor/open-telemetry/sdk/Trace/SpanLimitsBuilder.php create mode 100644 vendor/open-telemetry/sdk/Trace/SpanProcessor/BatchSpanProcessor.php create mode 100644 vendor/open-telemetry/sdk/Trace/SpanProcessor/BatchSpanProcessorBuilder.php create mode 100644 vendor/open-telemetry/sdk/Trace/SpanProcessor/MultiSpanProcessor.php create mode 100644 vendor/open-telemetry/sdk/Trace/SpanProcessor/NoopSpanProcessor.php create mode 100644 vendor/open-telemetry/sdk/Trace/SpanProcessor/SimpleSpanProcessor.php create mode 100644 vendor/open-telemetry/sdk/Trace/SpanProcessorFactory.php create mode 100644 vendor/open-telemetry/sdk/Trace/SpanProcessorInterface.php create mode 100644 vendor/open-telemetry/sdk/Trace/StatusData.php create mode 100644 vendor/open-telemetry/sdk/Trace/StatusDataInterface.php create mode 100644 vendor/open-telemetry/sdk/Trace/Tracer.php create mode 100644 vendor/open-telemetry/sdk/Trace/TracerProvider.php create mode 100644 vendor/open-telemetry/sdk/Trace/TracerProviderBuilder.php create mode 100644 vendor/open-telemetry/sdk/Trace/TracerProviderFactory.php create mode 100644 vendor/open-telemetry/sdk/Trace/TracerProviderInterface.php create mode 100644 vendor/open-telemetry/sdk/Trace/TracerSharedState.php (limited to 'vendor/open-telemetry/sdk/Trace') 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 @@ +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 @@ + $batch + * @return FutureInterface + */ + 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 @@ +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 $batch + * @return FutureInterface + */ + 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 $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 @@ +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 @@ +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 @@ +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 @@ + */ + private array $events; + + /** @var list */ + 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 $links + * @param list $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 @@ +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 @@ +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 @@ +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 @@ +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 @@ +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 @@ + 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 @@ + $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 @@ +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 @@ + + */ + 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 */ + 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 $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 $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 @@ + */ + 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 @@ + */ + public function getEvents(): array; + + /** @return list */ + 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 @@ +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 @@ +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 @@ +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 $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 $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 @@ +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 @@ +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 @@ +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 @@ + $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 + */ + 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 @@ +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 @@ +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 @@ + '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 */ + private array $batch = []; + /** @var SplQueue> */ + private SplQueue $queue; + /** @var SplQueue */ + 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 @@ +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 @@ + */ + 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 */ + 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 @@ +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 @@ + */ + 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 @@ +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 @@ +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 @@ +|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 @@ + + 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 @@ +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 @@ +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)); + } +} -- cgit v1.2.3