1
- import type { ClientOptions , CustomSamplingContext , Options , SamplingContext , TransactionContext } from '@sentry/types' ;
2
- import { isNaN , logger } from '@sentry/utils' ;
1
+ import type { ClientOptions , CustomSamplingContext , TransactionContext } from '@sentry/types' ;
2
+ import { logger } from '@sentry/utils' ;
3
3
4
4
import type { Hub } from '../hub' ;
5
5
import { getMainCarrier } from '../hub' ;
6
- import { hasTracingEnabled } from '../utils/hasTracingEnabled' ;
7
6
import { registerErrorInstrumentation } from './errors' ;
8
7
import { IdleTransaction } from './idletransaction' ;
8
+ import { sampleTransaction } from './sampling' ;
9
9
import { Transaction } from './transaction' ;
10
10
11
11
/** Returns all trace headers that are currently on the top scope. */
@@ -20,126 +20,6 @@ function traceHeaders(this: Hub): { [key: string]: string } {
20
20
: { } ;
21
21
}
22
22
23
- /**
24
- * Makes a sampling decision for the given transaction and stores it on the transaction.
25
- *
26
- * Called every time a transaction is created. Only transactions which emerge with a `sampled` value of `true` will be
27
- * sent to Sentry.
28
- *
29
- * @param transaction: The transaction needing a sampling decision
30
- * @param options: The current client's options, so we can access `tracesSampleRate` and/or `tracesSampler`
31
- * @param samplingContext: Default and user-provided data which may be used to help make the decision
32
- *
33
- * @returns The given transaction with its `sampled` value set
34
- */
35
- function sample < T extends Transaction > (
36
- transaction : T ,
37
- options : Pick < Options , 'tracesSampleRate' | 'tracesSampler' | 'enableTracing' > ,
38
- samplingContext : SamplingContext ,
39
- ) : T {
40
- // nothing to do if tracing is not enabled
41
- if ( ! hasTracingEnabled ( options ) ) {
42
- transaction . sampled = false ;
43
- return transaction ;
44
- }
45
-
46
- // if the user has forced a sampling decision by passing a `sampled` value in their transaction context, go with that
47
- if ( transaction . sampled !== undefined ) {
48
- transaction . setMetadata ( {
49
- sampleRate : Number ( transaction . sampled ) ,
50
- } ) ;
51
- return transaction ;
52
- }
53
-
54
- // we would have bailed already if neither `tracesSampler` nor `tracesSampleRate` nor `enableTracing` were defined, so one of these should
55
- // work; prefer the hook if so
56
- let sampleRate ;
57
- if ( typeof options . tracesSampler === 'function' ) {
58
- sampleRate = options . tracesSampler ( samplingContext ) ;
59
- transaction . setMetadata ( {
60
- sampleRate : Number ( sampleRate ) ,
61
- } ) ;
62
- } else if ( samplingContext . parentSampled !== undefined ) {
63
- sampleRate = samplingContext . parentSampled ;
64
- } else if ( typeof options . tracesSampleRate !== 'undefined' ) {
65
- sampleRate = options . tracesSampleRate ;
66
- transaction . setMetadata ( {
67
- sampleRate : Number ( sampleRate ) ,
68
- } ) ;
69
- } else {
70
- // When `enableTracing === true`, we use a sample rate of 100%
71
- sampleRate = 1 ;
72
- transaction . setMetadata ( {
73
- sampleRate,
74
- } ) ;
75
- }
76
-
77
- // Since this is coming from the user (or from a function provided by the user), who knows what we might get. (The
78
- // only valid values are booleans or numbers between 0 and 1.)
79
- if ( ! isValidSampleRate ( sampleRate ) ) {
80
- __DEBUG_BUILD__ && logger . warn ( '[Tracing] Discarding transaction because of invalid sample rate.' ) ;
81
- transaction . sampled = false ;
82
- return transaction ;
83
- }
84
-
85
- // if the function returned 0 (or false), or if `tracesSampleRate` is 0, it's a sign the transaction should be dropped
86
- if ( ! sampleRate ) {
87
- __DEBUG_BUILD__ &&
88
- logger . log (
89
- `[Tracing] Discarding transaction because ${
90
- typeof options . tracesSampler === 'function'
91
- ? 'tracesSampler returned 0 or false'
92
- : 'a negative sampling decision was inherited or tracesSampleRate is set to 0'
93
- } `,
94
- ) ;
95
- transaction . sampled = false ;
96
- return transaction ;
97
- }
98
-
99
- // Now we roll the dice. Math.random is inclusive of 0, but not of 1, so strict < is safe here. In case sampleRate is
100
- // a boolean, the < comparison will cause it to be automatically cast to 1 if it's true and 0 if it's false.
101
- transaction . sampled = Math . random ( ) < ( sampleRate as number | boolean ) ;
102
-
103
- // if we're not going to keep it, we're done
104
- if ( ! transaction . sampled ) {
105
- __DEBUG_BUILD__ &&
106
- logger . log (
107
- `[Tracing] Discarding transaction because it's not included in the random sample (sampling rate = ${ Number (
108
- sampleRate ,
109
- ) } )`,
110
- ) ;
111
- return transaction ;
112
- }
113
-
114
- __DEBUG_BUILD__ && logger . log ( `[Tracing] starting ${ transaction . op } transaction - ${ transaction . name } ` ) ;
115
- return transaction ;
116
- }
117
-
118
- /**
119
- * Checks the given sample rate to make sure it is valid type and value (a boolean, or a number between 0 and 1).
120
- */
121
- function isValidSampleRate ( rate : unknown ) : boolean {
122
- // we need to check NaN explicitly because it's of type 'number' and therefore wouldn't get caught by this typecheck
123
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
124
- if ( isNaN ( rate ) || ! ( typeof rate === 'number' || typeof rate === 'boolean' ) ) {
125
- __DEBUG_BUILD__ &&
126
- logger . warn (
127
- `[Tracing] Given sample rate is invalid. Sample rate must be a boolean or a number between 0 and 1. Got ${ JSON . stringify (
128
- rate ,
129
- ) } of type ${ JSON . stringify ( typeof rate ) } .`,
130
- ) ;
131
- return false ;
132
- }
133
-
134
- // in case sampleRate is a boolean, it will get automatically cast to 1 if it's true and 0 if it's false
135
- if ( rate < 0 || rate > 1 ) {
136
- __DEBUG_BUILD__ &&
137
- logger . warn ( `[Tracing] Given sample rate is invalid. Sample rate must be between 0 and 1. Got ${ rate } .` ) ;
138
- return false ;
139
- }
140
- return true ;
141
- }
142
-
143
23
/**
144
24
* Creates a new transaction and adds a sampling decision if it doesn't yet have one.
145
25
*
@@ -177,7 +57,7 @@ The transaction will not be sampled. Please use the ${configInstrumenter} instru
177
57
}
178
58
179
59
let transaction = new Transaction ( transactionContext , this ) ;
180
- transaction = sample ( transaction , options , {
60
+ transaction = sampleTransaction ( transaction , options , {
181
61
parentSampled : transactionContext . parentSampled ,
182
62
transactionContext,
183
63
...customSamplingContext ,
@@ -207,7 +87,7 @@ export function startIdleTransaction(
207
87
const options : Partial < ClientOptions > = ( client && client . getOptions ( ) ) || { } ;
208
88
209
89
let transaction = new IdleTransaction ( transactionContext , hub , idleTimeout , finalTimeout , heartbeatInterval , onScope ) ;
210
- transaction = sample ( transaction , options , {
90
+ transaction = sampleTransaction ( transaction , options , {
211
91
parentSampled : transactionContext . parentSampled ,
212
92
transactionContext,
213
93
...customSamplingContext ,
0 commit comments