1
1
import copy
2
2
import inspect
3
+ import random
3
4
4
5
import sentry_sdk
5
6
from django .conf import settings
111
112
112
113
113
114
UNSAFE_TAG = "_unsafe"
115
+ EXPERIMENT_TAG = "_experimental_event"
114
116
115
117
116
118
def is_current_event_safe ():
@@ -137,6 +139,16 @@ def is_current_event_safe():
137
139
return True
138
140
139
141
142
+ def is_current_event_experimental ():
143
+ """
144
+ Checks if the event was explicitly marked as experimental.
145
+ """
146
+ with configure_scope () as scope :
147
+ if scope ._tags .get (EXPERIMENT_TAG ):
148
+ return True
149
+ return False
150
+
151
+
140
152
def mark_scope_as_unsafe ():
141
153
"""
142
154
Set the unsafe tag on the SDK scope for outgoing crashes and transactions.
@@ -148,6 +160,16 @@ def mark_scope_as_unsafe():
148
160
scope .set_tag (UNSAFE_TAG , True )
149
161
150
162
163
+ def mark_scope_as_experimental ():
164
+ """
165
+ Set the experimental tag on the SDK scope for outgoing crashes and transactions.
166
+
167
+ Marking the scope will cause these crashes and transaction to be sent to a separate experimental dsn.
168
+ """
169
+ with configure_scope () as scope :
170
+ scope .set_tag (EXPERIMENT_TAG , True )
171
+
172
+
151
173
def set_current_event_project (project_id ):
152
174
"""
153
175
Set the current project on the SDK scope for outgoing crash reports.
@@ -249,6 +271,7 @@ def configure_sdk():
249
271
sdk_options = dict (settings .SENTRY_SDK_CONFIG )
250
272
251
273
relay_dsn = sdk_options .pop ("relay_dsn" , None )
274
+ experimental_dsn = sdk_options .pop ("experimental_dsn" , None )
252
275
internal_project_key = get_project_key ()
253
276
upstream_dsn = sdk_options .pop ("dsn" , None )
254
277
sdk_options ["traces_sampler" ] = traces_sampler
@@ -274,6 +297,12 @@ def configure_sdk():
274
297
else :
275
298
relay_transport = None
276
299
300
+ if experimental_dsn :
301
+ transport = make_transport (get_options (dsn = experimental_dsn , ** sdk_options ))
302
+ experimental_transport = patch_transport_for_instrumentation (transport , "experimental" )
303
+ else :
304
+ experimental_transport = None
305
+
277
306
class MultiplexingTransport (sentry_sdk .transport .Transport ):
278
307
def capture_envelope (self , envelope ):
279
308
# Temporarily capture envelope counts to compare to ingested
@@ -299,6 +328,14 @@ def capture_event(self, event):
299
328
self ._capture_anything ("capture_event" , event )
300
329
301
330
def _capture_anything (self , method_name , * args , ** kwargs ):
331
+ # Experimental events will be sent to the experimental transport.
332
+ if experimental_transport :
333
+ rate = options .get ("store.use-experimental-dsn-sample-rate" )
334
+ if is_current_event_experimental ():
335
+ if rate and random .random () < rate :
336
+ getattr (experimental_transport , method_name )(* args , ** kwargs )
337
+ # Experimental events should not be sent to other transports even if they are not sampled.
338
+ return
302
339
303
340
# Upstream should get the event first because it is most isolated from
304
341
# the this sentry installation.
0 commit comments