Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(seer grouping): Add platform to ingest metrics #82442

Open
wants to merge 2 commits into
base: kmclb-remove-too-many-frames-exception-code
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
24 changes: 13 additions & 11 deletions src/sentry/grouping/ingest/seer.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,33 +73,35 @@ def _event_content_is_seer_eligible(event: Event) -> bool:
"""
Determine if an event's contents makes it fit for using with Seer's similar issues model.
"""
platform = event.platform

if not event_content_has_stacktrace(event):
metrics.incr(
"grouping.similarity.event_content_seer_eligible",
sample_rate=options.get("seer.similarity.metrics_sample_rate"),
tags={"eligible": False, "blocker": "no-stacktrace"},
tags={"platform": platform, "eligible": False, "blocker": "no-stacktrace"},
)
return False

if event.platform in SEER_INELIGIBLE_EVENT_PLATFORMS:
metrics.incr(
"grouping.similarity.event_content_seer_eligible",
sample_rate=options.get("seer.similarity.metrics_sample_rate"),
tags={"eligible": False, "blocker": "unsupported-platform"},
tags={"platform": platform, "eligible": False, "blocker": "unsupported-platform"},
)
return False

metrics.incr(
"grouping.similarity.event_content_seer_eligible",
sample_rate=options.get("seer.similarity.metrics_sample_rate"),
tags={"eligible": True, "blocker": "none"},
tags={"platform": platform, "eligible": True, "blocker": "none"},
)
return True


def _has_too_many_contributing_frames(event: Event, variants: dict[str, BaseVariant]) -> bool:
if has_too_many_contributing_frames(event, variants, ReferrerOptions.INGEST):
record_did_call_seer_metric(call_made=False, blocker="excess-frames")
record_did_call_seer_metric(event, call_made=False, blocker="excess-frames")
return True

return False
Expand Down Expand Up @@ -135,14 +137,14 @@ def _has_customized_fingerprint(event: Event, variants: dict[str, BaseVariant])

# Hybrid fingerprinting ({{ default }} + some other value(s))
else:
record_did_call_seer_metric(call_made=False, blocker="hybrid-fingerprint")
record_did_call_seer_metric(event, call_made=False, blocker="hybrid-fingerprint")
return True

# Fully customized fingerprint (from either us or the user)
fingerprint_variant = variants.get("custom_fingerprint") or variants.get("built_in_fingerprint")

if fingerprint_variant:
record_did_call_seer_metric(call_made=False, blocker=fingerprint_variant.type)
record_did_call_seer_metric(event, call_made=False, blocker=fingerprint_variant.type)
return True

return False
Expand All @@ -164,7 +166,7 @@ def _ratelimiting_enabled(event: Event, project: Project) -> bool:
if ratelimiter.backend.is_limited("seer:similarity:global-limit", **global_ratelimit):
logger_extra["limit_per_sec"] = global_limit_per_sec
logger.warning("should_call_seer_for_grouping.global_ratelimit_hit", extra=logger_extra)
record_did_call_seer_metric(call_made=False, blocker="global-rate-limit")
record_did_call_seer_metric(event, call_made=False, blocker="global-rate-limit")

return True

Expand All @@ -173,7 +175,7 @@ def _ratelimiting_enabled(event: Event, project: Project) -> bool:
):
logger_extra["limit_per_sec"] = project_limit_per_sec
logger.warning("should_call_seer_for_grouping.project_ratelimit_hit", extra=logger_extra)
record_did_call_seer_metric(call_made=False, blocker="project-rate-limit")
record_did_call_seer_metric(event, call_made=False, blocker="project-rate-limit")

return True

Expand All @@ -194,7 +196,7 @@ def _circuit_breaker_broken(event: Event, project: Project) -> bool:
**breaker_config,
},
)
record_did_call_seer_metric(call_made=False, blocker="circuit-breaker")
record_did_call_seer_metric(event, call_made=False, blocker="circuit-breaker")

return circuit_broken

Expand All @@ -203,7 +205,7 @@ def _has_empty_stacktrace_string(event: Event, variants: dict[str, BaseVariant])
stacktrace_string = get_stacktrace_string(get_grouping_info_from_variants(variants))
if not stacktrace_string:
if stacktrace_string == "":
record_did_call_seer_metric(call_made=False, blocker="empty-stacktrace-string")
record_did_call_seer_metric(event, call_made=False, blocker="empty-stacktrace-string")
return True
# Store the stacktrace string in the event so we only calculate it once. We need to pop it
# later so it isn't stored in the database.
Expand Down Expand Up @@ -292,7 +294,7 @@ def maybe_check_seer_for_matching_grouphash(
seer_matched_grouphash = None

if should_call_seer_for_grouping(event, variants):
record_did_call_seer_metric(call_made=True, blocker="none")
record_did_call_seer_metric(event, call_made=True, blocker="none")

try:
# If no matching group is found in Seer, we'll still get back result
Expand Down
19 changes: 10 additions & 9 deletions src/sentry/seer/similarity/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,11 +275,11 @@ def event_content_has_stacktrace(event: GroupEvent | Event) -> bool:
return exception_stacktrace or threads_stacktrace or only_stacktrace


def record_did_call_seer_metric(*, call_made: bool, blocker: str) -> None:
def record_did_call_seer_metric(event: Event, *, call_made: bool, blocker: str) -> None:
metrics.incr(
"grouping.similarity.did_call_seer",
sample_rate=options.get("seer.similarity.metrics_sample_rate"),
tags={"call_made": call_made, "blocker": blocker},
tags={"call_made": call_made, "blocker": blocker, "platform": event.platform},
)


Expand Down Expand Up @@ -344,7 +344,7 @@ def has_too_many_contributing_frames(
def killswitch_enabled(
project_id: int | None,
referrer: ReferrerOptions,
event: GroupEvent | Event | None = None,
event: Event | None = None,
) -> bool:
"""
Check both the global and similarity-specific Seer killswitches.
Expand All @@ -358,8 +358,9 @@ def killswitch_enabled(
f"{logger_prefix}.seer_global_killswitch_enabled", # noqa
extra=logger_extra,
)
if is_ingest:
record_did_call_seer_metric(call_made=False, blocker="global-killswitch")
# When it's ingest, `event` will always be defined - the second check is purely for mypy
if is_ingest and event:
record_did_call_seer_metric(event, call_made=False, blocker="global-killswitch")

return True

Expand All @@ -368,8 +369,8 @@ def killswitch_enabled(
f"{logger_prefix}.seer_similarity_killswitch_enabled", # noqa
extra=logger_extra,
)
if is_ingest:
record_did_call_seer_metric(call_made=False, blocker="similarity-killswitch")
if is_ingest and event:
record_did_call_seer_metric(event, call_made=False, blocker="similarity-killswitch")

return True

Expand All @@ -380,8 +381,8 @@ def killswitch_enabled(
f"{logger_prefix}.seer_similarity_project_killswitch_enabled", # noqa
extra=logger_extra,
)
if is_ingest:
record_did_call_seer_metric(call_made=False, blocker="project-killswitch")
if is_ingest and event:
record_did_call_seer_metric(event, call_made=False, blocker="project-killswitch")

return True

Expand Down
6 changes: 4 additions & 2 deletions tests/sentry/grouping/ingest/test_seer.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ def test_obeys_empty_stacktrace_string_check(self, mock_record_did_call_seer: Mo

assert should_call_seer_for_grouping(new_event, new_event.get_grouping_variants()) is False
mock_record_did_call_seer.assert_any_call(
call_made=False, blocker="empty-stacktrace-string"
new_event, call_made=False, blocker="empty-stacktrace-string"
)

@patch("sentry.grouping.ingest.seer.get_similarity_data_from_seer", return_value=[])
Expand Down Expand Up @@ -466,7 +466,9 @@ def test_too_many_frames_maybe_check_seer_for_matching_group_hash(
"outcome": "block",
},
)
mock_record_did_call_seer.assert_any_call(call_made=False, blocker="excess-frames")
mock_record_did_call_seer.assert_any_call(
new_event, call_made=False, blocker="excess-frames"
)

mock_get_similar_issues.assert_not_called()

Expand Down
Loading