1- import type { Options , SamplingContext , TransactionArguments } from '@sentry/types' ;
2- import { isNaN , logger } from '@sentry/utils' ;
1+ import type { Options , SamplingContext } from '@sentry/types' ;
2+ import { logger } from '@sentry/utils' ;
33
44import { DEBUG_BUILD } from '../debug-build' ;
55import { hasTracingEnabled } from '../utils/hasTracingEnabled' ;
6+ import { parseSampleRate } from '../utils/parseSampleRate' ;
67
78/**
8- * Makes a sampling decision for the given transaction and stores it on the transaction .
9+ * Makes a sampling decision for the given options .
910 *
10- * Called every time a transaction is created. Only transactions which emerge with a `sampled` value of `true` will be
11+ * Called every time a root span is created. Only root spans which emerge with a `sampled` value of `true` will be
1112 * sent to Sentry.
12- *
13- * This method muttes the given `transaction` and will set the `sampled` value on it.
14- * It returns the same transaction, for convenience.
1513 */
16- export function sampleTransaction (
17- transactionContext : TransactionArguments ,
14+ export function sampleSpan (
1815 options : Pick < Options , 'tracesSampleRate' | 'tracesSampler' | 'enableTracing' > ,
1916 samplingContext : SamplingContext ,
2017) : [ sampled : boolean , sampleRate ?: number ] {
@@ -23,13 +20,6 @@ export function sampleTransaction(
2320 return [ false ] ;
2421 }
2522
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 ) ] ;
31- }
32-
3323 // we would have bailed already if neither `tracesSampler` nor `tracesSampleRate` nor `enableTracing` were defined, so one of these should
3424 // work; prefer the hook if so
3525 let sampleRate ;
@@ -44,15 +34,17 @@ export function sampleTransaction(
4434 sampleRate = 1 ;
4535 }
4636
47- // Since this is coming from the user (or from a function provided by the user), who knows what we might get. (The
48- // only valid values are booleans or numbers between 0 and 1.)
49- if ( ! isValidSampleRate ( sampleRate ) ) {
37+ // Since this is coming from the user (or from a function provided by the user), who knows what we might get.
38+ // (The only valid values are booleans or numbers between 0 and 1.)
39+ const parsedSampleRate = parseSampleRate ( sampleRate ) ;
40+
41+ if ( parsedSampleRate === undefined ) {
5042 DEBUG_BUILD && logger . warn ( '[Tracing] Discarding transaction because of invalid sample rate.' ) ;
5143 return [ false ] ;
5244 }
5345
5446 // if the function returned 0 (or false), or if `tracesSampleRate` is 0, it's a sign the transaction should be dropped
55- if ( ! sampleRate ) {
47+ if ( ! parsedSampleRate ) {
5648 DEBUG_BUILD &&
5749 logger . log (
5850 `[Tracing] Discarding transaction because ${
@@ -61,12 +53,12 @@ export function sampleTransaction(
6153 : 'a negative sampling decision was inherited or tracesSampleRate is set to 0'
6254 } `,
6355 ) ;
64- return [ false , Number ( sampleRate ) ] ;
56+ return [ false , parsedSampleRate ] ;
6557 }
6658
6759 // Now we roll the dice. Math.random is inclusive of 0, but not of 1, so strict < is safe here. In case sampleRate is
6860 // a boolean, the < comparison will cause it to be automatically cast to 1 if it's true and 0 if it's false.
69- const shouldSample = Math . random ( ) < sampleRate ;
61+ const shouldSample = Math . random ( ) < parsedSampleRate ;
7062
7163 // if we're not going to keep it, we're done
7264 if ( ! shouldSample ) {
@@ -76,32 +68,8 @@ export function sampleTransaction(
7668 sampleRate ,
7769 ) } )`,
7870 ) ;
79- return [ false , Number ( sampleRate ) ] ;
80- }
81-
82- return [ true , Number ( sampleRate ) ] ;
83- }
84-
85- /**
86- * Checks the given sample rate to make sure it is valid type and value (a boolean, or a number between 0 and 1).
87- */
88- function isValidSampleRate ( rate : unknown ) : rate is number | boolean {
89- // we need to check NaN explicitly because it's of type 'number' and therefore wouldn't get caught by this typecheck
90- if ( isNaN ( rate ) || ! ( typeof rate === 'number' || typeof rate === 'boolean' ) ) {
91- DEBUG_BUILD &&
92- logger . warn (
93- `[Tracing] Given sample rate is invalid. Sample rate must be a boolean or a number between 0 and 1. Got ${ JSON . stringify (
94- rate ,
95- ) } of type ${ JSON . stringify ( typeof rate ) } .`,
96- ) ;
97- return false ;
71+ return [ false , parsedSampleRate ] ;
9872 }
9973
100- // in case sampleRate is a boolean, it will get automatically cast to 1 if it's true and 0 if it's false
101- if ( rate < 0 || rate > 1 ) {
102- DEBUG_BUILD &&
103- logger . warn ( `[Tracing] Given sample rate is invalid. Sample rate must be between 0 and 1. Got ${ rate } .` ) ;
104- return false ;
105- }
106- return true ;
74+ return [ true , parsedSampleRate ] ;
10775}
0 commit comments