Skip to content

Commit 0ec5860

Browse files
committed
Implement strict_trace_propagation
1 parent 18b57e0 commit 0ec5860

File tree

3 files changed

+97
-6
lines changed

3 files changed

+97
-6
lines changed

src/Tracing/PropagationContext.php

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,33 @@ private static function parseTraceparentAndBaggage(string $traceparent, string $
188188
{
189189
$context = self::fromDefaults();
190190
$hasSentryTrace = false;
191+
$samplingContext = DynamicSamplingContext::fromHeader($baggage);
192+
193+
$client = SentrySdk::getCurrentHub()->getClient();
194+
if ($client !== null) {
195+
$options = $client->getOptions();
196+
$orgId = $options->getOrgId() ?? $options->getDsn()->getOrgId();
197+
198+
// Always check if the received org ID in the baggages matches
199+
// the one configured in the SDK.
200+
if (
201+
$orgId !== null &&
202+
$samplingContext->has('org_id') &&
203+
$samplingContext->get('org_id') !== (string) $orgId
204+
) {
205+
// We do not continue the trace.
206+
return $context;
207+
}
208+
209+
if ($client->getOptions()->isStrictTracePropagationEnabled()) {
210+
if (!$samplingContext->has('org_id')) {
211+
// We did not receive any org id in the baggage,
212+
// do not continue the trace. The none mathcing org ID
213+
// case was already handled above.
214+
return $context;
215+
}
216+
}
217+
}
191218

192219
if (preg_match(self::SENTRY_TRACEPARENT_HEADER_REGEX, $traceparent, $matches)) {
193220
if (!empty($matches['trace_id'])) {
@@ -206,8 +233,6 @@ private static function parseTraceparentAndBaggage(string $traceparent, string $
206233
}
207234
}
208235

209-
$samplingContext = DynamicSamplingContext::fromHeader($baggage);
210-
211236
if ($hasSentryTrace && !$samplingContext->hasEntries()) {
212237
// The request comes from an old SDK which does not support Dynamic Sampling.
213238
// Propagate the Dynamic Sampling Context as is, but frozen, even without sentry-* entries.

src/Tracing/TransactionContext.php

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
namespace Sentry\Tracing;
66

7+
use Sentry\SentrySdk;
8+
79
final class TransactionContext extends SpanContext
810
{
911
private const SENTRY_TRACEPARENT_HEADER_REGEX = '/^[ \\t]*(?<trace_id>[0-9a-f]{32})?-?(?<span_id>[0-9a-f]{16})?-?(?<sampled>[01])?[ \\t]*$/i';
@@ -148,6 +150,33 @@ private static function parseTraceAndBaggage(string $sentryTrace, string $baggag
148150
{
149151
$context = new self();
150152
$hasSentryTrace = false;
153+
$samplingContext = DynamicSamplingContext::fromHeader($baggage);
154+
155+
$client = SentrySdk::getCurrentHub()->getClient();
156+
if ($client !== null) {
157+
$options = $client->getOptions();
158+
$orgId = $options->getOrgId() ?? $options->getDsn()->getOrgId();
159+
160+
// Always check if the received org ID in the baggages matches
161+
// the one configured in the SDK.
162+
if (
163+
$orgId !== null &&
164+
$samplingContext->has('org_id') &&
165+
$samplingContext->get('org_id') !== (string) $orgId
166+
) {
167+
// We do not continue the trace.
168+
return $context;
169+
}
170+
171+
if ($client->getOptions()->isStrictTracePropagationEnabled()) {
172+
if (!$samplingContext->has('org_id')) {
173+
// We did not receive any org id in the baggage,
174+
// do not continue the trace. The none mathcing org ID
175+
// case was already handled above.
176+
return $context;
177+
}
178+
}
179+
}
151180

152181
if (preg_match(self::SENTRY_TRACEPARENT_HEADER_REGEX, $sentryTrace, $matches)) {
153182
if (!empty($matches['trace_id'])) {
@@ -166,8 +195,6 @@ private static function parseTraceAndBaggage(string $sentryTrace, string $baggag
166195
}
167196
}
168197

169-
$samplingContext = DynamicSamplingContext::fromHeader($baggage);
170-
171198
if ($hasSentryTrace && !$samplingContext->hasEntries()) {
172199
// The request comes from an old SDK which does not support Dynamic Sampling.
173200
// Propagate the Dynamic Sampling Context as is, but frozen, even without sentry-* entries.

tests/FunctionsTest.php

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -514,13 +514,20 @@ public function testBaggageWithTracingEnabled(): void
514514

515515
public function testContinueTrace(): void
516516
{
517-
$hub = new Hub();
517+
$client = $this->createMock(ClientInterface::class);
518+
$client->expects($this->atLeastOnce())
519+
->method('getOptions')
520+
->willReturn(new Options([
521+
'org_id' => 1,
522+
]));
523+
524+
$hub = new Hub($client);
518525

519526
SentrySdk::setCurrentHub($hub);
520527

521528
$transactionContext = continueTrace(
522529
'566e3688a61d4bc888951642d6f14a19-566e3688a61d4bc8-1',
523-
'sentry-trace_id=566e3688a61d4bc888951642d6f14a19'
530+
'sentry-trace_id=566e3688a61d4bc888951642d6f14a19,sentry-org_id=1'
524531
);
525532

526533
$this->assertSame('566e3688a61d4bc888951642d6f14a19', (string) $transactionContext->getTraceId());
@@ -539,4 +546,36 @@ public function testContinueTrace(): void
539546
$this->assertTrue($dynamicSamplingContext->isFrozen());
540547
});
541548
}
549+
550+
public function testContinueTraceWithNoneMatchingOrgId(): void
551+
{
552+
$client = $this->createMock(ClientInterface::class);
553+
$client->expects($this->atLeastOnce())
554+
->method('getOptions')
555+
->willReturn(new Options([
556+
'org_id' => 1,
557+
]));
558+
559+
$hub = new Hub($client);
560+
561+
SentrySdk::setCurrentHub($hub);
562+
563+
$transactionContext = continueTrace(
564+
'566e3688a61d4bc888951642d6f14a19-566e3688a61d4bc8-1',
565+
'sentry-trace_id=566e3688a61d4bc888951642d6f14a19,sentry-org_id=2'
566+
);
567+
568+
$this->assertNull($transactionContext->getTraceId());
569+
$this->assertNull($transactionContext->getParentSpanId());
570+
$this->assertNull($transactionContext->getParentSampled());
571+
572+
configureScope(function (Scope $scope): void {
573+
$propagationContext = $scope->getPropagationContext();
574+
575+
$this->assertNotSame('566e3688a61d4bc888951642d6f14a19', (string) $propagationContext->getTraceId());
576+
$this->assertNotSame('566e3688a61d4bc8', (string) $propagationContext->getParentSpanId());
577+
578+
$this->assertNull($propagationContext->getDynamicSamplingContext());
579+
});
580+
}
542581
}

0 commit comments

Comments
 (0)