Skip to content

feat(dynamic-sampling): Add per-org sample rates summary log - #120650

Merged
shellmayr merged 5 commits into
masterfrom
feat/ds-per-org-sample-rates-summary-log
Jul 27, 2026
Merged

feat(dynamic-sampling): Add per-org sample rates summary log#120650
shellmayr merged 5 commits into
masterfrom
feat/ds-per-org-sample-rates-summary-log

Conversation

@shellmayr

Copy link
Copy Markdown
Member
  • Add a single dynamic_sampling.per_org.sample_rates_summary log per org per cycle with the org, project, and transaction sample rates — EAP and generic metrics side by side.
  • Existing comparison logs unchanged.
  • Gated on dynamic-sampling.per_org.sample-rates-summary-log-rollout-rate, default off.

The per-org pipeline logs the EAP-vs-generic-metrics comparison as one line per
project and one line per transaction, so reconstructing what an org looked like in
a single cycle means joining many log entries.

Add a single summary log at the end of the per-org task carrying the org sample
rate plus, per project, the project sample rate and the transaction sample rates
(named and implicit) for both the EAP and the generic metrics pipeline. The
existing per-project and per-transaction comparison logs are unchanged.

Gate it on a new deterministic rollout-rate option keyed on organization id,
defaulting to off. The payload scales with projects x transactions, so the gate
also covers the extra Redis reads the log needs: with it off, the transaction
cache is read only for EAP-rebalanced projects and the project cache stays inside
the balancing branch, matching the previous read volume.

Pipeline the transaction cache reads into a single round trip, since serving the
log widens that fetch to every project in the org.

Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label Jul 27, 2026
shellmayr and others added 4 commits July 27, 2026 14:24
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
…ple-rates-summary-log

# Conflicts:
#	src/sentry/dynamic_sampling/per_org/gate.py
@shellmayr
shellmayr marked this pull request as ready for review July 27, 2026 12:38
@shellmayr
shellmayr requested review from a team as code owners July 27, 2026 12:38

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 95f2fe4. Configure here.

cached_project_sample_rates=cached_sample_rates,
rebalanced_transactions=rebalanced_transactions,
cached_transaction_sample_rates=cached_transaction_sample_rates,
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary log skipped on early returns

Medium Severity

log_sample_rates_summary only runs after transaction balancing finishes, so orgs that exit at ALL_PROJECTS_AT_FULL_SAMPLE_RATE or NO_TRANSACTION_VOLUMES never emit the per-cycle summary. Project cache is already fetched when log_summary is on for those paths, but the log is never written, so rolled-out orgs under quota or without transaction volume are missing from the comparison.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 95f2fe4. Configure here.

Comment on lines +207 to +215
def get_cached_organization_sample_rate(org_id: int) -> float | None:
"""
The organization sample rate the legacy (generic metrics) pipeline would serve: the
cached sliding-window rate, or the target sample rate option for custom sampling orgs.
Returns None on a cache miss instead of falling back to the blended rate, so the
comparison logging can distinguish "no cached value" from "cached value equals blended".
"""
sample_rate, _ = get_org_sample_rate(org_id=org_id, default_sample_rate=None)
return sample_rate

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The function get_cached_organization_sample_rate incorrectly returns 1.0 instead of None on a cache miss for organizations with custom dynamic sampling but no explicit rate set.
Severity: LOW

Suggested Fix

Modify the get_org_sample_rate function. When it is called with default_sample_rate=None and an organization has dynamic-sampling-custom enabled without a specific sentry:target_sample_rate, it should return None instead of falling back to TARGET_SAMPLE_RATE_DEFAULT. This will align the function's behavior with the documented contract of its caller, get_cached_organization_sample_rate.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: src/sentry/dynamic_sampling/per_org/calculations.py#L207-L215

Potential issue: The function `get_cached_organization_sample_rate` is documented to
return `None` on a cache miss to distinguish it from a cached value. However, for
organizations with the `dynamic-sampling-custom` feature enabled but no specific
`sentry:target_sample_rate` option set, it incorrectly returns a default value of `1.0`.
This is caused by an underlying helper, `get_org_sample_rate`, which falls back to
`TARGET_SAMPLE_RATE_DEFAULT` instead of propagating `None`. As a result, logging that
relies on this function will be misleading, making it impossible to differentiate
between a genuine cached value of `1.0` and a cache miss.

Did we get this right? 👍 / 👎 to inform future reviews.

@shellmayr
shellmayr merged commit 8667551 into master Jul 27, 2026
86 checks passed
@shellmayr
shellmayr deleted the feat/ds-per-org-sample-rates-summary-log branch July 27, 2026 14:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants