File size: 2,177 Bytes
a4a265d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import os
import requests
import time
from src.monitoring.logger import get_logger

logger = get_logger(__name__)

class AlertManager:
    """Manages system alerts via logs and optional webhooks for critical anomalies."""
    
    WEBHOOK_URL = os.getenv("ALERT_WEBHOOK_URL")
    _last_alerts = {} # Title -> timestamp cache for rate limiting
    _history = [] # Last 50 alerts for the UI
    ALERT_WINDOW_SEC = 60 # Cooldown period

    @classmethod
    def get_history(cls):
        return cls._history

    @classmethod
    def send_alert(cls, title: str, message: str, level: str = "WARNING") -> None:
        """Dispatches an alert with built-in spam suppression."""
        now = time.time()
        
        # Log to internal history for the UI dashboard
        cls._history.append({
            "timestamp": now,
            "title": title,
            "message": message,
            "level": level
        })
        if len(cls._history) > 50:
            cls._history.pop(0)

        if title in cls._last_alerts:
            if now - cls._last_alerts[title] < cls.ALERT_WINDOW_SEC:
                logger.debug(f"Suppressing redundant alert '{title}' within {cls.ALERT_WINDOW_SEC}s window.")
                return
        
        cls._last_alerts[title] = now
        full_msg = f"[{level}] {title}: {message}"
        
        # 1. Log the alert
        if level == "CRITICAL":
            logger.critical(full_msg)
        else:
            logger.warning(full_msg)
            
        # 2. Fire webhook if configured
        if cls.WEBHOOK_URL:
            try:
                payload = {
                    "text": full_msg,
                    "title": title,
                    "level": level,
                    "system": "Autonomous_ML_Builder",
                    "timestamp": now
                }
                requests.post(cls.WEBHOOK_URL, json=payload, timeout=5)
                logger.info(f"Alert sent to webhook: {cls.WEBHOOK_URL}")
            except Exception as e:
                logger.error(f"Failed to send webhook alert: {e}")
        else:
            logger.debug("No webhook URL configured. Alert restricted to local logs.")