@@ -28,6 +28,16 @@ final class PropagationContext
2828 */
2929 private $ parentSpanId ;
3030
31+ /**
32+ * @var bool|null The parent's sampling decision
33+ */
34+ private $ parentSampled ;
35+
36+ /**
37+ * @var float|null
38+ */
39+ private $ sampleRand ;
40+
3141 /**
3242 * @var DynamicSamplingContext|null The dynamic sampling context
3343 */
@@ -44,6 +54,8 @@ public static function fromDefaults(): self
4454 $ context ->traceId = TraceId::generate ();
4555 $ context ->spanId = SpanId::generate ();
4656 $ context ->parentSpanId = null ;
57+ $ context ->parentSampled = null ;
58+ $ context ->sampleRand = round (mt_rand (0 , mt_getrandmax () - 1 ) / mt_getrandmax (), 6 );
4759 $ context ->dynamicSamplingContext = null ;
4860
4961 return $ context ;
@@ -159,6 +171,19 @@ public function setDynamicSamplingContext(DynamicSamplingContext $dynamicSamplin
159171 return $ this ;
160172 }
161173
174+ public function getSampleRand (): ?float
175+ {
176+ return $ this ->sampleRand ;
177+ }
178+
179+ public function setSampleRand (?float $ sampleRand ): self
180+ {
181+ $ this ->sampleRand = $ sampleRand ;
182+
183+ return $ this ;
184+ }
185+
186+ // TODO add same logic as in TransactionContext
162187 private static function parseTraceparentAndBaggage (string $ traceparent , string $ baggage ): self
163188 {
164189 $ context = self ::fromDefaults ();
@@ -174,6 +199,11 @@ private static function parseTraceparentAndBaggage(string $traceparent, string $
174199 $ context ->parentSpanId = new SpanId ($ matches ['span_id ' ]);
175200 $ hasSentryTrace = true ;
176201 }
202+
203+ if (isset ($ matches ['sampled ' ])) {
204+ $ context ->parentSampled = $ matches ['sampled ' ] === '1 ' ;
205+ $ hasSentryTrace = true ;
206+ }
177207 } elseif (preg_match (self ::W3C_TRACEPARENT_HEADER_REGEX , $ traceparent , $ matches )) {
178208 if (!empty ($ matches ['trace_id ' ])) {
179209 $ context ->traceId = new TraceId ($ matches ['trace_id ' ]);
@@ -184,6 +214,11 @@ private static function parseTraceparentAndBaggage(string $traceparent, string $
184214 $ context ->parentSpanId = new SpanId ($ matches ['span_id ' ]);
185215 $ hasSentryTrace = true ;
186216 }
217+
218+ if (isset ($ matches ['sampled ' ])) {
219+ $ context ->parentSampled = $ matches ['sampled ' ] === '01 ' ;
220+ $ hasSentryTrace = true ;
221+ }
187222 }
188223
189224 $ samplingContext = DynamicSamplingContext::fromHeader ($ baggage );
@@ -201,6 +236,24 @@ private static function parseTraceparentAndBaggage(string $traceparent, string $
201236 $ context ->dynamicSamplingContext = $ samplingContext ;
202237 }
203238
239+ // Store the propagated trace sample rand or generate a new one
240+ if ($ samplingContext ->has ('sample_rand ' )) {
241+ $ context ->sampleRand = (float ) $ samplingContext ->get ('sample_rand ' );
242+ } else {
243+ if ($ samplingContext ->has ('sample_rate ' ) && $ context ->parentSampled !== null ) {
244+ if ($ context ->parentSampled === true ) {
245+ // [0, rate)
246+ $ context ->sampleRand = round (mt_rand (0 , mt_getrandmax () - 1 ) / mt_getrandmax () * (float ) $ samplingContext ->get ('sample_rate ' ), 6 );
247+ } else {
248+ // [rate, 1)
249+ $ context ->sampleRand = round (mt_rand (0 , mt_getrandmax () - 1 ) / mt_getrandmax () * (1 - (float ) $ samplingContext ->get ('sample_rate ' )) + (float ) $ samplingContext ->get ('sample-rate ' ), 6 );
250+ }
251+ } elseif ($ context ->parentSampled !== null ) {
252+ // [0, 1)
253+ $ context ->sampleRand = round (mt_rand (0 , mt_getrandmax () - 1 ) / mt_getrandmax (), 6 );
254+ }
255+ }
256+
204257 return $ context ;
205258 }
206259}
0 commit comments