Skip to content

Commit 6fef63f

Browse files
authored
Fix span suppression should suppress nested spans of non-recording spans too (#1921)
1 parent a39da3c commit 6fef63f

File tree

3 files changed

+92
-3
lines changed

3 files changed

+92
-3
lines changed

src/SDK/Trace/NonRecordingSpan.php

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace OpenTelemetry\SDK\Trace;
6+
7+
use OpenTelemetry\API\Trace\SpanContextInterface;
8+
use OpenTelemetry\API\Trace\SpanInterface;
9+
use OpenTelemetry\Context\ContextInterface;
10+
use OpenTelemetry\SDK\Trace\SpanSuppression\SpanSuppression;
11+
use Override;
12+
use Throwable;
13+
14+
/**
15+
* @internal
16+
*/
17+
final class NonRecordingSpan extends \OpenTelemetry\API\Trace\Span
18+
{
19+
public function __construct(
20+
private readonly SpanContextInterface $spanContext,
21+
private readonly SpanSuppression $spanSuppression,
22+
) {
23+
}
24+
25+
#[Override]
26+
public function storeInContext(ContextInterface $context): ContextInterface
27+
{
28+
return $this->spanSuppression->suppress(parent::storeInContext($context));
29+
}
30+
31+
#[Override]
32+
public function getContext(): SpanContextInterface
33+
{
34+
return $this->spanContext;
35+
}
36+
37+
#[Override]
38+
public function isRecording(): bool
39+
{
40+
return false;
41+
}
42+
43+
#[Override]
44+
public function setAttribute(string $key, float|array|bool|int|string|null $value): SpanInterface
45+
{
46+
return $this;
47+
}
48+
49+
#[Override]
50+
public function setAttributes(iterable $attributes): SpanInterface
51+
{
52+
return $this;
53+
}
54+
55+
#[Override]
56+
public function addLink(SpanContextInterface $context, iterable $attributes = []): SpanInterface
57+
{
58+
return $this;
59+
}
60+
61+
#[Override]
62+
public function addEvent(string $name, iterable $attributes = [], ?int $timestamp = null): SpanInterface
63+
{
64+
return $this;
65+
}
66+
67+
#[Override]
68+
public function recordException(Throwable $exception, iterable $attributes = []): SpanInterface
69+
{
70+
return $this;
71+
}
72+
73+
#[Override]
74+
public function updateName(string $name): SpanInterface
75+
{
76+
return $this;
77+
}
78+
79+
#[Override]
80+
public function setStatus(string $code, ?string $description = null): SpanInterface
81+
{
82+
return $this;
83+
}
84+
85+
#[Override]
86+
public function end(?int $endEpochNanos = null): void
87+
{
88+
// no-op
89+
}
90+
}

src/SDK/Trace/SpanBuilder.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,7 @@ public function startSpan(): API\SpanInterface
168168
);
169169

170170
if (!in_array($samplingDecision, [SamplingResult::RECORD_AND_SAMPLE, SamplingResult::RECORD_ONLY], true)) {
171-
// TODO must suppress no-op spans too
172-
return Span::wrap($spanContext);
171+
return new NonRecordingSpan($spanContext, $spanSuppression);
173172
}
174173

175174
$attributesBuilder = clone $this->attributesBuilder;

tests/Integration/SDK/TracerTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public function test_noop_span_should_be_started_when_sampling_result_is_drop():
4141
$processor->expects($this->never())->method('onStart');
4242
$span = $tracer->spanBuilder('test.span')->startSpan();
4343

44-
$this->assertInstanceOf(NonRecordingSpan::class, $span);
44+
$this->assertFalse($span->isRecording());
4545
$this->assertNotEquals(API\TraceFlags::SAMPLED, $span->getContext()->getTraceFlags());
4646
}
4747

0 commit comments

Comments
 (0)