From 6381c44ef79a5a395cd753421f2409f688682d48 Mon Sep 17 00:00:00 2001 From: zailon Date: Tue, 23 Jun 2026 15:38:26 +0500 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D1=82?= =?UTF-8?q?=D1=8C=20docs/services/lxc208-manage/alert/README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/services/lxc208-manage/alert/README.md | 153 ++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 docs/services/lxc208-manage/alert/README.md diff --git a/docs/services/lxc208-manage/alert/README.md b/docs/services/lxc208-manage/alert/README.md new file mode 100644 index 0000000..17ecd9e --- /dev/null +++ b/docs/services/lxc208-manage/alert/README.md @@ -0,0 +1,153 @@ +# Matrix Alert Relay — Документация + +## 1. Архитектура и структура проекта +Проект представляет собой HTTP-сервер (вебхук-релей), который принимает POST-запросы от систем мониторинга, парсит их, форматирует и отправляет в нужные комнаты Matrix. + +**Основные файлы:** +- `matrix-relay.py` — точка входа. HTTP-сервер, принимающий запросы и маршрутизирующий их. +- `config.py` — глобальные настройки (адрес Homeserver, токен, порт). +- `rooms.py` — маппинг логических имен каналов (`disk`, `backup`, `docker`) на ID комнат Matrix. +- `alerts.py` — словарь `ALERTS_CONFIG` с описанием всех известных типов алертов. +- `grafana.py` — обработчик стандартных вебхуков от Grafana/Prometheus. +- `pbs.py` — обработчик специфичных вебхуков от Proxmox VE / Proxmox Backup Server. +- `formatters.py` — функции красивого форматирования текста для специфичных алертов. +- `matrix.py` — низкоуровневая отправка HTML-сообщений в Matrix API. +- `utils.py` — вспомогательные утилиты (экранирование HTML, форматирование байтов и т.д.). + +--- + +## 2. Сценарий А: Добавление нового алерта (Grafana / Prometheus) +Если новый алерт приходит из Grafana или Prometheus, писать новый код парсинга не нужно. Достаточно обновить конфигурацию. + +### Шаг 2.1. Добавление комнаты (если нужна новая) +Открой `rooms.py` и добавь новое имя канала и ID комнаты: +```python +CHANNELS = { + "default": "!WlzSAzmLQEATwDCaBU:matrix.zailon.ru", + "disk": "!wOlscPjqPWVbSHpYgc:matrix.zailon.ru", + "backup": "!ViUbvoFxTTbRLMtZEO:matrix.zailon.ru", + "ups": "!NewRoomId:matrix.zailon.ru", +} +``` + +### Шаг 2.2. Создание форматтера (опционально) +Если алерт требует особого вывода (например, вывод заряда батареи в процентах), открой `formatters.py`: +```python +def ups_battery(device, value=None): + if value is not None: + return f"🔋 {device:<8} {value}%" + return f"🔋 {device:<8}" + +FORMATTERS = { + "temperature": temperature, + "ups_battery": ups_battery, +} +``` + +### Шаг 2.3. Регистрация алерта +Открой `alerts.py` и добавь новый ключ в `ALERTS_CONFIG`. Имя ключа должно точно совпадать с `alertname` из Grafana. +```python +ALERTS_CONFIG = { + "UPS Battery Low": { + "room": "ups", + "title": "🔋 Низкий заряд ИБП", + "summary": "⚡ Заряд батареи ИБП упал ниже критического.", + "info": "🔌 Проверьте питание и состояние ИБП.", + "resolved": "✅ Питание ИБП восстановлено.", + "formatter": "ups_battery", + "skip_zero_firing": False, + }, +} +``` +Релей автоматически подхватит новый алерт, отформатирует его и отправит в нужную комнату. + +--- + +## 3. Сценарий Б: Добавление нового ИСТОЧНИКА алертов (кастомный вебхук) +Если новая система (например, Docker Events, Zabbix, или скрипт мониторинга UPS) шлет свой собственный JSON, не похожий на формат Grafana, нужно написать новый модуль. + +### Шаг 3.1. Создание модуля-обработчика +Создай новый файл, например `ups.py` (по аналогии с `pbs.py`). +```python +import logging +from alerts.matrix import send_matrix + +logger = logging.getLogger(__name__) + +def process_ups_alert(obj: dict) -> None: + ups_name = obj.get("ups_name", "Unknown UPS") + battery_level = obj.get("battery", 0) + status = obj.get("status", "unknown") + + if status == "critical": + text = f"🚨 Критический разряд ИБП\n\n" + text += f"🔋 {ups_name}\n" + text += f"📉 Осталось заряда: {battery_level}%\n" + text += "⚡ Срочно проверьте питание!" + room = "ups" + else: + text = f"ℹ️ Статус ИБП\n\n{ups_name}: {battery_level}%" + room = "default" + + send_matrix(text, room) +``` + +### Шаг 3.2. Подключение обработчика в роутер +Открой `matrix-relay.py`. В методе `process_webhook` добавь условие для определения нового источника и вызови свою функцию. +```python +from alerts.ups import process_ups_alert + +class WebhookHandler(BaseHTTPRequestHandler): + def process_webhook(self, obj: Dict) -> None: + if "ups_name" in obj: + logger.info("Processing UPS notification") + process_ups_alert(obj) + return + + 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) +
+            "
" + ) +``` +Теперь при отправке POST-запроса на сервер с JSON `{"ups_name": "APC", "battery": 10, "status": "critical"}` алерт улетит в Matrix. + +--- + +## 4. Шпаргалка по настройке вебхуков +- **URL для всех источников:** `http://:8086/` (или `https://`, если стоит реверс-прокси). +- **Метод:** POST +- **Content-Type:** `application/json` + +### Пример вызова из bash-скрипта (для Docker, UPS, Cron): +```bash +curl -X POST http://127.0.0.1:8086/ \ + -H "Content-Type: application/json" \ + -d '{"ups_name": "ServerRoom_UPS", "battery": 5, "status": "critical"}' +``` + +--- + +## 5. Логирование и отладка +Все события пишутся в стандартный вывод. Если релей запущен через systemd, смотри логи: +```bash +journalctl -u matrix-relay -f +``` + +Если алерт пришел, но не обработался так, как ожидалось, ищи в логах строки: +- `Processing Grafana alerts` — релей распознал формат Grafana. +- `Processing backup notification` — релей распознал бэкап PVE/PBS. +- `Unknown webhook type` — релей не нашел знакомых ключей и отправил "сырой" JSON в комнату `default`. Используй это для отладки новых источников! \ No newline at end of file