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