Skip to content

Commit ddb21fa

Browse files
authored
chore(dynamic-sampling): add more detailed logs to sample rate calculations (#97563)
1 parent 7cfd09e commit ddb21fa

File tree

2 files changed

+82
-6
lines changed

2 files changed

+82
-6
lines changed

src/sentry/dynamic_sampling/tasks/boost_low_volume_projects.py

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -250,13 +250,19 @@ def boost_low_volume_projects_of_org(
250250
Task to adjust the sample rates of the projects of a single organization specified by an
251251
organization ID. Transaction counts and rates have to be provided.
252252
"""
253-
logger.info(
254-
"boost_low_volume_projects_of_org",
255-
extra={"traceparent": sentry_sdk.get_traceparent(), "baggage": sentry_sdk.get_baggage()},
256-
)
253+
257254
rebalanced_projects = calculate_sample_rates_of_projects(
258255
org_id, projects_with_tx_count_and_rates
259256
)
257+
258+
logger.info(
259+
"boost_low_volume_projects_of_org",
260+
extra={
261+
"traceparent": sentry_sdk.get_traceparent(),
262+
"baggage": sentry_sdk.get_baggage(),
263+
"org_id": org_id,
264+
},
265+
)
260266
if rebalanced_projects is not None:
261267
store_rebalanced_projects(org_id, rebalanced_projects)
262268

@@ -435,10 +441,27 @@ def calculate_sample_rates_of_projects(
435441

436442
# If we have the sliding window org sample rate, we use that or fall back to the blended sample rate in case of
437443
# issues.
444+
445+
default_sample_rate = quotas.backend.get_blended_sample_rate(organization_id=org_id)
446+
should_log_project_config = features.has("organizations:log-project-config", organization)
447+
438448
sample_rate, success = get_org_sample_rate(
439449
org_id=org_id,
440-
default_sample_rate=quotas.backend.get_blended_sample_rate(organization_id=org_id),
450+
default_sample_rate=default_sample_rate,
441451
)
452+
453+
if should_log_project_config:
454+
logger.info(
455+
"log-project-config: calculate_sample_rates_of_projects for org %s",
456+
org_id,
457+
extra={
458+
"org": org_id,
459+
"target_sample_rate": sample_rate,
460+
"success": success,
461+
"default_sample_rate": default_sample_rate,
462+
},
463+
)
464+
442465
if success:
443466
sample_function(
444467
function=log_sample_rate_source,
@@ -470,6 +493,14 @@ def calculate_sample_rates_of_projects(
470493
projects_with_counts = {
471494
project_id: count_per_root for project_id, count_per_root, _, _ in projects_with_tx_count
472495
}
496+
497+
if should_log_project_config:
498+
logger.info(
499+
"log-project-config: calculate_sample_rates_of_projects for org %s",
500+
org_id,
501+
extra={"projects_with_counts": projects_with_counts, "sample_rate": sample_rate},
502+
)
503+
473504
# The rebalancing will not work (or would make sense) when we have only projects with zero-counts.
474505
if not any(projects_with_counts.values()):
475506
return None
@@ -502,6 +533,26 @@ def calculate_sample_rates_of_projects(
502533
rebalanced_projects: list[RebalancedItem] | None = guarded_run(
503534
model, ProjectsRebalancingInput(classes=projects, sample_rate=sample_rate)
504535
)
536+
if should_log_project_config:
537+
logger.info(
538+
"log-project-config: rebalanced_projects for org %s",
539+
org_id,
540+
extra={
541+
"rebalanced_projects": (
542+
[
543+
{
544+
"id": project.id,
545+
"count": project.count,
546+
"new_sample_rate": project.new_sample_rate,
547+
}
548+
for project in rebalanced_projects
549+
]
550+
if rebalanced_projects
551+
else None
552+
),
553+
"sample_rate": sample_rate,
554+
},
555+
)
505556

506557
return rebalanced_projects
507558

src/sentry/dynamic_sampling/tasks/helpers/sample_rate.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88

99
__all__ = ["get_org_sample_rate"]
1010

11+
import logging
12+
13+
logger = logging.getLogger("sentry.dynamic_sampling")
14+
1115

1216
def get_org_sample_rate(
1317
org_id: int, default_sample_rate: float | None
@@ -28,14 +32,35 @@ def get_org_sample_rate(
2832
has_dynamic_sampling_custom = features.has("organizations:dynamic-sampling-custom", org)
2933
if has_dynamic_sampling_custom:
3034
sample_rate = org.get_option("sentry:target_sample_rate") if org else None
35+
if features.has("organizations:log-project-config", org):
36+
logger.info(
37+
"log-project-config: org.get_option: %s",
38+
sample_rate,
39+
extra={
40+
"org": org.id if org else None,
41+
"target_sample_rate": sample_rate,
42+
"default_sample_rate": default_sample_rate,
43+
},
44+
)
3145
if sample_rate is not None:
3246
return float(sample_rate), True
3347
if default_sample_rate is not None:
3448
return default_sample_rate, False
3549
return TARGET_SAMPLE_RATE_DEFAULT, False
3650

3751
# fallback to sliding window calculation
38-
return _get_sliding_window_org_sample_rate(org_id, default_sample_rate)
52+
sample_rate, is_custom = _get_sliding_window_org_sample_rate(org_id, default_sample_rate)
53+
if features.has("organizations:log-project-config", org):
54+
logger.info(
55+
"log-project-config: _get_sliding_window_org_sample_rate for org %s",
56+
org_id,
57+
extra={
58+
"sample_rate": sample_rate,
59+
"is_custom": is_custom,
60+
"default_sample_rate": default_sample_rate,
61+
},
62+
)
63+
return sample_rate, is_custom
3964

4065

4166
def _get_sliding_window_org_sample_rate(

0 commit comments

Comments
 (0)