1- import type { Options , SamplingContext } from '@sentry/types' ;
1+ import type { Options , SamplingContext , TransactionContext } from '@sentry/types' ;
22import { isNaN , logger } from '@sentry/utils' ;
33
44import { DEBUG_BUILD } from '../debug-build' ;
5- import { SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE } from '../semanticAttributes' ;
65import { hasTracingEnabled } from '../utils/hasTracingEnabled' ;
7- import { spanToJSON } from '../utils/spanUtils' ;
8- import type { Transaction } from './transaction' ;
96
107/**
118 * Makes a sampling decision for the given transaction and stores it on the transaction.
@@ -16,50 +13,42 @@ import type { Transaction } from './transaction';
1613 * This method muttes the given `transaction` and will set the `sampled` value on it.
1714 * It returns the same transaction, for convenience.
1815 */
19- export function sampleTransaction < T extends Transaction > (
20- transaction : T ,
16+ export function sampleTransaction (
17+ transactionContext : TransactionContext ,
2118 options : Pick < Options , 'tracesSampleRate' | 'tracesSampler' | 'enableTracing' > ,
2219 samplingContext : SamplingContext ,
23- ) : T {
20+ ) : [ sampled : boolean , sampleRate ?: number ] {
2421 // nothing to do if tracing is not enabled
2522 if ( ! hasTracingEnabled ( options ) ) {
26- // eslint-disable-next-line deprecation/deprecation
27- transaction . sampled = false ;
28- return transaction ;
23+ return [ false ] ;
2924 }
3025
31- // if the user has forced a sampling decision by passing a `sampled` value in their transaction context, go with that
32- // eslint-disable-next-line deprecation/deprecation
33- if ( transaction . sampled !== undefined ) {
34- // eslint-disable-next-line deprecation/deprecation
35- transaction . setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE , Number ( transaction . sampled ) ) ;
36- return transaction ;
26+ const transactionContextSampled = transactionContext . sampled ;
27+ // if the user has forced a sampling decision by passing a `sampled` value in
28+ // their transaction context, go with that.
29+ if ( transactionContextSampled !== undefined ) {
30+ return [ transactionContextSampled , Number ( transactionContextSampled ) ] ;
3731 }
3832
3933 // we would have bailed already if neither `tracesSampler` nor `tracesSampleRate` nor `enableTracing` were defined, so one of these should
4034 // work; prefer the hook if so
4135 let sampleRate ;
4236 if ( typeof options . tracesSampler === 'function' ) {
4337 sampleRate = options . tracesSampler ( samplingContext ) ;
44- transaction . setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE , Number ( sampleRate ) ) ;
4538 } else if ( samplingContext . parentSampled !== undefined ) {
4639 sampleRate = samplingContext . parentSampled ;
4740 } else if ( typeof options . tracesSampleRate !== 'undefined' ) {
4841 sampleRate = options . tracesSampleRate ;
49- transaction . setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE , Number ( sampleRate ) ) ;
5042 } else {
5143 // When `enableTracing === true`, we use a sample rate of 100%
5244 sampleRate = 1 ;
53- transaction . setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE , sampleRate ) ;
5445 }
5546
5647 // Since this is coming from the user (or from a function provided by the user), who knows what we might get. (The
5748 // only valid values are booleans or numbers between 0 and 1.)
5849 if ( ! isValidSampleRate ( sampleRate ) ) {
5950 DEBUG_BUILD && logger . warn ( '[Tracing] Discarding transaction because of invalid sample rate.' ) ;
60- // eslint-disable-next-line deprecation/deprecation
61- transaction . sampled = false ;
62- return transaction ;
51+ return [ false ] ;
6352 }
6453
6554 // if the function returned 0 (or false), or if `tracesSampleRate` is 0, it's a sign the transaction should be dropped
@@ -72,40 +61,31 @@ export function sampleTransaction<T extends Transaction>(
7261 : 'a negative sampling decision was inherited or tracesSampleRate is set to 0'
7362 } `,
7463 ) ;
75- // eslint-disable-next-line deprecation/deprecation
76- transaction . sampled = false ;
77- return transaction ;
64+ return [ false , Number ( sampleRate ) ] ;
7865 }
7966
8067 // Now we roll the dice. Math.random is inclusive of 0, but not of 1, so strict < is safe here. In case sampleRate is
8168 // a boolean, the < comparison will cause it to be automatically cast to 1 if it's true and 0 if it's false.
82- // eslint-disable-next-line deprecation/deprecation
83- transaction . sampled = Math . random ( ) < ( sampleRate as number | boolean ) ;
69+ const shouldSample = Math . random ( ) < sampleRate ;
8470
8571 // if we're not going to keep it, we're done
86- // eslint-disable-next-line deprecation/deprecation
87- if ( ! transaction . sampled ) {
72+ if ( ! shouldSample ) {
8873 DEBUG_BUILD &&
8974 logger . log (
9075 `[Tracing] Discarding transaction because it's not included in the random sample (sampling rate = ${ Number (
9176 sampleRate ,
9277 ) } )`,
9378 ) ;
94- return transaction ;
79+ return [ false , Number ( sampleRate ) ] ;
9580 }
9681
97- if ( DEBUG_BUILD ) {
98- const { op, description } = spanToJSON ( transaction ) ;
99- logger . log ( `[Tracing] starting ${ op } transaction - ${ description } ` ) ;
100- }
101-
102- return transaction ;
82+ return [ true , Number ( sampleRate ) ] ;
10383}
10484
10585/**
10686 * Checks the given sample rate to make sure it is valid type and value (a boolean, or a number between 0 and 1).
10787 */
108- function isValidSampleRate ( rate : unknown ) : boolean {
88+ function isValidSampleRate ( rate : unknown ) : rate is number | boolean {
10989 // we need to check NaN explicitly because it's of type 'number' and therefore wouldn't get caught by this typecheck
11090 if ( isNaN ( rate ) || ! ( typeof rate === 'number' || typeof rate === 'boolean' ) ) {
11191 DEBUG_BUILD &&
0 commit comments