Skip to content

Commit

Permalink
feat: Partially handle on-the-fly addition of span links
Browse files Browse the repository at this point in the history
  • Loading branch information
PROFeNoM committed Jan 4, 2024
1 parent daa99d1 commit 1dfd0db
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 0 deletions.
28 changes: 28 additions & 0 deletions src/DDTrace/OpenTelemetry/Span.php
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ public function toSpanData(): SpanDataInterface
{
$hasEnded = $this->hasEnded();

$this->updateSpanLinks();

return new ImmutableSpan(
$this,
$this->getName(),
Expand Down Expand Up @@ -436,4 +438,30 @@ public function getDDSpan(): SpanData
{
return $this->span;
}

private function updateSpanLinks()
{
// Important: Links are assumed not to be removable to update the span links from Datadog to OpenTelemetry
// For instance, if there are 4 links in Datadog and only 2 in OpenTelemetry, the 2 missing links will be added
// to OpenTelemetry
$datadogSpanLinks = $this->span->links;
$otelSpanLinks = $this->links;

$datadogSpanLinksCount = count($datadogSpanLinks);
$otelSpanLinksCount = count($otelSpanLinks);

for ($i = $otelSpanLinksCount; $i < $datadogSpanLinksCount; $i++) {
$spanLink = $datadogSpanLinks[$i];

$linkSpanContext = API\SpanContext::create(
$spanLink->traceId,
$spanLink->spanId,
API\TraceFlags::DEFAULT,
new API\TraceState($spanLink->traceState ?? null),
);

$this->links[] = new Link($linkSpanContext, Attributes::create($spanLink->attributes ?? []));
$this->totalRecordedLinks++;
}
}
}
55 changes: 55 additions & 0 deletions tests/OpenTelemetry/Integration/InteroperabilityTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -975,4 +975,59 @@ public function testSpanLinksInteroperabilityFromOpenTelemetrySpan()
$this->assertCount(1, $traces[0]);
$this->assertSame("[{\"trace_id\":\"12345678876543211234567887654321\",\"span_id\":\"8765432112345678\",\"trace_state\":\"dd=t.dm:-0\",\"attributes\":{\"arg1\":\"value1\"},\"dropped_attributes_count\":0}]", $traces[0][0]['meta']['_dd.span_links']);
}

public function testSpanLinksInteroperabilityBothTypes()
{
$sampledSpanContext = SpanContext::create(
'12345678876543211234567887654321',
'8765432112345678',
TraceFlags::SAMPLED,
new TraceState('dd=t.dm:-0')
);

$traces = $this->isolateTracer(function () use ($sampledSpanContext) {
// Add 1 span link using the OTel API
$otelSpan = self::getTracer()->spanBuilder("otel.span")
->addLink($sampledSpanContext, ['arg1' => 'value1'])
->startSpan();

// Add 1 span link using the DD API
$newSpanLink = new SpanLink();
$newSpanLink->traceId = "ff0000000000051791e0000000000041";
$newSpanLink->spanId = "ff00000000000517";
active_span()->links[] = $newSpanLink;

// Verify the span links from DD's POV
$datadogSpanLinks = active_span()->links;
$this->assertCount(2, $datadogSpanLinks);

$this->assertSame('12345678876543211234567887654321', $datadogSpanLinks[0]->traceId);
$this->assertSame('8765432112345678', $datadogSpanLinks[0]->spanId);
$this->assertSame('dd=t.dm:-0', $datadogSpanLinks[0]->traceState);
$this->assertSame(['arg1' => 'value1'], $datadogSpanLinks[0]->attributes);
$this->assertEquals(0, $datadogSpanLinks[0]->droppedAttributesCount);

$this->assertSame('ff0000000000051791e0000000000041', $datadogSpanLinks[1]->traceId);
$this->assertSame('ff00000000000517', $datadogSpanLinks[1]->spanId);

// Verify the span links from OTel's POV
$otelSpanLinks = $otelSpan->toSpanData()->getLinks();

$firstSpanLinkContext = $otelSpanLinks[0]->getSpanContext();
$this->assertSame('12345678876543211234567887654321', $firstSpanLinkContext->getTraceId());
$this->assertSame('8765432112345678', $firstSpanLinkContext->getSpanId());
$this->assertSame('dd=t.dm:-0', (string) $firstSpanLinkContext->getTraceState());
$this->assertSame(['arg1' => 'value1'], $otelSpanLinks[0]->getAttributes()->toArray());

$secondSpanLinkContext = $otelSpanLinks[1]->getSpanContext();
$this->assertSame('ff0000000000051791e0000000000041', $secondSpanLinkContext->getTraceId());
$this->assertSame('ff00000000000517', $secondSpanLinkContext->getSpanId());


$otelSpan->end();
});

$this->assertCount(1, $traces[0]);
$this->assertSame("[{\"trace_id\":\"12345678876543211234567887654321\",\"span_id\":\"8765432112345678\",\"trace_state\":\"dd=t.dm:-0\",\"attributes\":{\"arg1\":\"value1\"},\"dropped_attributes_count\":0},{\"trace_id\":\"ff0000000000051791e0000000000041\",\"span_id\":\"ff00000000000517\"}]", $traces[0][0]['meta']['_dd.span_links']);
}
}

0 comments on commit 1dfd0db

Please sign in to comment.