@@ -28,6 +28,16 @@ final class PropagationContext
28
28
*/
29
29
private $ parentSpanId ;
30
30
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
+
31
41
/**
32
42
* @var DynamicSamplingContext|null The dynamic sampling context
33
43
*/
@@ -44,6 +54,8 @@ public static function fromDefaults(): self
44
54
$ context ->traceId = TraceId::generate ();
45
55
$ context ->spanId = SpanId::generate ();
46
56
$ context ->parentSpanId = null ;
57
+ $ context ->parentSampled = null ;
58
+ $ context ->sampleRand = round (mt_rand (0 , mt_getrandmax () - 1 ) / mt_getrandmax (), 6 );
47
59
$ context ->dynamicSamplingContext = null ;
48
60
49
61
return $ context ;
@@ -159,6 +171,19 @@ public function setDynamicSamplingContext(DynamicSamplingContext $dynamicSamplin
159
171
return $ this ;
160
172
}
161
173
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
162
187
private static function parseTraceparentAndBaggage (string $ traceparent , string $ baggage ): self
163
188
{
164
189
$ context = self ::fromDefaults ();
@@ -174,6 +199,11 @@ private static function parseTraceparentAndBaggage(string $traceparent, string $
174
199
$ context ->parentSpanId = new SpanId ($ matches ['span_id ' ]);
175
200
$ hasSentryTrace = true ;
176
201
}
202
+
203
+ if (isset ($ matches ['sampled ' ])) {
204
+ $ context ->parentSampled = $ matches ['sampled ' ] === '1 ' ;
205
+ $ hasSentryTrace = true ;
206
+ }
177
207
} elseif (preg_match (self ::W3C_TRACEPARENT_HEADER_REGEX , $ traceparent , $ matches )) {
178
208
if (!empty ($ matches ['trace_id ' ])) {
179
209
$ context ->traceId = new TraceId ($ matches ['trace_id ' ]);
@@ -184,6 +214,11 @@ private static function parseTraceparentAndBaggage(string $traceparent, string $
184
214
$ context ->parentSpanId = new SpanId ($ matches ['span_id ' ]);
185
215
$ hasSentryTrace = true ;
186
216
}
217
+
218
+ if (isset ($ matches ['sampled ' ])) {
219
+ $ context ->parentSampled = $ matches ['sampled ' ] === '01 ' ;
220
+ $ hasSentryTrace = true ;
221
+ }
187
222
}
188
223
189
224
$ samplingContext = DynamicSamplingContext::fromHeader ($ baggage );
@@ -201,6 +236,24 @@ private static function parseTraceparentAndBaggage(string $traceparent, string $
201
236
$ context ->dynamicSamplingContext = $ samplingContext ;
202
237
}
203
238
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
+
204
257
return $ context ;
205
258
}
206
259
}
0 commit comments