#!/usr/bin/env python3 import sys sys.path.insert(0, '/usr/local/bin') import json import logging from http.server import HTTPServer, BaseHTTPRequestHandler from typing import Dict from alerts.matrix import send_matrix from alerts.grafana import process_grafana from alerts.pbs import detect_backup_source, process_backup from alerts.config import PORT logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s' ) logger = logging.getLogger(__name__) class WebhookHandler(BaseHTTPRequestHandler): def log_message(self, format, *args): logger.info("%s - %s", self.address_string(), format % args) def do_POST(self): try: content_length = int(self.headers.get('Content-Length', 0)) body = self.rfile.read(content_length).decode('utf-8') try: obj = json.loads(body) except json.JSONDecodeError as e: logger.error("JSON parse error: %s", e) self.send_error(400, "Invalid JSON") return self.process_webhook(obj) self.send_response(200) self.send_header('Content-Type', 'text/plain') self.end_headers() self.wfile.write(b"OK") except Exception as e: logger.exception("Error processing request") self.send_error(500, "Internal Server Error") def process_webhook(self, obj: Dict) -> None: source = detect_backup_source(obj) if source: logger.info("Processing backup notification (source=%s)", source.value) process_backup(obj, send_matrix, source) return if "alerts" in obj: alerts = obj["alerts"] logger.info("Processing Grafana alerts: %d items", len(alerts)) process_grafana({"alerts": alerts}, send_matrix) return logger.warning("Unknown webhook type") send_matrix( "Webhook received

" +
            json.dumps(obj, ensure_ascii=False, indent=2) +
            "
" ) def main(): server = HTTPServer(("0.0.0.0", PORT), WebhookHandler) logger.info("Matrix Relay started on port %s", PORT) try: server.serve_forever() except KeyboardInterrupt: logger.info("Shutting down...") server.shutdown() if __name__ == "__main__": main()