6
6
import sys
7
7
from collections .abc import Mapping
8
8
from datetime import timedelta
9
- from decimal import ROUND_DOWN , Decimal , DefaultContext , localcontext
10
9
from random import Random
11
10
from urllib .parse import quote , unquote
12
11
import uuid
@@ -502,7 +501,7 @@ def _fill_sample_rand(self):
502
501
return
503
502
504
503
sample_rand = try_convert (
505
- Decimal , self .dynamic_sampling_context .get ("sample_rand" )
504
+ float , self .dynamic_sampling_context .get ("sample_rand" )
506
505
)
507
506
if sample_rand is not None and 0 <= sample_rand < 1 :
508
507
# sample_rand is present and valid, so don't overwrite it
@@ -650,7 +649,7 @@ def populate_from_transaction(cls, transaction):
650
649
options = client .options or {}
651
650
652
651
sentry_items ["trace_id" ] = transaction .trace_id
653
- sentry_items ["sample_rand" ] = str ( transaction ._sample_rand )
652
+ sentry_items ["sample_rand" ] = f" { transaction ._sample_rand :.6f } " # noqa: E231
654
653
655
654
if options .get ("environment" ):
656
655
sentry_items ["environment" ] = options ["environment" ]
@@ -724,15 +723,15 @@ def strip_sentry_baggage(header):
724
723
)
725
724
726
725
def _sample_rand (self ):
727
- # type: () -> Optional[Decimal ]
726
+ # type: () -> Optional[float ]
728
727
"""Convenience method to get the sample_rand value from the sentry_items.
729
728
730
- We validate the value and parse it as a Decimal before returning it. The value is considered
731
- valid if it is a Decimal in the range [0, 1).
729
+ We validate the value and parse it as a float before returning it. The value is considered
730
+ valid if it is a float in the range [0, 1).
732
731
"""
733
- sample_rand = try_convert (Decimal , self .sentry_items .get ("sample_rand" ))
732
+ sample_rand = try_convert (float , self .sentry_items .get ("sample_rand" ))
734
733
735
- if sample_rand is not None and Decimal ( 0 ) <= sample_rand < Decimal ( 1 ) :
734
+ if sample_rand is not None and 0.0 <= sample_rand < 1.0 :
736
735
return sample_rand
737
736
738
737
return None
@@ -898,7 +897,7 @@ def _generate_sample_rand(
898
897
* ,
899
898
interval = (0.0 , 1.0 ), # type: tuple[float, float]
900
899
):
901
- # type: (...) -> Decimal
900
+ # type: (...) -> float
902
901
"""Generate a sample_rand value from a trace ID.
903
902
904
903
The generated value will be pseudorandomly chosen from the provided
@@ -913,19 +912,16 @@ def _generate_sample_rand(
913
912
raise ValueError ("Invalid interval: lower must be less than upper" )
914
913
915
914
rng = Random (trace_id )
916
- sample_rand = upper
917
- while sample_rand >= upper :
918
- sample_rand = rng .uniform (lower , upper )
919
-
920
- # Round down to exactly six decimal-digit precision.
921
- # Setting the context is needed to avoid an InvalidOperation exception
922
- # in case the user has changed the default precision or set traps.
923
- with localcontext (DefaultContext ) as ctx :
924
- ctx .prec = 6
925
- return Decimal (sample_rand ).quantize (
926
- Decimal ("0.000001" ),
927
- rounding = ROUND_DOWN ,
928
- )
915
+ lower_scaled = int (lower * 1_000_000 )
916
+ upper_scaled = int (upper * 1_000_000 )
917
+ try :
918
+ sample_rand_scaled = rng .randrange (lower_scaled , upper_scaled )
919
+ except ValueError :
920
+ # In some corner cases it might happen that the range is too small
921
+ # In that case, just take the lower bound
922
+ sample_rand_scaled = lower_scaled
923
+
924
+ return sample_rand_scaled / 1_000_000
929
925
930
926
931
927
def _sample_rand_range (parent_sampled , sample_rate ):
0 commit comments