2024-07-18 15:40:05 +02:00
|
|
|
import logging
|
2023-11-07 15:14:56 +01:00
|
|
|
from typing import Any, Dict, List, Tuple
|
|
|
|
|
|
|
|
|
|
from fastapi import Request
|
|
|
|
|
|
2023-11-24 10:23:00 +01:00
|
|
|
from ops_bot.common import (
|
|
|
|
|
COLOR_ALARM,
|
|
|
|
|
COLOR_INFO,
|
|
|
|
|
COLOR_OK,
|
|
|
|
|
COLOR_UNKNOWN,
|
|
|
|
|
COLOR_WARNING,
|
|
|
|
|
)
|
2023-11-07 15:14:56 +01:00
|
|
|
from ops_bot.config import RoutingKey
|
|
|
|
|
|
2023-11-24 10:23:00 +01:00
|
|
|
severity_colors = {
|
|
|
|
|
"warning": COLOR_WARNING,
|
|
|
|
|
"info": COLOR_INFO,
|
|
|
|
|
"critical": COLOR_ALARM,
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-07 15:14:56 +01:00
|
|
|
|
|
|
|
|
def prometheus_alert_to_markdown(
|
|
|
|
|
alert_data: Dict, # type: ignore[type-arg]
|
|
|
|
|
) -> List[Tuple[str, str]]:
|
|
|
|
|
"""
|
|
|
|
|
Converts a prometheus alert json to markdown
|
|
|
|
|
"""
|
|
|
|
|
messages = []
|
2023-11-24 10:23:00 +01:00
|
|
|
ignore_labels = ["grafana_folder"]
|
2024-07-18 15:40:05 +02:00
|
|
|
|
|
|
|
|
logging.debug(f"alertmanager payload: {alert_data}")
|
2023-11-07 15:14:56 +01:00
|
|
|
for alert in alert_data["alerts"]:
|
2024-07-18 16:20:35 +02:00
|
|
|
title = alert["labels"]["alertname"]
|
|
|
|
|
summary = alert["annotations"].get("summary")
|
|
|
|
|
description = alert["annotations"].get("description")
|
2024-07-18 15:40:05 +02:00
|
|
|
logging.debug(f"processing alert: '{title}'")
|
2023-11-24 10:23:00 +01:00
|
|
|
labels = alert.get("labels", {})
|
|
|
|
|
severity = labels.get("severity", "unknown")
|
|
|
|
|
status = alert.get("status", "unknown-status")
|
|
|
|
|
if status == "resolved":
|
2023-11-07 15:14:56 +01:00
|
|
|
color = COLOR_OK
|
|
|
|
|
else:
|
2023-11-24 10:23:00 +01:00
|
|
|
color = severity_colors.get(severity, COLOR_UNKNOWN)
|
2023-11-07 15:14:56 +01:00
|
|
|
|
2023-11-24 10:23:00 +01:00
|
|
|
plain = f"{status.upper()}[{severity}]: {title}"
|
|
|
|
|
header_str = f"{status.upper()}[{severity}]"
|
2024-07-18 15:40:05 +02:00
|
|
|
formatted = (
|
2024-07-18 16:20:35 +02:00
|
|
|
f"<strong><font color={color}>{header_str}</font></strong>: {title}"
|
2024-07-18 15:40:05 +02:00
|
|
|
)
|
2024-07-18 16:20:35 +02:00
|
|
|
if summary:
|
|
|
|
|
formatted += f" - {summary}"
|
|
|
|
|
plain += f" - {summary}"
|
2023-11-24 10:23:00 +01:00
|
|
|
label_strings = []
|
|
|
|
|
for label_name, label_value in labels.items():
|
2024-07-18 15:49:39 +02:00
|
|
|
logging.debug(f"got label: {label_name} = {label_value}")
|
2023-11-08 14:00:05 +01:00
|
|
|
if label_name.startswith("__"):
|
|
|
|
|
continue
|
|
|
|
|
if label_name in ignore_labels:
|
|
|
|
|
continue
|
2023-11-24 10:23:00 +01:00
|
|
|
label_strings.append((f"**{label_name.capitalize()}**: {label_value}"))
|
|
|
|
|
labels_final = ", ".join(label_strings)
|
|
|
|
|
plain += f" \n{labels_final}"
|
2024-07-18 16:20:35 +02:00
|
|
|
if description:
|
|
|
|
|
formatted += f"<br/>Description: {description}"
|
|
|
|
|
plain += f" \n{description}"
|
|
|
|
|
|
2023-11-24 10:23:00 +01:00
|
|
|
formatted += f"<br/>{labels_final}"
|
2024-07-18 16:20:35 +02:00
|
|
|
generatorURL = alert.get("generatorURL")
|
|
|
|
|
runbookURL = alert["annotations"].get("runbook_url")
|
|
|
|
|
dashboardURL = alert.get("dashboardURL")
|
|
|
|
|
silenceURL = alert.get("silenceURL")
|
|
|
|
|
actions = []
|
|
|
|
|
if silenceURL:
|
|
|
|
|
actions.append(f"[🔕 Mute]({silenceURL})")
|
|
|
|
|
if runbookURL:
|
|
|
|
|
actions.append(f"[📗 Runbook]({runbookURL})")
|
|
|
|
|
if dashboardURL:
|
|
|
|
|
actions.append(f"[📈 Dashboard]({dashboardURL})")
|
|
|
|
|
if generatorURL:
|
|
|
|
|
actions.append(f"[🔍 Inspect]({generatorURL})")
|
|
|
|
|
formatted += "<br/>" + " | ".join(actions)
|
2023-11-07 15:14:56 +01:00
|
|
|
messages.append((plain, formatted))
|
|
|
|
|
return messages
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def parse_alertmanager_event(
|
|
|
|
|
route: RoutingKey,
|
|
|
|
|
payload: Any,
|
|
|
|
|
request: Request,
|
|
|
|
|
) -> List[Tuple[str, str]]:
|
|
|
|
|
return prometheus_alert_to_markdown(payload)
|