Skip to content

Enable tracing without performance by default #4240

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Apr 9, 2025
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
1 change: 1 addition & 0 deletions MIGRATION_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Looking to upgrade from Sentry SDK 2.x to 3.x? Here's a comprehensive list of wh
### Changed

- The SDK now supports Python 3.7 and higher.
- The default of `traces_sample_rate` changed to `0`. Meaning: Incoming traces will be continued by default. For example, if your frontend sends a `sentry-trace/baggage` headers pair, your SDK will create Spans and send them to Sentry. (The default used to be `None` meaning by default no Spans where created, no matter what headers the frontend sent to your project.) See also: https://docs.sentry.io/platforms/python/configuration/options/#traces_sample_rate
- `sentry_sdk.start_span` now only takes keyword arguments.
- `sentry_sdk.start_transaction`/`sentry_sdk.start_span` no longer takes the following arguments: `span`, `parent_sampled`, `trace_id`, `span_id` or `parent_span_id`.
- You can no longer change the sampled status of a span with `span.sampled = False` after starting it.
Expand Down
2 changes: 1 addition & 1 deletion sentry_sdk/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ def __init__(
debug=None, # type: Optional[bool]
attach_stacktrace=False, # type: bool
ca_certs=None, # type: Optional[str]
traces_sample_rate=None, # type: Optional[float]
traces_sample_rate=0, # type: Optional[float]
traces_sampler=None, # type: Optional[TracesSampler]
profiles_sample_rate=None, # type: Optional[float]
profiles_sampler=None, # type: Optional[TracesSampler]
Expand Down
5 changes: 4 additions & 1 deletion tests/integrations/aiohttp/test_aiohttp.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,10 @@ async def hello(request):
async def test_trace_from_headers_if_performance_disabled(
sentry_init, aiohttp_client, capture_events
):
sentry_init(integrations=[AioHttpIntegration()])
sentry_init(
integrations=[AioHttpIntegration()],
traces_sample_rate=None, # disable all performance monitoring
)

async def hello(request):
capture_message("It's a good day to try dividing by 0")
Expand Down
8 changes: 6 additions & 2 deletions tests/integrations/asgi/test_asgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,9 @@ async def test_has_trace_if_performance_disabled(
asgi3_app_with_error_and_msg,
capture_events,
):
sentry_init()
sentry_init(
traces_sample_rate=None, # disable all performance monitoring
)
app = SentryAsgiMiddleware(asgi3_app_with_error_and_msg)

with pytest.raises(ZeroDivisionError):
Expand Down Expand Up @@ -325,7 +327,9 @@ async def test_trace_from_headers_if_performance_disabled(
asgi3_app_with_error_and_msg,
capture_events,
):
sentry_init()
sentry_init(
traces_sample_rate=None, # disable all performance monitoring
)
app = SentryAsgiMiddleware(asgi3_app_with_error_and_msg)

trace_id = "582b43a4192642f0b136d5159a501701"
Expand Down
2 changes: 2 additions & 0 deletions tests/integrations/django/asgi/test_asgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ async def test_has_trace_if_performance_enabled(sentry_init, capture_events):
async def test_has_trace_if_performance_disabled(sentry_init, capture_events):
sentry_init(
integrations=[DjangoIntegration()],
traces_sample_rate=None, # disable all performance monitoring
)

events = capture_events()
Expand Down Expand Up @@ -386,6 +387,7 @@ async def test_trace_from_headers_if_performance_enabled(sentry_init, capture_ev
async def test_trace_from_headers_if_performance_disabled(sentry_init, capture_events):
sentry_init(
integrations=[DjangoIntegration()],
traces_sample_rate=None, # disable all performance monitoring
)

events = capture_events()
Expand Down
1 change: 1 addition & 0 deletions tests/integrations/django/test_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ def test_trace_from_headers_if_performance_disabled(
http_methods_to_capture=("HEAD",),
)
],
traces_sample_rate=None, # disable all performance monitoring
)

