|
| 1 | +import random |
1 | 2 | from typing import cast
|
2 |
| -from random import random |
3 | 3 |
|
4 | 4 | from opentelemetry import trace
|
5 | 5 |
|
@@ -46,17 +46,33 @@ def get_parent_sampled(parent_context, trace_id):
|
46 | 46 | return None
|
47 | 47 |
|
48 | 48 |
|
49 |
| -def dropped_result(span_context, attributes, sample_rate=None): |
| 49 | +def dropped_result(parent_span_context, attributes, sample_rate=None): |
50 | 50 | # type: (SpanContext, Attributes, Optional[float]) -> SamplingResult
|
51 | 51 | # these will only be added the first time in a root span sampling decision
|
52 |
| - trace_state = span_context.trace_state |
| 52 | + trace_state = parent_span_context.trace_state |
53 | 53 |
|
54 | 54 | if TRACESTATE_SAMPLED_KEY not in trace_state:
|
55 | 55 | trace_state = trace_state.add(TRACESTATE_SAMPLED_KEY, "false")
|
56 | 56 |
|
57 | 57 | if sample_rate and TRACESTATE_SAMPLE_RATE_KEY not in trace_state:
|
58 | 58 | trace_state = trace_state.add(TRACESTATE_SAMPLE_RATE_KEY, str(sample_rate))
|
59 | 59 |
|
| 60 | + is_root_span = not ( |
| 61 | + parent_span_context.is_valid and not parent_span_context.is_remote |
| 62 | + ) |
| 63 | + if is_root_span: |
| 64 | + # Tell Sentry why we dropped the transaction/root-span |
| 65 | + client = sentry_sdk.get_client() |
| 66 | + if client.monitor and client.monitor.downsample_factor > 0: |
| 67 | + reason = "backpressure" |
| 68 | + else: |
| 69 | + reason = "sample_rate" |
| 70 | + |
| 71 | + client.transport.record_lost_event(reason, data_category="transaction") |
| 72 | + |
| 73 | + # Only one span (the transaction itself) is discarded, since we did not record any spans here. |
| 74 | + client.transport.record_lost_event(reason, data_category="span") |
| 75 | + |
60 | 76 | return SamplingResult(
|
61 | 77 | Decision.DROP,
|
62 | 78 | attributes=attributes,
|
@@ -136,9 +152,14 @@ def should_sample(
|
136 | 152 | )
|
137 | 153 | return dropped_result(parent_span_context, attributes)
|
138 | 154 |
|
| 155 | + # Down-sample in case of back pressure monitor says so |
| 156 | + # TODO: this should only be done for transactions (aka root spans) |
| 157 | + if client.monitor: |
| 158 | + sample_rate /= 2**client.monitor.downsample_factor |
| 159 | + |
139 | 160 | # Roll the dice on sample rate
|
140 | 161 | sample_rate = float(cast("Union[bool, float, int]", sample_rate))
|
141 |
| - sampled = random() < sample_rate |
| 162 | + sampled = random.random() < sample_rate |
142 | 163 |
|
143 | 164 | if sampled:
|
144 | 165 | return sampled_result(parent_span_context, attributes, sample_rate)
|
|
0 commit comments