added api
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
import hashlib
|
||||
import json
|
||||
import time
|
||||
from typing import Any
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.config import get_settings
|
||||
from app.homelab.netdata import NetdataClient
|
||||
from app.homelab.state import get_state, set_state
|
||||
|
||||
ALERT_COOLDOWN_SEC = 1800
|
||||
|
||||
|
||||
def _alarm_key(alarm: dict[str, Any]) -> str:
|
||||
return f"{alarm.get('name')}:{alarm.get('status')}"
|
||||
|
||||
|
||||
def check_netdata_alerts(db: Session) -> list[str]:
|
||||
settings = get_settings()
|
||||
if not settings.netdata_alerts_enabled:
|
||||
return []
|
||||
|
||||
result = NetdataClient().fetch_alarms()
|
||||
if not result.get("ok"):
|
||||
return []
|
||||
|
||||
alarms = result.get("alarms") or []
|
||||
significant = [
|
||||
a for a in alarms
|
||||
if (a.get("status") or "").lower() in ("warning", "critical", "raised")
|
||||
]
|
||||
if not significant:
|
||||
return []
|
||||
|
||||
prev_raw = get_state(db, "netdata_alarm_hashes") or "{}"
|
||||
try:
|
||||
prev_map: dict[str, float] = json.loads(prev_raw)
|
||||
except json.JSONDecodeError:
|
||||
prev_map = {}
|
||||
|
||||
now = time.time()
|
||||
notices: list[str] = []
|
||||
new_map = dict(prev_map)
|
||||
|
||||
for alarm in significant:
|
||||
key = _alarm_key(alarm)
|
||||
digest = hashlib.sha256(json.dumps(alarm, sort_keys=True).encode()).hexdigest()[:16]
|
||||
state_key = f"netdata:{key}:{digest}"
|
||||
last_sent = prev_map.get(state_key, 0)
|
||||
if now - last_sent < ALERT_COOLDOWN_SEC:
|
||||
continue
|
||||
|
||||
host = alarm.get("host") or "server"
|
||||
value = alarm.get("value_string") or ""
|
||||
info = alarm.get("info") or alarm.get("name") or "алерт"
|
||||
status = alarm.get("status") or "alert"
|
||||
link = settings.netdata_public_url
|
||||
link_part = f" [Netdata]({link})" if link else ""
|
||||
notices.append(
|
||||
f"⚠️ **Netdata** · {host}: {info} — {status}"
|
||||
+ (f" ({value})" if value else "")
|
||||
+ link_part
|
||||
)
|
||||
new_map[state_key] = now
|
||||
|
||||
if notices:
|
||||
set_state(db, "netdata_alarm_hashes", json.dumps(new_map))
|
||||
|
||||
return notices
|
||||
Reference in New Issue
Block a user