events = capture_events()
Expand Down
28 changes: 16 additions & 12 deletions tests/integrations/opentelemetry/test_sampler.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@
import sentry_sdk


USE_DEFAULT_TRACES_SAMPLE_RATE = -1

tracer = trace.get_tracer(__name__)


@pytest.mark.parametrize(
"traces_sample_rate, expected_num_of_envelopes",
[
# special case for testing, do not pass any traces_sample_rate to init() (the default traces_sample_rate=None will be used)
(-1, 0),
# special case for testing, do not pass any traces_sample_rate to init() (the default traces_sample_rate=0 will be used)
(USE_DEFAULT_TRACES_SAMPLE_RATE, 0),
# traces_sample_rate=None means do not create new traces, and also do not continue incoming traces. So, no envelopes at all.
(None, 0),
# traces_sample_rate=0 means do not create new traces (0% of the requests), but continue incoming traces. So envelopes will be created only if there is an incoming trace.
Expand All @@ -29,7 +31,7 @@ def test_sampling_traces_sample_rate_0_or_100(
expected_num_of_envelopes,
):
kwargs = {}
if traces_sample_rate != -1:
if traces_sample_rate != USE_DEFAULT_TRACES_SAMPLE_RATE:
kwargs["traces_sample_rate"] = traces_sample_rate

sentry_init(**kwargs)
Expand Down Expand Up @@ -176,8 +178,8 @@ def keep_only_a(sampling_context):
@pytest.mark.parametrize(
"traces_sample_rate, expected_num_of_envelopes",
[
# special case for testing, do not pass any traces_sample_rate to init() (the default traces_sample_rate=None will be used)
(-1, 0),
# special case for testing, do not pass any traces_sample_rate to init() (the default traces_sample_rate=0 will be used)
(USE_DEFAULT_TRACES_SAMPLE_RATE, 1),
# traces_sample_rate=None means do not create new traces, and also do not continue incoming traces. So, no envelopes at all.
(None, 0),
# traces_sample_rate=0 means do not create new traces (0% of the requests), but continue incoming traces. So envelopes will be created only if there is an incoming trace.
Expand All @@ -193,7 +195,7 @@ def test_sampling_parent_sampled(
capture_envelopes,
):
kwargs = {}
if traces_sample_rate != -1:
if traces_sample_rate != USE_DEFAULT_TRACES_SAMPLE_RATE:
kwargs["traces_sample_rate"] = traces_sample_rate

sentry_init(**kwargs)
Expand Down Expand Up @@ -227,9 +229,11 @@ def test_sampling_parent_sampled(
@pytest.mark.parametrize(
"traces_sample_rate, upstream_sampled, expected_num_of_envelopes",
[
# special case for testing, do not pass any traces_sample_rate to init() (the default traces_sample_rate=None will be used)
(-1, 0, 0),
# special case for testing, do not pass any traces_sample_rate to init() (the default traces_sample_rate=0 will be used)
(USE_DEFAULT_TRACES_SAMPLE_RATE, 0, 0),
(USE_DEFAULT_TRACES_SAMPLE_RATE, 1, 1),
# traces_sample_rate=None means do not create new traces, and also do not continue incoming traces. So, no envelopes at all.
(None, 0, 0),
(None, 1, 0),
# traces_sample_rate=0 means do not create new traces (0% of the requests), but continue incoming traces. So envelopes will be created only if there is an incoming trace.
(0, 0, 0),
Expand All @@ -247,7 +251,7 @@ def test_sampling_parent_dropped(
capture_envelopes,
):
kwargs = {}
if traces_sample_rate != -1:
if traces_sample_rate != USE_DEFAULT_TRACES_SAMPLE_RATE:
kwargs["traces_sample_rate"] = traces_sample_rate

sentry_init(**kwargs)
Expand Down Expand Up @@ -281,8 +285,8 @@ def test_sampling_parent_dropped(
@pytest.mark.parametrize(
"traces_sample_rate, expected_num_of_envelopes",
[
# special case for testing, do not pass any traces_sample_rate to init() (the default traces_sample_rate=None will be used)
(-1, 0),
# special case for testing, do not pass any traces_sample_rate to init() (the default traces_sample_rate=0 will be used)
(USE_DEFAULT_TRACES_SAMPLE_RATE, 0),
# traces_sample_rate=None means do not create new traces, and also do not continue incoming traces. So, no envelopes at all.
(None, 0),
# traces_sample_rate=0 means do not create new traces (0% of the requests), but continue incoming traces. So envelopes will be created only if there is an incoming trace.
Expand All @@ -298,7 +302,7 @@ def test_sampling_parent_deferred(
capture_envelopes,
):
kwargs = {}
if traces_sample_rate != -1:
if traces_sample_rate != USE_DEFAULT_TRACES_SAMPLE_RATE:
kwargs["traces_sample_rate"] = traces_sample_rate

sentry_init(**kwargs)
Expand Down
8 changes: 6 additions & 2 deletions tests/integrations/wsgi/test_wsgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,9 @@ def dogpark(environ, start_response):
capture_message("Attempting to fetch the ball")
raise ValueError("Fetch aborted. The ball was not returned.")

sentry_init()
sentry_init(
traces_sample_rate=None, # disable all performance monitoring
)
app = SentryWsgiMiddleware(dogpark)
client = Client(app)
events = capture_events()
Expand Down Expand Up @@ -301,7 +303,9 @@ def dogpark(environ, start_response):
capture_message("Attempting to fetch the ball")
raise ValueError("Fetch aborted. The ball was not returned.")

sentry_init()
sentry_init(
traces_sample_rate=None, # disable all performance monitoring
)
app = SentryWsgiMiddleware(dogpark)
client = Client(app)
events = capture_events()
Expand Down
4 changes: 2 additions & 2 deletions tests/test_dsc.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,8 +287,8 @@ def my_traces_sampler(sampling_context):
"local_traces_sampler_result": None,
"local_traces_sample_rate": None,
},
None, # expected_sample_rate
"tracing-disabled-no-transactions-should-be-sent", # expected_sampled (traces_sample_rate=None disables all transaction creation)
1.0, # expected_sample_rate
"true", # expected_sampled
),
( # 6 traces_sampler overrides incoming (traces_sample_rate not set)
{
Expand Down
4 changes: 2 additions & 2 deletions tests/tracing/test_sample_rand_propagation.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def test_continue_trace_with_sample_rand(sentry_init):
sentry_init()

headers = {
"sentry-trace": "00000000000000000000000000000000-0000000000000000-0",
"sentry-trace": "771a43a4192642f0b136d5159a501700-1234567890abcdef-0",
"baggage": "sentry-sample_rand=0.1,sentry-sample_rate=0.5",
}

Expand All @@ -34,7 +34,7 @@ def test_continue_trace_missing_sample_rand(sentry_init):
sentry_init()

headers = {
"sentry-trace": "00000000000000000000000000000000-0000000000000000",
"sentry-trace": "771a43a4192642f0b136d5159a501700-1234567890abcdef",
"baggage": "sentry-placeholder=asdf",
}

Expand Down
5 changes: 4 additions & 1 deletion tests/tracing/test_sampling.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,10 @@ def test_records_lost_event_only_if_traces_sampler_enabled(
sampled_output,
expected_record_lost_event_calls,
):
sentry_init(traces_sampler=traces_sampler)
sentry_init(
traces_sample_rate=None,
traces_sampler=traces_sampler,
)
record_lost_event_calls = capture_record_lost_event_calls()

with start_span(name="dogpark") as span:
Expand Down
Loading
Loading