Fix: Mail-Alerts per Fingerprint deduplizieren — jede Mail nur einmal melden, nie wiederholen
This commit is contained in:
parent
7454db1bc6
commit
f7417f6517
1 changed files with 33 additions and 16 deletions
|
|
@ -11,13 +11,12 @@ sys.path.insert(0, os.path.dirname(__file__))
|
|||
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,
|
||||
ALERT_COOLDOWN_SECONDS = {
|
||||
"container": 1800,
|
||||
"ram": 1800,
|
||||
"panic": 3600,
|
||||
"silence": 3600,
|
||||
"default": 3600,
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -94,8 +93,26 @@ def check_all() -> list[str]:
|
|||
mail_client.init(cfg)
|
||||
important = mail_client.get_important_mails(hours=1)
|
||||
if important and "error" not in important[0]:
|
||||
senders = [m["from"][:30] for m in important]
|
||||
alerts.append(f"📧 {len(important)} wichtige Mail(s) (letzte Stunde): {', '.join(senders)}")
|
||||
state = _load_alert_state()
|
||||
seen = state.get("seen_mails", {})
|
||||
now = datetime.now(timezone.utc).timestamp()
|
||||
|
||||
new_mails = []
|
||||
for m in important:
|
||||
fp = hashlib.md5(
|
||||
f"{m.get('date_str','')}|{m.get('from','')}|{m.get('subject','')}".encode()
|
||||
).hexdigest()
|
||||
if fp not in seen:
|
||||
new_mails.append(m)
|
||||
seen[fp] = now
|
||||
|
||||
seen = {k: v for k, v in seen.items() if now - v < 172800}
|
||||
state["seen_mails"] = seen
|
||||
_save_alert_state(state)
|
||||
|
||||
if new_mails:
|
||||
senders = [m["from"][:30] for m in new_mails]
|
||||
alerts.append(f"📧 {len(new_mails)} neue wichtige Mail(s): {', '.join(senders)}")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
|
@ -160,8 +177,6 @@ def _alert_key(alert_text: str) -> str:
|
|||
|
||||
|
||||
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:
|
||||
|
|
@ -174,24 +189,26 @@ def _alert_category(alert_text: str) -> str:
|
|||
|
||||
|
||||
def _filter_new_alerts(alerts: list[str]) -> list[str]:
|
||||
"""Filtert bereits gemeldete Alerts. Gibt nur neue/fällige zurück."""
|
||||
"""Filtert bereits gemeldete Infra-Alerts per Cooldown. Mails werden separat in check_all() dedupliziert."""
|
||||
state = _load_alert_state()
|
||||
now = datetime.now(timezone.utc).timestamp()
|
||||
cooldowns = state.get("alert_cooldowns", {})
|
||||
new_alerts = []
|
||||
|
||||
for alert in alerts:
|
||||
key = _alert_key(alert)
|
||||
cat = _alert_category(alert)
|
||||
cooldown = ALERT_COOLDOWN_MINUTES.get(cat, 60) * 60
|
||||
cooldown = ALERT_COOLDOWN_SECONDS.get(cat, 3600)
|
||||
|
||||
last_sent = state.get(key, {}).get("ts", 0)
|
||||
last_sent = cooldowns.get(key, {}).get("ts", 0)
|
||||
if now - last_sent > cooldown:
|
||||
new_alerts.append(alert)
|
||||
state[key] = {"ts": now, "text": alert[:80], "cat": cat}
|
||||
cooldowns[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}
|
||||
cooldowns = {k: v for k, v in cooldowns.items() if v.get("ts", 0) > cutoff}
|
||||
|
||||
state["alert_cooldowns"] = cooldowns
|
||||
_save_alert_state(state)
|
||||
return new_alerts
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue