|
7 | 7 | from sentry_sdk.consts import INSTRUMENTER, SPANSTATUS, SPANDATA |
8 | 8 | from sentry_sdk.profiler.continuous_profiler import get_profiler_id |
9 | 9 | from sentry_sdk.utils import ( |
| 10 | + event_from_exception, |
10 | 11 | get_current_thread_meta, |
11 | 12 | is_valid_sample_rate, |
12 | 13 | logger, |
@@ -1143,9 +1144,12 @@ def _set_initial_sampling_decision(self, sampling_context): |
1143 | 1144 | # we would have bailed already if neither `traces_sampler` nor |
1144 | 1145 | # `traces_sample_rate` were defined, so one of these should work; prefer |
1145 | 1146 | # the hook if so |
| 1147 | + traces_sampler_rate = _rate_from_traces_sampler( |
| 1148 | + client.options.get("traces_sampler"), sampling_context |
| 1149 | + ) |
1146 | 1150 | sample_rate = ( |
1147 | | - client.options["traces_sampler"](sampling_context) |
1148 | | - if callable(client.options.get("traces_sampler")) |
| 1151 | + traces_sampler_rate |
| 1152 | + if traces_sampler_rate is not None |
1149 | 1153 | else ( |
1150 | 1154 | # default inheritance behavior |
1151 | 1155 | sampling_context["parent_sampled"] |
@@ -1341,6 +1345,23 @@ async def my_async_function(): |
1341 | 1345 | return start_child_span_decorator |
1342 | 1346 |
|
1343 | 1347 |
|
| 1348 | +def _rate_from_traces_sampler(traces_sampler, sampling_context): |
| 1349 | + # type: (Any, SamplingContext) -> Optional[Any] |
| 1350 | + if not callable(traces_sampler): |
| 1351 | + return None |
| 1352 | + |
| 1353 | + try: |
| 1354 | + return traces_sampler(sampling_context) |
| 1355 | + except Exception as e: |
| 1356 | + event, hint = event_from_exception( |
| 1357 | + e, |
| 1358 | + mechanism={"type": "traces_sampler", "handled": False}, |
| 1359 | + ) |
| 1360 | + sentry_sdk.capture_event(event, hint) |
| 1361 | + logger.error("Unhandled exception in traces_sampler", exc_info=True) |
| 1362 | + return None |
| 1363 | + |
| 1364 | + |
1344 | 1365 | # Circular imports |
1345 | 1366 |
|
1346 | 1367 | from sentry_sdk.tracing_utils import ( |
|
0 commit comments