Skip to content
Closed
Show file tree
Hide file tree
Changes from 8 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
2 changes: 0 additions & 2 deletions src/sentry/features/temporary.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,8 +384,6 @@ def register_temporary_features(manager: FeatureManager) -> None:
# Enable high date range options on new explore page
manager.add("organizations:visibility-explore-range-high", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)

# Use batched Snuba queries for weekly report key errors instead of per-project queries
manager.add("organizations:weekly-report-batched-key-errors", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=False)
# Show combined resolved "past issues" section instead of separate key errors / performance issues
manager.add("organizations:weekly-report-past-issues", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=False)
# Allow users to exclude specific projects from their weekly email reports
Expand Down
4 changes: 1 addition & 3 deletions src/sentry/snuba/referrer.py
Original file line number Diff line number Diff line change
Expand Up @@ -787,9 +787,7 @@ class Referrer(StrEnum):
REPLAYS_SCRIPTS_DELETE_REPLAYS = "replays.scripts.delete_replays"
FEEDBACKS_LABEL_QUERY = "feedbacks.label_query"
EU_DATA_EXPORT = "sentry.internal.eu-compliance-data-export"
REPORTS_KEY_ERRORS = "reports.key_errors"
REPORTS_KEY_ERRORS_BATCHED = "reports.key_errors.batched"
REPORTS_KEY_PERFORMANCE_ISSUES = "reports.key_performance_issues"
REPORTS_TOP_ISSUES = "reports.top_issues"
REPORTS_PAST_RESOLVED_ISSUES = "reports.past_resolved_issues"
REPORTS_OUTCOME_SERIES = "reports.outcome_series"
REPORTS_OUTCOMES = "reports.outcomes"
Expand Down
66 changes: 20 additions & 46 deletions src/sentry/tasks/summaries/organization_report_context_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@
fetch_key_error_groups,
fetch_key_performance_issue_groups,
fetch_past_resolved_issue_links,
org_key_errors,
org_top_issues,
organization_project_issue_summaries,
project_event_counts_for_organization,
project_key_errors,
project_key_performance_issues,
project_past_resolved_issues,
)
from sentry.tasks.summaries.weekly_report_cache import read_project_metrics
Expand Down Expand Up @@ -178,59 +176,35 @@
)

@metrics.wraps("weekly_report.create_context.project_key_errors")
def _append_project_key_errors(self, ctx: OrganizationReportContext) -> None:
def _append_project_key_issues(self, ctx: OrganizationReportContext) -> None:
with start_span(op="weekly_reports.project_passes", name="weekly_reports.project_passes"):
organization = ctx.organization
use_batched = features.has(
"organizations:weekly-report-batched-key-errors", organization
)

projects = [
p for p in organization.project_set.all() if p.id in ctx.projects_context_map
]

if use_batched:
try:
eligible_project_ids = [p.id for p in projects if p.first_event]
key_errors_by_project = org_key_errors(
ctx,
project_ids=eligible_project_ids,
referrer=Referrer.REPORTS_KEY_ERRORS_BATCHED.value,
)
for project_id, key_errors in key_errors_by_project.items():
project_ctx = ctx.projects_context_map[project_id]
assert isinstance(project_ctx, ProjectContext), (
f"Expected a ProjectContext, received {type(project_ctx)}"
)
project_ctx.key_errors_by_id = [
(e["events.group_id"], e["count()"]) for e in key_errors
]
except Exception:
sentry_sdk.capture_exception()
use_batched = False
eligible_projects = [p for p in projects if p.first_event]
if not eligible_projects:
return

try:
error_issues_by_project, perf_issues_by_project = org_top_issues(
ctx,
eligible_projects,
referrer=Referrer.REPORTS_TOP_ISSUES.value,
)
except Exception:

Check warning on line 195 in src/sentry/tasks/summaries/organization_report_context_factory.py

View check run for this annotation

@sentry/warden / warden: sentry-backend-bugs

Performance issues dropped for transaction-only projects (first_event gate)

In `_append_project_key_issues`, `eligible_projects = [p for p in projects if p.first_event]` filters out projects that have never received an error event, and `org_top_issues` (which queries BOTH error and performance issues) is only run for those eligible projects. A project that only receives transactions has `first_event=None` (transactions set `flags.has_transactions`/`first_transaction_received`, not `first_event`), so its performance issues are never populated into `key_performance_issues` and never appear in the weekly report. The prior data layer ran the performance-issue query for every project without a first_event gate, so this is a silent data-completeness regression for transaction-only projects. Fix by including transaction-having projects in eligibility (matching the codebase idiom `p.first_event or p.flags.has_transactions`).
Comment thread
sentry-warden[bot] marked this conversation as resolved.
sentry_sdk.capture_exception()
return
Comment thread
cursor[bot] marked this conversation as resolved.

for project in projects:
project_ctx = ctx.projects_context_map[project.id]
assert isinstance(project_ctx, ProjectContext), (
f"Expected a ProjectContext, received {type(project_ctx)}"
)

if not use_batched:
per_project_key_errors = project_key_errors(
ctx, project, referrer=Referrer.REPORTS_KEY_ERRORS.value
)
if per_project_key_errors:
project_ctx.key_errors_by_id = [
(e["events.group_id"], e["count()"]) for e in per_project_key_errors
]

key_performance_issues = project_key_performance_issues(
ctx, project, referrer=Referrer.REPORTS_KEY_PERFORMANCE_ISSUES.value
)
if key_performance_issues:
ctx.projects_context_map[
project.id
].key_performance_issues = key_performance_issues
if project.id in error_issues_by_project:
project_ctx.key_errors_by_id = error_issues_by_project[project.id]
if project.id in perf_issues_by_project:
project_ctx.key_performance_issues = perf_issues_by_project[project.id]

@metrics.wraps("weekly_report.create_context.hydrate_key_error_groups")
def _hydrate_key_error_groups(self, ctx: OrganizationReportContext) -> None:
Expand Down Expand Up @@ -282,7 +256,7 @@

# Enhanced privacy flag hides issue titles, transaction names, and source details
if not self.organization.flags.enhanced_privacy:
self._append_project_key_errors(ctx)
self._append_project_key_issues(ctx)
self._hydrate_key_error_groups(ctx)
self._hydrate_key_performance_issue_groups(ctx)
if features.has("organizations:weekly-report-past-issues", self.organization):
Expand Down
Loading
Loading