65 lines
2.7 KiB
Python
65 lines
2.7 KiB
Python
from ..chat import MessageRef
|
|
from ..db import Database
|
|
from ..models import AI_PENDING, AI_SKIPPED, STATE_OK, Event
|
|
|
|
RECENT_LIMIT = 200
|
|
DAY_SECONDS = 86400
|
|
|
|
INSERT_ALERT_SQL = (
|
|
"INSERT INTO alerts(ts, host, service, kind, state, output, suppressed, suppress_reason, "
|
|
"ai_status, message_group) VALUES (?,?,?,?,?,?,?,?,?,?)"
|
|
)
|
|
|
|
|
|
class AlertRepository:
|
|
def __init__(self, db: Database):
|
|
self._db = db
|
|
|
|
def insert_alerts(self, events: list[Event], message_group: str) -> list[int]:
|
|
return [
|
|
self._db.insert(INSERT_ALERT_SQL, (
|
|
e.ts, e.host, e.service, e.kind, e.state, e.output, int(e.suppressed),
|
|
e.suppress_reason, AI_PENDING if e.wants_ai else AI_SKIPPED, message_group,
|
|
))
|
|
for e in events
|
|
]
|
|
|
|
def add_delivery(self, alert_id: int, ref: MessageRef) -> None:
|
|
self._db.execute(
|
|
"INSERT INTO deliveries(alert_id, backend, target, message_id) VALUES (?,?,?,?)",
|
|
(alert_id, ref.backend, ref.target, ref.message_id),
|
|
)
|
|
|
|
def set_ai(self, alert_id: int, status: str, text: str | None) -> None:
|
|
self._db.execute("UPDATE alerts SET ai_status=?, ai_text=? WHERE id=?", (status, text, alert_id))
|
|
|
|
def services_for_message(self, backend: str, target: str, message_id: str) -> list[tuple[str, str]]:
|
|
rows = self._db.query(
|
|
"SELECT DISTINCT a.host, a.service FROM deliveries d JOIN alerts a ON a.id=d.alert_id "
|
|
"WHERE d.backend=? AND d.target=? AND d.message_id=? ORDER BY a.host, a.service",
|
|
(backend, target, message_id),
|
|
)
|
|
return [(r["host"], r["service"]) for r in rows]
|
|
|
|
def service_for_alert(self, alert_id: int) -> tuple[str, str] | None:
|
|
rows = self._db.query("SELECT host, service FROM alerts WHERE id=?", (alert_id,))
|
|
return (rows[0]["host"], rows[0]["service"]) if rows else None
|
|
|
|
def recent(self, limit: int = RECENT_LIMIT) -> list[dict]:
|
|
rows = self._db.query("SELECT * FROM alerts ORDER BY ts DESC, id DESC LIMIT ?", (limit,))
|
|
return [dict(row) for row in rows]
|
|
|
|
def get(self, alert_id: int) -> dict | None:
|
|
rows = self._db.query("SELECT * FROM alerts WHERE id=?", (alert_id,))
|
|
return dict(rows[0]) if rows else None
|
|
|
|
def count_since(self, since_ts: int) -> int:
|
|
return self._db.query("SELECT COUNT(*) AS n FROM alerts WHERE ts>=?", (since_ts,))[0]["n"]
|
|
|
|
def open_problems(self) -> list[dict]:
|
|
rows = self._db.query(
|
|
"SELECT host, service, state, output, last_state_change, in_downtime, flapping "
|
|
"FROM service_states WHERE state!=? ORDER BY state DESC, host, service", (STATE_OK,),
|
|
)
|
|
return [dict(row) for row in rows]
|