Fix: Hausmeister-Check Deduplizierung — gleiche Alerts nicht mehr alle 5 Min wiederholen
This commit is contained in:
parent
4c0f466811
commit
c11f417ef8
1 changed files with 73 additions and 2 deletions
|
|
@ -2,11 +2,24 @@
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
import json
|
||||||
|
import hashlib
|
||||||
import requests
|
import requests
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
sys.path.insert(0, os.path.dirname(__file__))
|
sys.path.insert(0, os.path.dirname(__file__))
|
||||||
from core import config, loki_client, proxmox_client, mail_client
|
from core import config, loki_client, proxmox_client, mail_client
|
||||||
|
|
||||||
|
ALERT_STATE_FILE = os.path.join(os.path.dirname(__file__), ".alert_state.json")
|
||||||
|
ALERT_COOLDOWN_MINUTES = {
|
||||||
|
"mail": 120,
|
||||||
|
"container": 30,
|
||||||
|
"ram": 30,
|
||||||
|
"panic": 60,
|
||||||
|
"silence": 60,
|
||||||
|
"default": 60,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def _get_tokens(cfg):
|
def _get_tokens(cfg):
|
||||||
tokens = {}
|
tokens = {}
|
||||||
|
|
@ -126,6 +139,63 @@ def format_report() -> str:
|
||||||
return "\n".join(lines)
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
|
||||||
|
def _load_alert_state() -> dict:
|
||||||
|
try:
|
||||||
|
with open(ALERT_STATE_FILE, "r") as f:
|
||||||
|
return json.load(f)
|
||||||
|
except (FileNotFoundError, json.JSONDecodeError):
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
def _save_alert_state(state: dict):
|
||||||
|
try:
|
||||||
|
with open(ALERT_STATE_FILE, "w") as f:
|
||||||
|
json.dump(state, f)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def _alert_key(alert_text: str) -> str:
|
||||||
|
return hashlib.md5(alert_text.encode()).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def _alert_category(alert_text: str) -> str:
|
||||||
|
if "📧" in alert_text or "Mail" in alert_text:
|
||||||
|
return "mail"
|
||||||
|
if "CT " in alert_text and "ist " in alert_text:
|
||||||
|
return "container"
|
||||||
|
if "RAM " in alert_text:
|
||||||
|
return "ram"
|
||||||
|
if "panic" in alert_text.lower() or "fatal" in alert_text.lower():
|
||||||
|
return "panic"
|
||||||
|
if "Keine Logs" in alert_text:
|
||||||
|
return "silence"
|
||||||
|
return "default"
|
||||||
|
|
||||||
|
|
||||||
|
def _filter_new_alerts(alerts: list[str]) -> list[str]:
|
||||||
|
"""Filtert bereits gemeldete Alerts. Gibt nur neue/fällige zurück."""
|
||||||
|
state = _load_alert_state()
|
||||||
|
now = datetime.now(timezone.utc).timestamp()
|
||||||
|
new_alerts = []
|
||||||
|
|
||||||
|
for alert in alerts:
|
||||||
|
key = _alert_key(alert)
|
||||||
|
cat = _alert_category(alert)
|
||||||
|
cooldown = ALERT_COOLDOWN_MINUTES.get(cat, 60) * 60
|
||||||
|
|
||||||
|
last_sent = state.get(key, {}).get("ts", 0)
|
||||||
|
if now - last_sent > cooldown:
|
||||||
|
new_alerts.append(alert)
|
||||||
|
state[key] = {"ts": now, "text": alert[:80], "cat": cat}
|
||||||
|
|
||||||
|
cutoff = now - 86400
|
||||||
|
state = {k: v for k, v in state.items() if v.get("ts", 0) > cutoff}
|
||||||
|
|
||||||
|
_save_alert_state(state)
|
||||||
|
return new_alerts
|
||||||
|
|
||||||
|
|
||||||
def send_alert(token: str, chat_id: str, message: str):
|
def send_alert(token: str, chat_id: str, message: str):
|
||||||
"""Sendet eine Nachricht via Telegram."""
|
"""Sendet eine Nachricht via Telegram."""
|
||||||
requests.post(
|
requests.post(
|
||||||
|
|
@ -144,8 +214,9 @@ def run_check_and_alert():
|
||||||
return
|
return
|
||||||
|
|
||||||
alerts = check_all()
|
alerts = check_all()
|
||||||
if alerts:
|
new_alerts = _filter_new_alerts(alerts)
|
||||||
msg = "🔧 Hausmeister-Check\n\n" + "\n".join(alerts)
|
if new_alerts:
|
||||||
|
msg = "🔧 Hausmeister-Check\n\n" + "\n".join(new_alerts)
|
||||||
send_alert(token, chat_id, msg)
|
send_alert(token, chat_id, msg)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue