6
6
from django .utils .translation import gettext as _
7
7
8
8
from sentry import features
9
- from sentry .incidents .models .alert_rule import AlertRule , AlertRuleThresholdType
10
- from sentry .incidents .models .incident import Incident , IncidentStatus
9
+ from sentry .constants import CRASH_RATE_ALERT_AGGREGATE_ALIAS
10
+ from sentry .incidents .models .alert_rule import AlertRule , AlertRuleThresholdType , AlertRuleTrigger
11
+ from sentry .incidents .models .incident import INCIDENT_STATUS , Incident , IncidentStatus
11
12
from sentry .incidents .utils .format_duration import format_duration_idiomatic
12
13
from sentry .integrations .metric_alerts import TEXT_COMPARISON_DELTA
13
14
from sentry .issues .grouptype import MetricIssuePOC
@@ -43,16 +44,21 @@ def to_dict(self) -> dict[str, Any]:
43
44
"count_unique(tags[sentry:user])" : "Number of users affected" ,
44
45
"percentage(sessions_crashed, sessions)" : "Crash free session rate" ,
45
46
"percentage(users_crashed, users)" : "Crash free user rate" ,
47
+ "failure_rate()" : "Failure rate" ,
48
+ "apdex()" : "Apdex score" ,
46
49
}
47
50
48
51
49
- def construct_title (alert_rule : AlertRule ) -> str :
52
+ def construct_title (alert_rule : AlertRule , status : int ) -> str :
50
53
# Parse the aggregate key from the alert rule
51
54
agg_display_key = alert_rule .snuba_query .aggregate
52
55
if is_mri_field (agg_display_key ):
53
- agg_text = format_mri_field (agg_display_key )
56
+ aggregate = format_mri_field (agg_display_key )
57
+ elif CRASH_RATE_ALERT_AGGREGATE_ALIAS in agg_display_key :
58
+ agg_display_key = agg_display_key .split (f"AS { CRASH_RATE_ALERT_AGGREGATE_ALIAS } " )[0 ].strip ()
59
+ aggregate = QUERY_AGGREGATION_DISPLAY .get (agg_display_key , agg_display_key )
54
60
else :
55
- agg_text = QUERY_AGGREGATION_DISPLAY .get (agg_display_key , alert_rule .snuba_query .aggregate )
61
+ aggregate = QUERY_AGGREGATION_DISPLAY .get (agg_display_key , alert_rule .snuba_query .aggregate )
56
62
57
63
# Determine the higher or lower comparison
58
64
higher_or_lower = ""
@@ -61,19 +67,35 @@ def construct_title(alert_rule: AlertRule) -> str:
61
67
else :
62
68
higher_or_lower = "less than" if alert_rule .comparison_delta else "below"
63
69
70
+ label = INCIDENT_STATUS [IncidentStatus (status )]
71
+
64
72
# Format the time window for the threshold
65
- time_window = alert_rule .snuba_query .time_window // 60
66
- title = f"{ agg_text } in the last { format_duration_idiomatic (time_window )} { higher_or_lower } "
73
+ time_window = format_duration_idiomatic (alert_rule .snuba_query .time_window // 60 )
67
74
68
75
# If the alert rule has a comparison delta, format the comparison string
76
+ comparison : str | int | float = "threshold"
69
77
if alert_rule .comparison_delta :
70
78
comparison_delta_minutes = alert_rule .comparison_delta // 60
71
- comparison_string = TEXT_COMPARISON_DELTA .get (
72
- comparison_delta_minutes , f"same time { comparison_delta_minutes } minutes ago"
79
+ comparison = TEXT_COMPARISON_DELTA .get (
80
+ comparison_delta_minutes , f"same time { comparison_delta_minutes } minutes ago "
73
81
)
74
- return _ (f"{ title } { comparison_string } " )
75
-
76
- return _ (f"{ title } threshold" )
82
+ else :
83
+ # Otherwise, check if there is a trigger with a threshold
84
+ trigger = AlertRuleTrigger .objects .filter (id = alert_rule .id , label = label .lower ()).first ()
85
+ if trigger :
86
+ threshold = trigger .alert_threshold
87
+ comparison = int (threshold ) if threshold % 1 == 0 else threshold
88
+
89
+ template = "{label}: {metric} in the last {time_window} {higher_or_lower} {comparison}"
90
+ return _ (
91
+ template .format (
92
+ label = label .capitalize (),
93
+ metric = aggregate ,
94
+ higher_or_lower = higher_or_lower ,
95
+ comparison = comparison ,
96
+ time_window = time_window ,
97
+ )
98
+ )
77
99
78
100
79
101
def _build_occurrence_from_incident (
@@ -88,7 +110,7 @@ def _build_occurrence_from_incident(
88
110
else PriorityLevel .MEDIUM
89
111
)
90
112
fingerprint = [str (incident .alert_rule .id )]
91
- title = construct_title (incident .alert_rule )
113
+ title = construct_title (incident .alert_rule , incident . status )
92
114
return IssueOccurrence (
93
115
id = uuid4 ().hex ,
94
116
project_id = project .id ,
0 commit comments