Skip to content

Commit 9ff8981

Browse files
authored
Add a new rule for monitoring inactive telemetry alerts (#2773)
1 parent 5885596 commit 9ff8981

File tree

5 files changed

+186
-0
lines changed

5 files changed

+186
-0
lines changed
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# This Source Code Form is subject to the terms of the Mozilla Public
2+
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
3+
# You can obtain one at http://mozilla.org/MPL/2.0/.
4+
5+
6+
from libmozdata.bugzilla import BugzillaUser
7+
8+
from bugbot.bzcleaner import BzCleaner
9+
from bugbot.user_activity import UserActivity, UserStatus
10+
11+
12+
class TelemetryAlertInactiveRegression(BzCleaner):
13+
def __init__(self, nweeks=1):
14+
super().__init__()
15+
self.nweeks = nweeks
16+
self.extra_ni = {"nweeks": self.nweeks}
17+
18+
def description(self):
19+
return f"Telemetry alerts with {self.nweeks} week(s) of inactivity"
20+
21+
def get_extra_for_needinfo_template(self):
22+
return self.extra_ni
23+
24+
def get_extra_for_template(self):
25+
return self.extra_ni
26+
27+
def get_bz_params(self, date):
28+
start_date, _ = self.get_dates(date)
29+
30+
fields = [
31+
"id",
32+
"history",
33+
]
34+
35+
# Find all bugs that have a telemetry-alert keyword, have not changed in the
36+
# last week, and do not have the backlog-deferred keyword set
37+
params = {
38+
"include_fields": fields,
39+
"f3": "keywords",
40+
"o3": "allwords",
41+
"v3": ["telemetry-alert"],
42+
"f4": "keywords",
43+
"o4": "nowords",
44+
"v4": "backlog-deferred",
45+
"f5": "days_elapsed",
46+
"o5": "greaterthan",
47+
"v5": self.nweeks * 7,
48+
"status": ["UNCONFIRMED", "NEW", "REOPENED"],
49+
"resolution": ["---"],
50+
}
51+
52+
return params
53+
54+
def get_probe_owner(self, bug_history):
55+
probe_owner = ""
56+
57+
for change in bug_history:
58+
# Skip history changes when they are not from the intermittent bug filer
59+
# since it's responsible for adding the first needinfo for the probe owner
60+
if change["who"] != "[email protected]":
61+
continue
62+
63+
# Use the CC field entry to find the email of the person that should
64+
# be needinfo'ed so we don't need to parse it from the needinfo change
65+
needinfo_found = False
66+
for specific_change in change["changes"]:
67+
if (
68+
specific_change["field_name"] == "flagtypes.name"
69+
and "needinfo" in specific_change["added"]
70+
):
71+
needinfo_found = True
72+
elif specific_change["field_name"] == "cc":
73+
probe_owner = specific_change["added"]
74+
75+
if needinfo_found:
76+
break
77+
78+
return probe_owner
79+
80+
def handle_bug(self, bug, data):
81+
probe_owner = self.get_probe_owner(bug["history"])
82+
if not probe_owner:
83+
# Could not find a probe owner for some reason
84+
return
85+
86+
data[str(bug["id"])] = {"probe_owner": probe_owner}
87+
88+
return bug
89+
90+
def get_needinfo_nicks(self, bugs):
91+
def _user_handler(user, data):
92+
data[user["name"]] = user["nick"]
93+
94+
authors_to_ni = set()
95+
for bug_info in bugs.values():
96+
authors_to_ni.add(bug_info["probe_owner"])
97+
98+
if not authors_to_ni:
99+
return
100+
101+
user_emails_to_names = {}
102+
BugzillaUser(
103+
user_names=list(authors_to_ni),
104+
include_fields=["nick", "name"],
105+
user_handler=_user_handler,
106+
user_data=user_emails_to_names,
107+
).wait()
108+
109+
for bug_info in bugs.values():
110+
bug_info["nickname"] = user_emails_to_names[bug_info["probe_owner"]]
111+
112+
def filter_bugs(self, bugs):
113+
# Exclude bugs where the regressor author is inactive or blocked needinfo.
114+
# TODO: We can drop this when https://github.com/mozilla/bugbot/issues/1465 is implemented.
115+
users_info = UserActivity(include_fields=["groups", "requests"]).check_users(
116+
set(bug["probe_owner"] for bug in bugs.values()),
117+
keep_active=True,
118+
fetch_employee_info=True,
119+
)
120+
121+
for bug_id, bug in list(bugs.items()):
122+
user_info = users_info[bug["probe_owner"]]
123+
if (
124+
user_info["status"] != UserStatus.ACTIVE
125+
or user_info["requests"]["needinfo"]["blocked"]
126+
):
127+
del bugs[bug_id]
128+
129+
return bugs
130+
131+
def set_autofix(self, bugs):
132+
for bugid, info in bugs.items():
133+
self.add_auto_ni(
134+
bugid,
135+
{
136+
"mail": info["probe_owner"],
137+
"nickname": info["nickname"],
138+
},
139+
)
140+
141+
def get_bugs(self, *args, **kwargs):
142+
bugs = super().get_bugs(*args, **kwargs)
143+
self.get_needinfo_nicks(bugs)
144+
self.filter_bugs(bugs)
145+
self.set_autofix(bugs)
146+
return bugs
147+
148+
149+
if __name__ == "__main__":
150+
TelemetryAlertInactiveRegression().run()

configs/rules.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,9 @@
478478
"perfalert_resolved_regression": {
479479
"additional_receivers": ["[email protected]", "[email protected]"]
480480
},
481+
"telemetryalert_inactive_regression": {
482+
"additional_receivers": ["[email protected]", "[email protected]"]
483+
},
481484
"topcrash_notify": {
482485
"additional_receivers": ["rm"]
483486
}

scripts/cron_run_daily.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ python -m bugbot.rules.perfalert_inactive_regression --production
2121
# Send an email about all performance alerts who were recently resolved
2222
python -m bugbot.rules.perfalert_resolved_regression --production
2323

24+
# Try to detect potential telemetry alerts that have been inactive for too long
25+
python -m bugbot.rules.telemetryalert_inactive_regression --production
26+
2427
# Update the webcompat score fields
2528
python -m bugbot.rules.webcompat_score --production
2629

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<p>
2+
The following {{ plural('bug is a telemetry alert which has had', data, pword='bugs are telemetry alerts which have had') }} no activity in the last {{ extra['nweeks'] * 7 }} days:
3+
</p>
4+
<table {{ table_attrs }}>
5+
<thead>
6+
<tr>
7+
<th>Bug</th>
8+
<th>Summary</th>
9+
</tr>
10+
</thead>
11+
<tbody>
12+
{% for i, (bugid, summary) in enumerate(data) -%}
13+
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"
14+
{% endif -%}
15+
>
16+
<td>
17+
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>
18+
</td>
19+
<td>{{ summary | e }}</td>
20+
</tr>
21+
{% endfor -%}
22+
</tbody>
23+
</table>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
It has been over {{ extra["nweeks"] * 7 }} days with no activity on this telemetry alert.
2+
3+
:{{ nickname }}, since you are the owner of the probe that alerted, could you please provide a progress update?
4+
5+
If there are any questions about how to proceed for finding a culprit please check comment #0 for information on how to find help.
6+
7+
{{ documentation }}

0 commit comments

Comments
 (0)