feat(openspec): vesti-alerts — 6 алертов на компоненты VESTI (web/publisher/tunnel/db/stale); OpenSpec change

This commit is contained in:
kpa39l
2026-09-13 15:34:47 +00:00
parent df1ebed76d
commit 62a4f1a0db
7 changed files with 342 additions and 1 deletions
@@ -0,0 +1,61 @@
# Design
## Механизм алертов
В стеке /opt/monitoring алерты реализованы **Prometheus Alerting rules** (prometheus.yml
`rule_files: /etc/prometheus/alerts.yml`, Prometheus 3.1+ встроенный алертинг с мульти-секционной
группировкой `groups:`/`rules:`). Формат rules (алерты на базе PromQL-выражений с `for` = время
удержания условия, `labels.severity`, `annotations.summary`). Доставка уведомлений — согласно
существующей конфигурации (webhook/канал, настроенный в Prometheus или в той же alerts.yml
внешним получателем — проверить фактический механизм доставки в стеке; в референсах скилла
указано, что уведомления приходят в чат).
## Метрики VESTI (textfile-коллектор, job `node`, label `component="vesti"`)
| Метрика | Смысл | Алерт |
|---|---|---|
| vesti_web_up | web :8400 (systemd) | ==0 → critical |
| vesti_publisher_health | publisher :8410 /healthz | ==0 → critical |
| vesti_publisher_docker | контейнер publisher (docker ps) | ==0 → critical |
| vesti_telegram_tunnel | SOCKS5-туннель :1080 | ==0 → critical |
| vesti_db_ok | SQLite vesti.db доступна | ==0 → critical |
| vesti_db_last_run_ts | Unix-ts последнего рan краулера | time()-ts >1800 → warning |
## Формат rules (из alerts.yml)
```yaml
groups:
- name: vesti
rules:
- alert: VestiWebDown
expr: vesti_web_up{component="vesti"} == 0
for: 2m
labels:
severity: critical
annotations:
summary: VESTI web (:8400) is down
```
Время реакции: `for: 2m` — алерт срабатывает после 2 минут непрерывного условия
(метрики обновляются раз в минуту скриптом vesti-metrics.sh → 2-3 пробы подряд).
## Верификация
1. `docker exec prometheus promtool check config /etc/prometheus/prometheus.yml` → OK
(проверяет и rule_files).
2. `docker compose restart prometheus` (перечитывает alerts.yml).
3. Запрос в Prometheus API: значения метрик vesti_* присутствуют.
4. Проверка алертов: имитация (временно выставить метрику в 0, убедиться что алерт firing,
вернуть обратно) — или проверка через Prometheus /api/v1/rules/дубликат.
5. Обновить README.md + EXPERIENCE.md, openspec validate + archive.
## Риски
- При `for: 2m` и интервале скрипта 1 мин алерт может срабатывать с задержкой до 3 мин
(приемлемо для внутреннего сервиса).
- Метрики пишутся только при успешном выполнении скрипта; если textfile-файл пропадёт
(сломан скрипт) — метрики исчезнут и алерт по `==0` не сработает. Для этого есть
`VestiDbStale` (time() - ts) — он тоже покроет случай пропадания данных? Нет: если файл
пропал, ts не обновится → last_run_ts останется старым → VestiDbStale сработает.
Дополнительно можно добавить expr на отсутствие данных (deadman), но это выходит за рамки
текущего change — зафиксировать в EXPERIENCE.md как известное ограничение.
@@ -0,0 +1,30 @@
# Proposal: vesti-alerts
## Why
Проект /opt/vesti (веб :8400 + publisher-контейнер :8410 + SOCKS5-туннель :1080 + SQLite БД)
получил дашборд VESTI в Grafana (2026-09-13), но **алертов на падение компонентов нет**:
при недоступности web/publisher/туннеля/БД никто не узнает в реальном времени (только постфактум
на дашборде). Нужны алерты в существующем механизме мониторинга (Prometheus rule_files → alerts.yml)
на все компоненты vesti, с уведомлением (webhook/настроенный канал).
## What Changes
- В `/opt/monitoring/alerts.yml` добавляется группа `vesti` с алертами:
- `VestiWebDown` — `vesti_web_up{component="vesti"} == 0`, for 2m, severity: critical
- `VestiPublisherDown` — `vesti_publisher_health{component="vesti"} == 0`, for 2m, severity: critical
- `VestiPublisherContainerDown` — `vesti_publisher_docker{component="vesti"} == 0`, for 2m, severity: critical
- `VestiTunnelDown` — `vesti_telegram_tunnel{component="vesti"} == 0`, for 2m, severity: critical
- `VestiDbDown` — `vesti_db_ok{component="vesti"} == 0`, for 2m, severity: critical
- `VestiDbStale` — `time() - vesti_db_last_run_ts{component="vesti"} > 1800`, for 5m, severity: warning
(краулер не работал >30 мин)
- Все алерты аннотируются summary с именем компонента.
- Верификация: `promtool check config` + запрос фактических значений в Prometheus API.
## Capabilities
### New Capabilities
- `vesti-alerts`: алерты на компоненты VESTI (web, publisher, docker, tunnel, db, краулер staleness).
### Modified Capabilities
- `monitoring-stack` (alerts.yml) — добавлена группа `vesti`.
@@ -0,0 +1,99 @@
# vesti-alerts
## ADDED Requirements
### Requirement: VestiWebDown
Алерт на недоступность web-интерфейса VESTI (:8400, systemd-юнит).
#### Scenario: web не отвечает
- Given метрика `vesti_web_up{component="vesti"}` = 0
- When условие держится 2 минуты
- Then алерт `VestiWebDown` переходит в Firing (severity critical)
#### Scenario: web восстановился
- Given метрика `vesti_web_up{component="vesti"}` = 1
- When алерт в Firing
- Then алерт закрывается автоматически
### Requirement: VestiPublisherDown
Алерт на недоступность publisher-сервиса VESTI (:8410, /healthz).
#### Scenario: publisher не отвечает
- Given метрика `vesti_publisher_health{component="vesti"}` = 0
- When условие держится 2 минуты
- Then алерт `VestiPublisherDown` переходит в Firing (severity critical)
#### Scenario: publisher восстановился
- Given метрика `vesti_publisher_health{component="vesti"}` = 1
- When алерт в Firing
- Then алерт закрывается автоматически
### Requirement: VestiPublisherContainerDown
Алерт на остановку Docker-контейнера publisher.
#### Scenario: контейнер publisher не в статусе Up
- Given метрика `vesti_publisher_docker{component="vesti"}` = 0
- When условие держится 2 минуты
- Then алерт `VestiPublisherContainerDown` переходит в Firing (severity critical)
#### Scenario: контейнер publisher снова Up
- Given метрика `vesti_publisher_docker{component="vesti"}` = 1
- When алерт в Firing
- Then алерт закрывается автоматически
### Requirement: VestiTunnelDown
Алерт на недоступность SOCKS5-туннеля Telegram (:1080).
#### Scenario: туннель недоступен
- Given метрика `vesti_telegram_tunnel{component="vesti"}` = 0
- When условие держится 2 минуты
- Then алерт `VestiTunnelDown` переходит в Firing (severity critical)
#### Scenario: туннель восстановился
- Given метрика `vesti_telegram_tunnel{component="vesti"}` = 1
- When алерт в Firing
- Then алерт закрывается автоматически
### Requirement: VestiDbDown
Алерт на недоступность SQLite-базы vesti.db.
#### Scenario: БД недоступна
- Given метрика `vesti_db_ok{component="vesti"}` = 0
- When условие держится 2 минуты
- Then алерт `VestiDbDown` переходит в Firing (severity critical)
#### Scenario: БД восстановилась
- Given метрика `vesti_db_ok{component="vesti"}` = 1
- When алерт в Firing
- Then алерт закрывается автоматически
### Requirement: VestiDbStale
Алерт на устаревание данных краулера (не запускался >30 минут).
#### Scenario: краулер не запускался более 30 минут
- Given метрика `vesti_db_last_run_ts{component="vesti"}` = T
- When `time() - T` > 1800 секунд и условие держится 5 минут
- Then алерт `VestiDbStale` переходит в Firing (severity warning)
#### Scenario: краулер снова запустился
- Given метрика `vesti_db_last_run_ts{component="vesti"}` обновлена (time() - ts < 1800)
- When алерт в Firing
- Then алерт закрывается автоматически
@@ -0,0 +1,22 @@
# Tasks
## 1. Алерты в alerts.yml
- [x] 1.1 В `/opt/monitoring/alerts.yml` добавить группу `vesti`:
- VestiWebDown (vesti_web_up == 0, for 2m, critical)
- VestiPublisherDown (vesti_publisher_health == 0, for 2m, critical)
- VestiPublisherContainerDown (vesti_publisher_docker == 0, for 2m, critical)
- VestiTunnelDown (vesti_telegram_tunnel == 0, for 2m, critical)
- VestiDbDown (vesti_db_ok == 0, for 2m, critical)
- VestiDbStale (time() - vesti_db_last_run_ts > 1800, for 5m, warning)
- [x] 1.2 Проверка: `docker exec prometheus promtool check config /etc/prometheus/prometheus.yml` → OK (13 rules)
- [x] 1.3 Рестарт: `docker restart prometheus`
- [x] 1.4 Проверка: группа vesti в /api/v1/rules, 6 правил, state=inactive (норма)
## 2. Документация
- [x] 2.1 Обновить `/opt/monitoring/README.md` (секция VESTI: алерты, метрики)
- [x] 2.2 Добавить запись в `/opt/monitoring/EXPERIENCE.md` (22-24: textfile, alerting, OpenSpec)
## 3. Git и OpenSpec
- [ ] 3.1 `git add` (поимённо) + commit + push в gitverse (истина), gitea подтянет mirror
- [ ] 3.2 `openspec validate` + `openspec archive --yes`
- [ ] 3.3 Обновить STATUS.md/WALKTHROUGH.md