diff --git a/src/State/Hub.php b/src/State/Hub.php index 070ec7025..117f3df9d 100644 --- a/src/State/Hub.php +++ b/src/State/Hub.php @@ -269,6 +269,7 @@ public function startTransaction(TransactionContext $context, array $customSampl $samplingContext->setAdditionalContext($customSamplingContext); $sampleSource = 'context'; + $sampleRand = $context->getMetadata()->getSampleRand(); if ($transaction->getSampled() === null) { $tracesSampler = $options->getTracesSampler(); @@ -278,12 +279,17 @@ public function startTransaction(TransactionContext $context, array $customSampl $sampleSource = 'config:traces_sampler'; } else { - $sampleRate = $this->getSampleRate( - $samplingContext->getParentSampled(), - $options->getTracesSampleRate() ?? 0 - ); - - $sampleSource = $samplingContext->getParentSampled() ? 'parent' : 'config:traces_sample_rate'; + $parentSampleRate = (float) $context->getMetadata()->getDynamicSamplingContext()->get('sample_rate'); + if ($parentSampleRate !== null) { + $sampleRate = $parentSampleRate; + $sampleSource = 'parent'; + } else { + $sampleRate = $this->getSampleRate( + $samplingContext->getParentSampled(), + $options->getTracesSampleRate() ?? 0 + ); + $sampleSource = $samplingContext->getParentSampled() ? 'parent' : 'config:traces_sample_rate'; + } } if (!$this->isValidSampleRate($sampleRate)) { @@ -294,6 +300,7 @@ public function startTransaction(TransactionContext $context, array $customSampl return $transaction; } + // TODO Why are we doing this? $transaction->getMetadata()->setSamplingRate($sampleRate); if ($sampleRate === 0.0) { diff --git a/src/Tracing/DynamicSamplingContext.php b/src/Tracing/DynamicSamplingContext.php index 8146894cc..55dafa5a4 100644 --- a/src/Tracing/DynamicSamplingContext.php +++ b/src/Tracing/DynamicSamplingContext.php @@ -199,6 +199,7 @@ public static function fromOptions(Options $options, Scope $scope): self { $samplingContext = new self(); $samplingContext->set('trace_id', (string) $scope->getPropagationContext()->getTraceId()); + $samplingContext->set('sample_rand', (string) $scope->getPropagationContext()->getSampleRand()); if ($options->getTracesSampleRate() !== null) { $samplingContext->set('sample_rate', (string) $options->getTracesSampleRate()); diff --git a/src/Tracing/PropagationContext.php b/src/Tracing/PropagationContext.php index fce1b2207..d84221ba8 100644 --- a/src/Tracing/PropagationContext.php +++ b/src/Tracing/PropagationContext.php @@ -33,6 +33,11 @@ final class PropagationContext */ private $dynamicSamplingContext; + /** + * @var float|null + */ + private $sampleRand; + private function __construct() { } @@ -46,6 +51,9 @@ public static function fromDefaults(): self $context->parentSpanId = null; $context->dynamicSamplingContext = null; + // TODO check if this is precise enough + $context->sampleRand = round(mt_rand(0, mt_getrandmax() - 1) / mt_getrandmax(), 6); + return $context; } @@ -159,6 +167,7 @@ public function setDynamicSamplingContext(DynamicSamplingContext $dynamicSamplin return $this; } + // TODO add same logic as in TransactionContext private static function parseTraceparentAndBaggage(string $traceparent, string $baggage): self { $context = self::fromDefaults(); diff --git a/src/Tracing/TransactionContext.php b/src/Tracing/TransactionContext.php index 7bd8693a9..be74ea747 100644 --- a/src/Tracing/TransactionContext.php +++ b/src/Tracing/TransactionContext.php @@ -199,12 +199,20 @@ private static function parseTraceAndBaggage(string $sentryTrace, string $baggag } if ($samplingContext->has('sample_rand')) { + // TODO check for 1e13 etc. $context->getMetadata()->setSampleRand((float) $samplingContext->get('sample_rand')); } else { if ($samplingContext->has('sample-rate') && $context->parentSampled !== null) { - $context->getMetadata()->setSampleRand(1); + if ($context->parentSampled === true) { + // [0, rate) + $context->getMetadata()->setSampleRand(round(mt_rand(0, mt_getrandmax() - 1) / mt_getrandmax() * $samplingContext->get('sample-rate'), 6)); + } else { + // [rate, 1] + $context->getMetadata()->setSampleRand(round(mt_rand(0, mt_getrandmax() - 1) / mt_getrandmax() * (1 - $samplingContext->get('sample-rate')) + $samplingContext->get('sample-rate'), 6)); + } } elseif ($context->parentSampled !== null) { - $context->getMetadata()->setSampleRand(1); + // [0, 1) + $context->getMetadata()->setSampleRand(round(mt_rand(0, mt_getrandmax() - 1) / mt_getrandmax(), 6)); } } diff --git a/src/Tracing/TransactionMetadata.php b/src/Tracing/TransactionMetadata.php index 670a1586c..6799df29c 100644 --- a/src/Tracing/TransactionMetadata.php +++ b/src/Tracing/TransactionMetadata.php @@ -42,7 +42,8 @@ public function __construct( $this->dynamicSamplingContext = $dynamicSamplingContext; $this->source = $source ?? TransactionSource::custom(); - $this->sampleRand = round(mt_rand(0, mt_getrandmax() - 1) / mt_getrandmax(), 2); + // TODO check if this is precise enough + $this->sampleRand = round(mt_rand(0, mt_getrandmax() - 1) / mt_getrandmax(), 6); } /**