This repository has been archived by the owner on Aug 4, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use Airflow variable to omit DAGs from any Slack notification (#644)
* Add DAG to check for DAGs that need alerts reenabled * Add tests * Add test that send_alert skips * Update message format to prevent links unfurling * Rename files and small refactor to make it easier to add silenced notifications as well as alerts * Update send_message to conditionally omit dags from slack notifications * Update reporting to pass dag_id to send_message * Update tests * Add notifications configuration check to DAG * Make dag_id required argument to ensure all Slack messages are skipped * Make single variable for silencing notifs of all types, allow different issues * Update record reporting * Only allow one predicate per github issue * Add types for clarity * Update check_silenced_dags DAG * Change order of functions * Correct default for slack_message_override * Consolidate DAG to one file, update docstring, fix send_alert * Quote predicate in slack message * Update dag docs * Fix typo Co-authored-by: Zack Krida <[email protected]> * Update DAG docs with fixed typo Co-authored-by: Zack Krida <[email protected]>
- Loading branch information
Showing
13 changed files
with
411 additions
and
264 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
118 changes: 118 additions & 0 deletions
118
openverse_catalog/dags/maintenance/check_silenced_dags.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
""" | ||
Checks for DAGs that have silenced Slack alerts which may need to be turned back | ||
on. | ||
When a DAG has known failures, it can be ommitted from Slack error reporting by adding | ||
an entry to the `silenced_slack_notifications` Airflow variable. This is a dictionary | ||
where thekey is the `dag_id` of the affected DAG, and the value is a list of | ||
SilencedSlackNotifications (which map silenced notifications to GitHub URLs) for that | ||
DAG. | ||
The `check_silenced_dags` DAG iterates over the entries in the | ||
`silenced_slack_notifications` configuration and verifies that the associated GitHub | ||
issues are still open. If an issue has been closed, it is assumed that the DAG should | ||
have Slack reporting reenabled, and an alert is sent to prompt manual update of the | ||
configuration. This prevents developers from forgetting to reenable Slack reporting | ||
after the issue has been resolved. | ||
The DAG runs weekly. | ||
""" | ||
|
||
import logging | ||
from datetime import datetime, timedelta | ||
from typing import Tuple | ||
|
||
from airflow.exceptions import AirflowException, AirflowSkipException | ||
from airflow.models import DAG, Variable | ||
from airflow.operators.python import PythonOperator | ||
from common.constants import DAG_DEFAULT_ARGS | ||
from common.github import GitHubAPI | ||
from common.slack import SilencedSlackNotification, send_alert | ||
|
||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
DAG_ID = "check_silenced_dags" | ||
MAX_ACTIVE = 1 | ||
GITHUB_PAT = Variable.get("GITHUB_API_KEY", default_var="not_set") | ||
|
||
|
||
def get_issue_info(issue_url: str) -> Tuple[str, str, str]: | ||
""" | ||
Parses out the owner, repo, and issue_number from a GitHub issue url. | ||
""" | ||
url_split = issue_url.split("/") | ||
if len(url_split) < 4: | ||
raise AirflowException(f"Issue url {issue_url} could not be parsed.") | ||
return url_split[-4], url_split[-3], url_split[-1] | ||
|
||
|
||
def get_dags_with_closed_issues( | ||
github_pat: str, silenced_dags: dict[str, list[SilencedSlackNotification]] | ||
): | ||
gh = GitHubAPI(github_pat) | ||
|
||
dags_to_reenable = [] | ||
for dag_id, silenced_notifications in silenced_dags.items(): | ||
for notification in silenced_notifications: | ||
issue_url = notification["issue"] | ||
owner, repo, issue_number = get_issue_info(issue_url) | ||
github_issue = gh.get_issue(repo, issue_number, owner) | ||
|
||
if github_issue.get("state") == "closed": | ||
# If the associated issue has been closed, this DAG can have | ||
# alerting reenabled for this predicate. | ||
dags_to_reenable.append((dag_id, issue_url, notification["predicate"])) | ||
return dags_to_reenable | ||
|
||
|
||
def check_configuration(github_pat: str): | ||
silenced_dags = Variable.get( | ||
"silenced_slack_notifications", default_var={}, deserialize_json=True | ||
) | ||
dags_to_reenable = get_dags_with_closed_issues(github_pat, silenced_dags) | ||
|
||
if not dags_to_reenable: | ||
raise AirflowSkipException( | ||
"All DAGs configured to silence messages have work still in progress." | ||
" No configuration updates needed." | ||
) | ||
|
||
message = ( | ||
"The following DAGs have Slack messages silenced, but the associated issue is" | ||
" closed. Please remove them from the silenced_slack_notifications Airflow" | ||
" variable or assign a new issue." | ||
) | ||
for (dag, issue, predicate) in dags_to_reenable: | ||
message += f"\n - <{issue}|{dag}: '{predicate}'>" | ||
send_alert( | ||
message, dag_id=DAG_ID, username="Silenced DAG Check", unfurl_links=False | ||
) | ||
return message | ||
|
||
|
||
dag = DAG( | ||
dag_id=DAG_ID, | ||
default_args={ | ||
**DAG_DEFAULT_ARGS, | ||
"retry_delay": timedelta(minutes=1), | ||
}, | ||
start_date=datetime(2022, 7, 29), | ||
schedule_interval="@weekly", | ||
max_active_tasks=MAX_ACTIVE, | ||
max_active_runs=MAX_ACTIVE, | ||
catchup=False, | ||
# Use the docstring at the top of the file as md docs in the UI | ||
doc_md=__doc__, | ||
tags=["maintenance"], | ||
) | ||
|
||
with dag: | ||
PythonOperator( | ||
task_id="check_silenced_dags_configuration", | ||
python_callable=check_configuration, | ||
op_kwargs={ | ||
"github_pat": GITHUB_PAT, | ||
}, | ||
) |
57 changes: 0 additions & 57 deletions
57
openverse_catalog/dags/maintenance/check_silenced_dags/check_silenced_dags.py
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.