summaryrefslogtreecommitdiff
path: root/vendor/open-telemetry/exporter-otlp/SpanConverter.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/open-telemetry/exporter-otlp/SpanConverter.php')
-rw-r--r--vendor/open-telemetry/exporter-otlp/SpanConverter.php187
1 files changed, 187 insertions, 0 deletions
diff --git a/vendor/open-telemetry/exporter-otlp/SpanConverter.php b/vendor/open-telemetry/exporter-otlp/SpanConverter.php
new file mode 100644
index 000000000..1a8b4369e
--- /dev/null
+++ b/vendor/open-telemetry/exporter-otlp/SpanConverter.php
@@ -0,0 +1,187 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\Contrib\Otlp;
+
+use OpenTelemetry\API\Trace as API;
+use Opentelemetry\Proto\Collector\Trace\V1\ExportTraceServiceRequest;
+use Opentelemetry\Proto\Common\V1\InstrumentationScope;
+use Opentelemetry\Proto\Common\V1\KeyValue;
+use Opentelemetry\Proto\Resource\V1\Resource as Resource_;
+use Opentelemetry\Proto\Trace\V1\ResourceSpans;
+use Opentelemetry\Proto\Trace\V1\ScopeSpans;
+use Opentelemetry\Proto\Trace\V1\Span;
+use Opentelemetry\Proto\Trace\V1\Span\Event;
+use Opentelemetry\Proto\Trace\V1\Span\Link;
+use Opentelemetry\Proto\Trace\V1\Span\SpanKind;
+use Opentelemetry\Proto\Trace\V1\Status;
+use Opentelemetry\Proto\Trace\V1\Status\StatusCode;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+use OpenTelemetry\SDK\Trace\SpanDataInterface;
+use function serialize;
+use function spl_object_id;
+
+final class SpanConverter
+{
+ private ProtobufSerializer $serializer;
+
+ public function __construct(?ProtobufSerializer $serializer = null)
+ {
+ $this->serializer = $serializer ?? ProtobufSerializer::getDefault();
+ }
+
+ public function convert(iterable $spans): ExportTraceServiceRequest
+ {
+ $pExportTraceServiceRequest = new ExportTraceServiceRequest();
+
+ $resourceSpans = [];
+ $resourceCache = [];
+ $scopeSpans = [];
+ $scopeCache = [];
+ foreach ($spans as $span) {
+ $resource = $span->getResource();
+ $instrumentationScope = $span->getInstrumentationScope();
+
+ $resourceId = $resourceCache[spl_object_id($resource)] ??= serialize([
+ $resource->getSchemaUrl(),
+ $resource->getAttributes()->toArray(),
+ $resource->getAttributes()->getDroppedAttributesCount(),
+ ]);
+ $instrumentationScopeId = $scopeCache[spl_object_id($instrumentationScope)] ??= serialize([
+ $instrumentationScope->getName(),
+ $instrumentationScope->getVersion(),
+ $instrumentationScope->getSchemaUrl(),
+ $instrumentationScope->getAttributes()->toArray(),
+ $instrumentationScope->getAttributes()->getDroppedAttributesCount(),
+ ]);
+
+ if (($pResourceSpans = $resourceSpans[$resourceId] ?? null) === null) {
+ /** @psalm-suppress InvalidArgument */
+ $pExportTraceServiceRequest->getResourceSpans()[]
+ = $resourceSpans[$resourceId]
+ = $pResourceSpans
+ = $this->convertResourceSpans($resource);
+ }
+
+ if (($pScopeSpans = $scopeSpans[$resourceId][$instrumentationScopeId] ?? null) === null) {
+ /** @psalm-suppress InvalidArgument */
+ $pResourceSpans->getScopeSpans()[]
+ = $scopeSpans[$resourceId][$instrumentationScopeId]
+ = $pScopeSpans
+ = $this->convertScopeSpans($instrumentationScope);
+ }
+
+ /** @psalm-suppress InvalidArgument */
+ $pScopeSpans->getSpans()[] = $this->convertSpan($span);
+ }
+
+ return $pExportTraceServiceRequest;
+ }
+
+ private function convertResourceSpans(ResourceInfo $resource): ResourceSpans
+ {
+ $pResourceSpans = new ResourceSpans();
+ $pResource = new Resource_();
+ $this->setAttributes($pResource, $resource->getAttributes());
+ $pResourceSpans->setResource($pResource);
+ $pResourceSpans->setSchemaUrl((string) $resource->getSchemaUrl());
+
+ return $pResourceSpans;
+ }
+
+ private function convertScopeSpans(InstrumentationScopeInterface $instrumentationScope): ScopeSpans
+ {
+ $pScopeSpans = new ScopeSpans();
+ $pInstrumentationScope = new InstrumentationScope();
+ $pInstrumentationScope->setName($instrumentationScope->getName());
+ $pInstrumentationScope->setVersion((string) $instrumentationScope->getVersion());
+ $this->setAttributes($pInstrumentationScope, $instrumentationScope->getAttributes());
+ $pScopeSpans->setScope($pInstrumentationScope);
+ $pScopeSpans->setSchemaUrl((string) $instrumentationScope->getSchemaUrl());
+
+ return $pScopeSpans;
+ }
+
+ /**
+ * @param Resource_|Span|Event|Link|InstrumentationScope $pElement
+ */
+ private function setAttributes($pElement, AttributesInterface $attributes): void
+ {
+ foreach ($attributes as $key => $value) {
+ /** @psalm-suppress InvalidArgument */
+ $pElement->getAttributes()[] = (new KeyValue())
+ ->setKey($key)
+ ->setValue(AttributesConverter::convertAnyValue($value));
+ }
+ $pElement->setDroppedAttributesCount($attributes->getDroppedAttributesCount());
+ }
+
+ private function convertSpanKind(int $kind): int
+ {
+ switch ($kind) {
+ case API\SpanKind::KIND_INTERNAL: return SpanKind::SPAN_KIND_INTERNAL;
+ case API\SpanKind::KIND_CLIENT: return SpanKind::SPAN_KIND_CLIENT;
+ case API\SpanKind::KIND_SERVER: return SpanKind::SPAN_KIND_SERVER;
+ case API\SpanKind::KIND_PRODUCER: return SpanKind::SPAN_KIND_PRODUCER;
+ case API\SpanKind::KIND_CONSUMER: return SpanKind::SPAN_KIND_CONSUMER;
+ }
+
+ return SpanKind::SPAN_KIND_UNSPECIFIED;
+ }
+
+ private function convertStatusCode(string $status): int
+ {
+ switch ($status) {
+ case API\StatusCode::STATUS_UNSET: return StatusCode::STATUS_CODE_UNSET;
+ case API\StatusCode::STATUS_OK: return StatusCode::STATUS_CODE_OK;
+ case API\StatusCode::STATUS_ERROR: return StatusCode::STATUS_CODE_ERROR;
+ }
+
+ return StatusCode::STATUS_CODE_UNSET;
+ }
+
+ private function convertSpan(SpanDataInterface $span): Span
+ {
+ $pSpan = new Span();
+ $pSpan->setTraceId($this->serializer->serializeTraceId($span->getContext()->getTraceIdBinary()));
+ $pSpan->setSpanId($this->serializer->serializeSpanId($span->getContext()->getSpanIdBinary()));
+ $pSpan->setTraceState((string) $span->getContext()->getTraceState());
+ if ($span->getParentContext()->isValid()) {
+ $pSpan->setParentSpanId($this->serializer->serializeSpanId($span->getParentContext()->getSpanIdBinary()));
+ }
+ $pSpan->setName($span->getName());
+ $pSpan->setKind($this->convertSpanKind($span->getKind()));
+ $pSpan->setStartTimeUnixNano($span->getStartEpochNanos());
+ $pSpan->setEndTimeUnixNano($span->getEndEpochNanos());
+ $this->setAttributes($pSpan, $span->getAttributes());
+
+ foreach ($span->getEvents() as $event) {
+ /** @psalm-suppress InvalidArgument */
+ $pSpan->getEvents()[] = $pEvent = new Event();
+ $pEvent->setTimeUnixNano($event->getEpochNanos());
+ $pEvent->setName($event->getName());
+ $this->setAttributes($pEvent, $event->getAttributes());
+ }
+ $pSpan->setDroppedEventsCount($span->getTotalDroppedEvents());
+
+ foreach ($span->getLinks() as $link) {
+ /** @psalm-suppress InvalidArgument */
+ $pSpan->getLinks()[] = $pLink = new Link();
+ $pLink->setTraceId($this->serializer->serializeTraceId($link->getSpanContext()->getTraceIdBinary()));
+ $pLink->setSpanId($this->serializer->serializeSpanId($link->getSpanContext()->getSpanIdBinary()));
+ $pLink->setTraceState((string) $link->getSpanContext()->getTraceState());
+ $this->setAttributes($pLink, $link->getAttributes());
+ }
+ $pSpan->setDroppedLinksCount($span->getTotalDroppedLinks());
+
+ $pStatus = new Status();
+ $pStatus->setMessage($span->getStatus()->getDescription());
+ $pStatus->setCode($this->convertStatusCode($span->getStatus()->getCode()));
+ $pSpan->setStatus($pStatus);
+
+ return $pSpan;
+ }
+}