@@ -263,6 +263,10 @@ def iter_headers(self):
263
263
"""
264
264
Creates a generator which returns the span's `sentry-trace` and
265
265
`tracestate` headers.
266
+
267
+ If the span's containing transaction doesn't yet have a
268
+ `sentry_tracestate` value, this will cause one to be generated and
269
+ stored.
266
270
"""
267
271
yield "sentry-trace" , self .to_traceparent ()
268
272
@@ -310,19 +314,21 @@ def to_tracestate(self):
310
314
Computes the `tracestate` header value using data from the containing
311
315
transaction.
312
316
317
+ If the containing transaction doesn't yet have a `sentry_tracestate`
318
+ value, this will cause one to be generated and stored.
319
+
320
+ If there is no containing transaction, a value will be generated but not
321
+ stored.
322
+
313
323
Returns None if there's no client and/or no DSN.
314
324
"""
315
325
316
- transaction = self .containing_transaction
317
-
318
- # we should have the relevant values stored on the transaction, but if
319
- # this is an orphan span, make a new value
320
- if transaction :
321
- sentry_tracestate = transaction ._sentry_tracestate
322
- third_party_tracestate = transaction ._third_party_tracestate
323
- else :
324
- sentry_tracestate = compute_tracestate_entry (self )
325
- third_party_tracestate = None
326
+ sentry_tracestate = self .get_or_set_sentry_tracestate ()
327
+ third_party_tracestate = (
328
+ self .containing_transaction ._third_party_tracestate
329
+ if self .containing_transaction
330
+ else None
331
+ )
326
332
327
333
if not sentry_tracestate :
328
334
return None
@@ -334,6 +340,25 @@ def to_tracestate(self):
334
340
335
341
return header_value
336
342
343
+ def get_or_set_sentry_tracestate (self ):
344
+ # type: (Span) -> Optional[str]
345
+ """
346
+ Read sentry tracestate off of the span's containing transaction.
347
+
348
+ If the transaction doesn't yet have a `_sentry_tracestate` value,
349
+ compute one and store it.
350
+ """
351
+ transaction = self .containing_transaction
352
+
353
+ if transaction :
354
+ if not transaction ._sentry_tracestate :
355
+ transaction ._sentry_tracestate = compute_tracestate_entry (self )
356
+
357
+ return transaction ._sentry_tracestate
358
+
359
+ # orphan span - nowhere to store the value, so just return it
360
+ return compute_tracestate_entry (self )
361
+
337
362
def set_tag (self , key , value ):
338
363
# type: (str, Any) -> None
339
364
self ._tags [key ] = value
@@ -440,10 +465,14 @@ def get_trace_context(self):
440
465
if self .status :
441
466
rv ["status" ] = self .status
442
467
443
- transaction = self .containing_transaction
468
+ # if the transaction didn't inherit a tracestate value, and no outgoing
469
+ # requests - whose need for headers would have caused a tracestate value
470
+ # to be created - were made as part of the transaction, the transaction
471
+ # still won't have a tracestate value, so compute one now
472
+ sentry_tracestate = self .get_or_set_sentry_tracestate ()
444
473
445
- if transaction :
446
- rv ["tracestate" ] = transaction . _sentry_tracestate
474
+ if sentry_tracestate :
475
+ rv ["tracestate" ] = sentry_tracestate
447
476
448
477
return rv
449
478
@@ -482,7 +511,10 @@ def __init__(
482
511
Span .__init__ (self , ** kwargs )
483
512
self .name = name
484
513
self .parent_sampled = parent_sampled
485
- self ._sentry_tracestate = sentry_tracestate or compute_tracestate_entry (self )
514
+ # if tracestate isn't inherited and set here, it will get set lazily,
515
+ # either the first time an outgoing request needs it for a header or the
516
+ # first time an event needs it for inclusion in the captured data
517
+ self ._sentry_tracestate = sentry_tracestate
486
518
self ._third_party_tracestate = third_party_tracestate
487
519
488
520
def __repr__ (self ):
0 commit comments