Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions sentry_sdk/profiler/transaction_profiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,12 +290,11 @@ def _set_initial_sampling_decision(
sample_rate = options["profiles_sampler"](sampling_context)
except Exception:
logger.warning(
"[Profiling] profiles_sampler raised; falling back to profiles_sample_rate",
"[Profiling] profiles_sampler raised; unsampling profile",
exc_info=True,
)
sample_rate = options["profiles_sample_rate"]
if sample_rate is None:
sample_rate = options["_experiments"].get("profiles_sample_rate")
self.sampled = False
return
Comment thread
sentrivana marked this conversation as resolved.
Resolved
elif options["profiles_sample_rate"] is not None:
sample_rate = options["profiles_sample_rate"]
else:
Expand Down
9 changes: 3 additions & 6 deletions sentry_sdk/tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -1217,14 +1217,11 @@ def _set_initial_sampling_decision(
sample_rate = client.options["traces_sampler"](sampling_context)
except Exception:
logger.warning(
"[Tracing] traces_sampler raised; falling back to parent sample rate or traces_sample_rate",
"[Tracing] traces_sampler raised; unsampling trace",
exc_info=True,
)
sample_rate = (
sampling_context["parent_sampled"]
if sampling_context["parent_sampled"] is not None
else client.options["traces_sample_rate"]
)
self.sampled = False
return
Comment thread
sentrivana marked this conversation as resolved.
Resolved
else:
sample_rate = (
sampling_context["parent_sampled"]
Expand Down
7 changes: 2 additions & 5 deletions sentry_sdk/tracing_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1702,13 +1702,10 @@ def _make_sampling_decision(
sample_rate = client.options["traces_sampler"](sampling_context)
except Exception:
logger.warning(
"[Tracing] traces_sampler raised; falling back to parent sample rate or traces_sample_rate",
"[Tracing] traces_sampler raised; unsampling trace",
exc_info=True,
)
if propagation_context.parent_sampled is not None:
sample_rate = propagation_context.parent_sampled
else:
sample_rate = client.options["traces_sample_rate"]
return False, None, None, "callback_error"
else:
if propagation_context.parent_sampled is not None:
sample_rate = propagation_context.parent_sampled
Expand Down
5 changes: 2 additions & 3 deletions tests/profiler/test_transaction_profiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ def test_profiles_sampler(

@pytest.mark.tests_internal_exceptions
@mock.patch("sentry_sdk.profiler.transaction_profiler.PROFILE_MINIMUM_SAMPLES", 0)
def test_profiles_sampler_exception_falls_back_to_profiles_sample_rate(
def test_profiles_sampler_exception_unsamples(
sentry_init,
capture_envelopes,
teardown_profiling,
Expand All @@ -263,8 +263,7 @@ def bad_sampler(sampling_context):
items[item.type].append(item)

assert len(items["transaction"]) == 1
# Falls back to profiles_sample_rate=1.0, so profile should be sent
assert len(items["profile"]) == 1
assert len(items["profile"]) == 0


def test_minimum_unique_samples_required(
Expand Down
104 changes: 2 additions & 102 deletions tests/tracing/test_sampling.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,117 +198,17 @@ def test_tolerates_traces_sampler_returning_a_boolean_span_streaming(
assert span.sampled is traces_sampler_return_value


@pytest.mark.parametrize(
"traces_sample_rate,expected_decision",
[(0.0, False), (0.25, False), (0.75, True), (1.00, True)],
)
def test_traces_sampler_raising_falls_back_to_traces_sample_rate(
sentry_init,
traces_sample_rate,
expected_decision,
):
def test_traces_sampler_raising_unsamples(sentry_init):
sentry_init(
traces_sampler=mock.Mock(side_effect=ValueError("boom")),
traces_sample_rate=traces_sample_rate,
traces_sample_rate=1.0,
)

baggage = Baggage(sentry_items={"sample_rand": "0.500000"})
transaction = start_transaction(name="dogpark", baggage=baggage)
assert transaction.sampled is expected_decision


@pytest.mark.parametrize("parent_sampling_decision", [True, False])
def test_traces_sampler_raising_falls_back_to_parent_sampling_decision(
sentry_init, parent_sampling_decision
):
# set traces_sample_rate to produce the opposite of the parent decision,
# to prove the parent's decision takes precedence in the fallback
sentry_init(
traces_sampler=mock.Mock(side_effect=ValueError("boom")),
traces_sample_rate=0.0 if parent_sampling_decision else 1.0,
)

baggage = Baggage(sentry_items={"sample_rand": "0.500000"})
transaction = start_transaction(
name="dogpark", baggage=baggage, parent_sampled=parent_sampling_decision
)
assert transaction.sampled is parent_sampling_decision


@pytest.mark.parametrize(
"traces_sample_rate,expected_decision",
[(0.0, False), (0.25, False), (0.75, True), (1.00, True)],
)
def test_traces_sampler_raising_falls_back_to_traces_sample_rate_span_streaming(
sentry_init,
traces_sample_rate,
expected_decision,
):
sentry_init(
traces_sampler=mock.Mock(side_effect=ValueError("boom")),
traces_sample_rate=traces_sample_rate,
trace_lifecycle="stream",
)

sentry_sdk.traces.continue_trace(
{
"sentry-trace": "0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331",
"baggage": "sentry-sample_rand=0.500000",
}
)

with sentry_sdk.traces.start_span(name="dogpark") as span:
assert span.sampled is expected_decision


@pytest.mark.parametrize(
"traces_sample_rate,expected_decision",
[(0.0, False), (0.25, False), (0.75, True), (1.00, True)],
)
def test_traces_sampler_raising_no_incoming_trace_falls_back_to_traces_sample_rate_span_streaming(
sentry_init,
traces_sample_rate,
expected_decision,
monkeypatch,
):
sentry_init(
traces_sampler=mock.Mock(side_effect=ValueError("boom")),
traces_sample_rate=traces_sample_rate,
trace_lifecycle="stream",
)

# no continue_trace, so no propagated sample_rand; make it deterministic
monkeypatch.setattr(
"sentry_sdk.tracing_utils._generate_sample_rand", lambda *a, **kw: 0.5
)

with sentry_sdk.traces.start_span(name="dogpark") as span:
assert span.sampled is expected_decision


def test_traces_sampler_raising_no_incoming_trace_and_no_traces_sample_rate(
sentry_init,
):
sentry_init(
traces_sampler=mock.Mock(side_effect=ValueError("boom")),
)

transaction = start_transaction(name="dogpark")
assert transaction.sampled is False


def test_traces_sampler_raising_no_incoming_trace_and_no_traces_sample_rate_span_streaming(
sentry_init,
):
sentry_init(
traces_sampler=mock.Mock(side_effect=ValueError("boom")),
trace_lifecycle="stream",
)

with sentry_sdk.traces.start_span(name="dogpark") as span:
assert span.sampled is False


@pytest.mark.parametrize("sampling_decision", [True, False])
def test_only_captures_transaction_when_sampled_is_true(
sentry_init, sampling_decision, capture_events
Expand Down
8 changes: 4 additions & 4 deletions tests/tracing/test_span_streaming.py
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ def traces_sampler(sampling_context):


@pytest.mark.tests_internal_exceptions
def test_traces_sampler_exception_falls_back(sentry_init, capture_items):
def test_traces_sampler_exception_unsamples(sentry_init, capture_items):
def traces_sampler(sampling_context):
raise ValueError("traces_sampler error")

Expand All @@ -580,11 +580,11 @@ def traces_sampler(sampling_context):
with sentry_sdk.traces.start_span(name="test"):
...

sentry_sdk.get_client().flush()
sentry_sdk.flush()

spans = [item.payload for item in items]

# Falls back to traces_sample_rate=1.0, so span should still be sent
assert len(spans) == 1
assert not spans


def test_traces_sampler_called_once_per_segment(sentry_init):
Expand Down
Loading