From 7120d06f9b69e51ac1d37e20069e608b7dc99f5a Mon Sep 17 00:00:00 2001 From: Tony Xiao Date: Fri, 5 Sep 2025 13:06:04 -0400 Subject: [PATCH 1/3] fix(profiling): Re-init continuous profiler Re-initializing the continuous profiler should use new settings. --- sentry_sdk/profiler/continuous_profiler.py | 9 ++++++++- tests/profiler/test_continuous_profiler.py | 11 ++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/sentry_sdk/profiler/continuous_profiler.py b/sentry_sdk/profiler/continuous_profiler.py index 00dd29e36c..08b3679b03 100644 --- a/sentry_sdk/profiler/continuous_profiler.py +++ b/sentry_sdk/profiler/continuous_profiler.py @@ -77,7 +77,7 @@ def setup_continuous_profiler(options, sdk_info, capture_func): if _scheduler is not None: logger.debug("[Profiling] Continuous Profiler is already setup") - return False + teardown_continuous_profiler() if is_gevent(): # If gevent has patched the threading modules then we cannot rely on @@ -122,6 +122,13 @@ def setup_continuous_profiler(options, sdk_info, capture_func): return True +def is_profile_session_sampled(): + # type: () -> bool + if _scheduler is None: + return False + return _scheduler.sampled + + def try_autostart_continuous_profiler(): # type: () -> None diff --git a/tests/profiler/test_continuous_profiler.py b/tests/profiler/test_continuous_profiler.py index 7283ec7164..2ce812dc3f 100644 --- a/tests/profiler/test_continuous_profiler.py +++ b/tests/profiler/test_continuous_profiler.py @@ -8,6 +8,7 @@ import sentry_sdk from sentry_sdk.consts import VERSION from sentry_sdk.profiler.continuous_profiler import ( + is_profile_session_sampled, get_profiler_id, setup_continuous_profiler, start_profiler, @@ -113,19 +114,23 @@ def test_continuous_profiler_valid_mode(mode, make_options, teardown_profiling): ], ) def test_continuous_profiler_setup_twice(mode, make_options, teardown_profiling): - options = make_options(mode=mode) # setting up the first time should return True to indicate success + options = make_options(mode=mode, profile_session_sample_rate=0.0) assert setup_continuous_profiler( options, mock_sdk_info, lambda envelope: None, ) - # setting up the second time should return False to indicate no-op - assert not setup_continuous_profiler( + assert not is_profile_session_sampled() + + # setting up the second time should return True to indicate re-init + options = make_options(mode=mode, profile_session_sample_rate=1.0) + assert setup_continuous_profiler( options, mock_sdk_info, lambda envelope: None, ) + assert is_profile_session_sampled() def assert_single_transaction_with_profile_chunks( From f189f0fd6abb83eec77186a5a3b9bd1148d7594e Mon Sep 17 00:00:00 2001 From: Tony Xiao Date: Fri, 5 Sep 2025 13:37:24 -0400 Subject: [PATCH 2/3] do not set up atexit twice --- sentry_sdk/profiler/continuous_profiler.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sentry_sdk/profiler/continuous_profiler.py b/sentry_sdk/profiler/continuous_profiler.py index 08b3679b03..165bd13837 100644 --- a/sentry_sdk/profiler/continuous_profiler.py +++ b/sentry_sdk/profiler/continuous_profiler.py @@ -75,7 +75,9 @@ def setup_continuous_profiler(options, sdk_info, capture_func): # type: (Dict[str, Any], SDKInfo, Callable[[Envelope], None]) -> bool global _scheduler - if _scheduler is not None: + already_initialized = _scheduler is not None + + if already_initialized: logger.debug("[Profiling] Continuous Profiler is already setup") teardown_continuous_profiler() @@ -117,7 +119,8 @@ def setup_continuous_profiler(options, sdk_info, capture_func): ) ) - atexit.register(teardown_continuous_profiler) + if not already_initialized: + atexit.register(teardown_continuous_profiler) return True From 4ea8286c214db4cadc2acb295b0a0b35564f424c Mon Sep 17 00:00:00 2001 From: Tony Xiao Date: Fri, 5 Sep 2025 13:38:28 -0400 Subject: [PATCH 3/3] more coverage --- tests/profiler/test_continuous_profiler.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/profiler/test_continuous_profiler.py b/tests/profiler/test_continuous_profiler.py index 2ce812dc3f..e4f5cb5e25 100644 --- a/tests/profiler/test_continuous_profiler.py +++ b/tests/profiler/test_continuous_profiler.py @@ -114,23 +114,25 @@ def test_continuous_profiler_valid_mode(mode, make_options, teardown_profiling): ], ) def test_continuous_profiler_setup_twice(mode, make_options, teardown_profiling): + assert not is_profile_session_sampled() + # setting up the first time should return True to indicate success - options = make_options(mode=mode, profile_session_sample_rate=0.0) + options = make_options(mode=mode, profile_session_sample_rate=1.0) assert setup_continuous_profiler( options, mock_sdk_info, lambda envelope: None, ) - assert not is_profile_session_sampled() + assert is_profile_session_sampled() # setting up the second time should return True to indicate re-init - options = make_options(mode=mode, profile_session_sample_rate=1.0) + options = make_options(mode=mode, profile_session_sample_rate=0.0) assert setup_continuous_profiler( options, mock_sdk_info, lambda envelope: None, ) - assert is_profile_session_sampled() + assert not is_profile_session_sampled() def assert_single_transaction_with_profile_chunks(