@@ -18,7 +18,11 @@ import {
18
18
logger ,
19
19
sampleSpan ,
20
20
} from '@sentry/core' ;
21
- import { SENTRY_TRACE_STATE_SAMPLED_NOT_RECORDING , SENTRY_TRACE_STATE_URL } from './constants' ;
21
+ import {
22
+ SENTRY_TRACE_STATE_SAMPLED_NOT_RECORDING ,
23
+ SENTRY_TRACE_STATE_SAMPLE_RAND ,
24
+ SENTRY_TRACE_STATE_URL ,
25
+ } from './constants' ;
22
26
import { DEBUG_BUILD } from './debug-build' ;
23
27
import { getScopesFromContext } from './utils/contextData' ;
24
28
import { getSamplingDecision } from './utils/getSamplingDecision' ;
@@ -99,11 +103,10 @@ export class SentrySampler implements Sampler {
99
103
100
104
const isRootSpan = ! parentSpan || parentContext ?. isRemote ;
101
105
102
- const { isolationScope, scope } = getScopesFromContext ( context ) ?? { } ;
103
-
104
106
// We only sample based on parameters (like tracesSampleRate or tracesSampler) for root spans (which is done in sampleSpan).
105
107
// Non-root-spans simply inherit the sampling decision from their parent.
106
108
if ( isRootSpan ) {
109
+ const { isolationScope, scope } = getScopesFromContext ( context ) ?? { } ;
107
110
const sampleRand = scope ?. getPropagationContext ( ) . sampleRand ?? Math . random ( ) ;
108
111
const [ sampled , sampleRate ] = sampleSpan (
109
112
options ,
@@ -126,7 +129,7 @@ export class SentrySampler implements Sampler {
126
129
DEBUG_BUILD && logger . log ( `[Tracing] Not sampling span because HTTP method is '${ method } ' for ${ spanName } ` ) ;
127
130
128
131
return {
129
- ...wrapSamplingDecision ( { decision : SamplingDecision . NOT_RECORD , context, spanAttributes } ) ,
132
+ ...wrapSamplingDecision ( { decision : SamplingDecision . NOT_RECORD , context, spanAttributes, sampleRand } ) ,
130
133
attributes,
131
134
} ;
132
135
}
@@ -145,6 +148,7 @@ export class SentrySampler implements Sampler {
145
148
decision : sampled ? SamplingDecision . RECORD_AND_SAMPLED : SamplingDecision . NOT_RECORD ,
146
149
context,
147
150
spanAttributes,
151
+ sampleRand,
148
152
} ) ,
149
153
attributes,
150
154
} ;
@@ -196,8 +200,18 @@ export function wrapSamplingDecision({
196
200
decision,
197
201
context,
198
202
spanAttributes,
199
- } : { decision : SamplingDecision | undefined ; context : Context ; spanAttributes : SpanAttributes } ) : SamplingResult {
200
- const traceState = getBaseTraceState ( context , spanAttributes ) ;
203
+ sampleRand,
204
+ } : {
205
+ decision : SamplingDecision | undefined ;
206
+ context : Context ;
207
+ spanAttributes : SpanAttributes ;
208
+ sampleRand ?: number ;
209
+ } ) : SamplingResult {
210
+ let traceState = getBaseTraceState ( context , spanAttributes ) ;
211
+
212
+ if ( sampleRand !== undefined ) {
213
+ traceState = traceState . set ( SENTRY_TRACE_STATE_SAMPLE_RAND , `${ sampleRand } ` ) ;
214
+ }
201
215
202
216
// If the decision is undefined, we treat it as NOT_RECORDING, but we don't propagate this decision to downstream SDKs
203
217
// Which is done by not setting `SENTRY_TRACE_STATE_SAMPLED_NOT_RECORDING` traceState
0 commit comments