feat(profiling): Add support for profiles_sample_rate (#1613) · gitcommit90/sentry-python@b36d84a · GitHub
Skip to content

Commit b36d84a

Browse files
authored
feat(profiling): Add support for profiles_sample_rate (getsentry#1613)
This changes the way profiling is enabled in the python sdk by allowing the end user to specify a `profiles_sample_rate` which is used to control the sampling of profiles. This sample rate is relative to the `traces_sample_rate` meaning the true sample rate of profiles is approximately equal to `traces_sample_rate * profiles_sample_rate`.
1 parent 0e6aa6d commit b36d84a

5 files changed

Lines changed: 55 additions & 54 deletions

File tree

sentry_sdk/client.py

Lines changed: 8 additions & 0 deletions

sentry_sdk/consts.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"smart_transaction_trimming": Optional[bool],
3535
"propagate_tracestate": Optional[bool],
3636
"custom_measurements": Optional[bool],
37-
"enable_profiling": Optional[bool],
37+
"profiles_sample_rate": Optional[float],
3838
},
3939
total=False,
4040
)

sentry_sdk/integrations/profiling.py

Lines changed: 0 additions & 14 deletions
This file was deleted.

sentry_sdk/profiler.py

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import atexit
1616
import platform
17+
import random
1718
import signal
1819
import threading
1920
import time
@@ -63,7 +64,7 @@ def nanosecond_time():
6364
_scheduler = None # type: Optional[_Scheduler]
6465

6566

66-
def _setup_profiler(buffer_secs=60, frequency=101):
67+
def setup_profiler(buffer_secs=60, frequency=101):
6768
# type: (int, int) -> None
6869

6970
"""
@@ -90,17 +91,15 @@ def _setup_profiler(buffer_secs=60, frequency=101):
9091
# This setups a process wide signal handler that will be called
9192
# at an interval to record samples.
9293
signal.signal(signal.SIGPROF, _sample_stack)
93-
atexit.register(_teardown_profiler)
94+
atexit.register(teardown_profiler)
9495

9596

96-
def _teardown_profiler():
97+
def teardown_profiler():
9798
# type: () -> None
9899

99100
global _sample_buffer
100101
global _scheduler
101102

102-
assert _sample_buffer is not None and _scheduler is not None
103-
104103
_sample_buffer = None
105104
_scheduler = None
106105

@@ -328,17 +327,37 @@ def stop_profiling(self):
328327
return should_stop_timer
329328

330329

331-
def _has_profiling_enabled():
332-
# type: () -> bool
333-
return _sample_buffer is not None and _scheduler is not None
330+
def _should_profile(hub):
331+
# type: (Optional[sentry_sdk.Hub]) -> bool
332+
333+
# The profiler hasn't been properly initialized.
334+
if _sample_buffer is None or _scheduler is None:
335+
return False
336+
337+
hub = hub or sentry_sdk.Hub.current
338+
client = hub.client
339+
340+
# The client is None, so we can't get the sample rate.
341+
if client is None:
342+
return False
343+
344+
options = client.options
345+
profiles_sample_rate = options["_experiments"].get("profiles_sample_rate")
346+
347+
# The profiles_sample_rate option was not set, so profiling
348+
# was never enabled.
349+
if profiles_sample_rate is None:
350+
return False
351+
352+
return random.random() < float(profiles_sample_rate)
334353

335354

336355
@contextmanager
337356
def start_profiling(transaction, hub=None):
338357
# type: (sentry_sdk.tracing.Transaction, Optional[sentry_sdk.Hub]) -> Generator[None, None, None]
339358

340359
# if profiling was not enabled, this should be a noop
341-
if _has_profiling_enabled():
360+
if _should_profile(hub):
342361
with Profile(transaction, hub=hub):
343362
yield
344363
else:

tests/integrations/wsgi/test_wsgi.py

Lines changed: 18 additions & 30 deletions

0 commit comments

Comments
 (0)