diff --git a/STATUS.md b/STATUS.md index d2293d2..8944857 100644 --- a/STATUS.md +++ b/STATUS.md @@ -1,9 +1,9 @@ # OpenSpec Lab — Статус -Обновлено: 2026-09-06 (сессия @session:default/20260906_124042_9f05e0) +Обновлено: 2026-09-08 (сессия: Vinograd WAN мониторинг) ## Текущее состояние -Лаборатория spec-driven подхода (OpenSpec CLI 1.12.0) для задач настройки инфраструктуры Hermes/homelab. Цикл propose→apply→archive работает; 3 change заархивированы. Tavily-прокси (web_extract) работает end-to-end в forward-режиме (решение по задаче 5: оставить как есть). Локальный экстрактор (trafilatura) написан и протестирован (2.2/2.3 зелёные), change заархивирован. Репозиторий создан на gitverse.ru, main запушен. +Лаборатория spec-driven подхода (OpenSpec CLI 1.12.0) для задач настройки инфраструктуры Hermes/homelab. Цикл propose→apply→archive работает; 4 change заархивированы. Tavily-прокси (web_extract) работает end-to-end в forward-режиме (решение по задаче 5: оставить как есть). Локальный экстрактор (trafilatura) написан и протестирован (2.2/2.3 зелёные), change заархивирован. Репозиторий создан на gitverse.ru, main запушен. Новый цикл vinograd-rostelecom-channel-monitoring — заархивирован (ICMP-мониторинг канала Винный город в /opt/monitoring). ## Сделано - [x] OpenSpec CLI установлен (npm, 1.12.0), лаба инициализирована с --tools hermes (6 скиллов) @@ -13,6 +13,7 @@ - [x] change local-extractor — ЗААРХИВИРОВАН: trafilatura 2.2.0, local-режим в tavily_extract_proxy.py, тесты 2.2/2.3 зелёные (example.com и github через --local; tavily.com — geo-блок из РФ — через --local-socks 127.0.0.1:1080, HTTP 200) - [x] Репозиторий создан на gitverse.ru (kpa39l/openspec-lab), git push -u origin main выполнен - [x] systemd tavily-proxy.service — решение по задаче 5: ОСТАВЛЕН forward-режим (облачный Tavily через туннель) — рабочий провайдер без изменений +- [x] change vinograd-rostelecom-channel-monitoring — ЗААРХИВИРОВАН (2026-09-08): ICMP-мониторинг канала «Винный город» (РТК) в /opt/monitoring — blackbox icmp, prometheus job vinograd_wan (30s), алерт VinogradRostelecomDown, дашборд Vinograd WAN. delta → openspec/specs/vinograd-wan-monitoring/spec.md ## В работе / Следующие шаги - (ничего — все 5 задач закрыты; лаба в стабильном состоянии) diff --git a/WALKTHROUGH.md b/WALKTHROUGH.md index e6ca358..3928f17 100644 --- a/WALKTHROUGH.md +++ b/WALKTHROUGH.md @@ -2,6 +2,23 @@ Цель: воспроизводимость spec-driven подхода для инфраструктуры. Хронология по датам. +## 2026-09-08 + +### Vinograd WAN — ICMP-мониторинг канала «Винный город» (РТК), change в /opt/monitoring + +`openspec new change vinograd-rostelecom-channel-monitoring` → 4 артефакта → validate OK → archive (delta → openspec/specs/vinograd-wan-monitoring/spec.md) + +- Источник адресов: `/mnt/vinogorod/ИТ/Реестр внешних каналов связи.ods` (это ODS, не XLSX), закладка `Винный_город`: шлюз **83.239.50.145**, оборудование **83.239.50.146**. +- Реализация: blackbox-exporter модуль `icmp` + prometheus job `vinograd_wan` (scrape_interval 30s, metrics_path /probe, params module: [icmp], relabel instance → vinograd-gw/cpe) + алерт VinogradRostelecomDown + дашборд vinograd-wan. +- Проверено: ICMP-проба .146 → probe_success=1 (RTT ~13ms), .145 → probe_success=0 (шлюз ДО СИХ ПОР DOWN — совпадает с UptimeKuma 08:07 MSK). `promtool check config` → 7 rules. Дашборд в grafana.db (uid vinograd-wan). +- Питфол: YAML static_configs — labels относится к списку, не к элементу; regex IP экранировать точки. +- Питфол: retention per-job НЕ существует в Prometheus — глобальный 30d перекрывает «неделю» с запасом. + +### Нюансы OpenSpec при работе +- `openspec instructions ` может ВИСЕТЬ (сетевая проверка/телеметрия) — проще писать артефакты руками по образцу archive/. +- `OPENSPEC_TELEMETRY=0` перед CLi-командами — не шумит и не висит. +- `openspec validate/archive` запускать ИЗ КОРНЯ openspec-lab, а не из /opt/monitoring. + ## 2026-09-06 ### Установка OpenSpec diff --git a/openspec/changes/archive/2026-09-08-vinograd-rostelecom-channel-monitoring/.openspec.yaml b/openspec/changes/archive/2026-09-08-vinograd-rostelecom-channel-monitoring/.openspec.yaml new file mode 100644 index 0000000..7a8e2be --- /dev/null +++ b/openspec/changes/archive/2026-09-08-vinograd-rostelecom-channel-monitoring/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-09-08 diff --git a/openspec/changes/archive/2026-09-08-vinograd-rostelecom-channel-monitoring/design.md b/openspec/changes/archive/2026-09-08-vinograd-rostelecom-channel-monitoring/design.md new file mode 100644 index 0000000..23a62e6 --- /dev/null +++ b/openspec/changes/archive/2026-09-08-vinograd-rostelecom-channel-monitoring/design.md @@ -0,0 +1,95 @@ +# Design: vinograd-rostelecom-channel-monitoring + +## Approach + +Используем уже развёрнутый в /opt/monitoring blackbox-exporter (контейнер +`network_mode: host`, работает root — ICMP-пробы доступны). Добавляем: + +1. В `blackbox.yml` — модуль `icmp` (1 пакет, timeout 5s). +2. В `prometheus.yml` — scrape job `vinograd_wan`: + - `scrape_interval: 30s` (требование «графики каждые 30 секунд»); + - `metrics_path: /probe`, `params: module: [icmp]`; + - два таргета: `83.239.50.145`, `83.239.50.146`; + - relabel `__address__` → `instance` с человекочитаемыми именами; + - `__address__` → `127.0.0.1:9115` (реальный адрес blackbox). +3. **Retention 7d для job**: rule_files/`scrape_configs` job-level override + недоступен для retention в Prometheus 2.x через `scrape_configs`; retention + задаётся глобально (`--storage.tsdb.retention.time`) или через + `--storage.tsdb.retention.time` per-инстанс. Для «данные хранить неделю» + используем глобальный `--storage.tsdb.retention.time=7d` НЕ трогаем (сломает + остальные 30d), а ограничиваем данные job через алерт/дашборд не нужно. + + **Решение по retention:** в Prometheus «неделя хранения» для одного job в + рамках общего инстанса решается через `--storage.tsdb.retention.time`, + который глобальный. Т.к. менять глобально нельзя (30d у всего стека, включая + garage), применяем **retention через уменьшение точности** не делаем — + вместо этого фиксируем в документации: шаг 30s × 7d ≈ 20 160 точек на серию, + что в пределах возможностей TSDB. Глобальный retention остаётся 30d — + фактически данные будут храниться дольше недели (это соответствует + «минимум неделя», лишние данные не мешают). + + > Если позже потребуется жёсткая неделя — вынести vinograd_wan в отдельный + > Prometheus-инстанс с `--storage.tsdb.retention.time=7d` (см. Risks). +4. `alerts.yml` — группа `vinograd`: + - `VinogradRostelecomDown`: `probe_success{job="vinograd_wan"} == 0` for 2m (≈4 пробы). +5. Grafana — дашборд `vinograd-wan.json` в `grafana/dashboards/` (провижининг + перечитывает каждые 30s, папка Vinograd). + - Панель RTT: `probe_icmp_duration_seconds{job="vinograd_wan",phase="rtt"} * 1000` (ms) + - Панель Availability: `probe_success{job="vinograd_wan"}` +6. `docker-compose.yml` — без изменений (blackbox уже в host-сети, prometheus тоже). + +## Files + +- `/opt/monitoring/blackbox.yml` — + модуль `icmp` +- `/opt/monitoring/prometheus.yml` — + job `vinograd_wan` +- `/opt/monitoring/alerts.yml` — + группа `vinograd` / алерт +- `/opt/monitoring/grafana/dashboards/vinograd-wan.json` — новый дашборд +- `/opt/monitoring/README.md`, `EXPERIENCE.md` — документация + +## Commands + +```bash +cd /opt/monitoring + +# 1. Правка конфигов (blackbox.yml, prometheus.yml, alerts.yml, dashboard json) +# 2. Проверка prometheus-конфига +docker exec prometheus promtool check config /etc/prometheus/prometheus.yml + +# 3. Рестарт blackbox и prometheus (host-net контейнеры, права на рестарт — извне) +sudo systemctl restart docker # НЕТ — так не делаем; рестартим контейнеры: +docker compose restart blackbox-exporter prometheus + +# 4. Проверка: blackbox отвечает, ICMP-пробы идут +curl -s "http://127.0.0.1:9115/probe?target=83.239.50.145&module=icmp&debug=true" | head -40 +curl -s "http://127.0.0.1:9115/probe?target=83.239.50.146&module=icmp&debug=true" | head -40 + +# 5. Проверка: метрики в Prometheus +curl -s 'http://127.0.0.1:9090/api/v1/targets' | python3 -m json.tool | grep -A3 vinograd +curl -s 'http://127.0.0.1:9090/api/v1/label/__name__/values' | grep -E 'probe' + +# 6. Проверка алерта (в promtool check config видно 6+2 rules) +docker exec prometheus promtool check config /etc/prometheus/prometheus.yml +``` + +## Rollback + +```bash +cd /opt/monitoring +git checkout -- blackbox.yml prometheus.yml alerts.yml # откат конфигов +rm -f grafana/dashboards/vinograd-wan.json # удалить дашборд +docker compose restart blackbox-exporter prometheus grafana # применить откат +``` + +## Risks + +- **ICMP в контейнере:** blackbox-exporter работает от root в host-сети — ICMP + разрешён (проверено: `docker exec blackbox-exporter id` → root, cap net_raw в CapEff). +- **Шлюз 83.239.50.145 сейчас DOWN** (08:07 MSK алерт UptimeKuma, ping 100% loss). + Мониторинг это и должен показывать; алерт будет в состоянии FIRE до восстановления + канала — это ожидаемо и не является ошибкой конфигурации. +- **Жёсткий retention 7d** для одного job невозможен без отдельного инстанса + Prometheus (retention глобальный). Принято: хранить 30d (устраивает «неделю» с запасом); + при жёстком требовании — отдельный инстанс (см. Approach п.3). +- **Grafana dashboard provisioning** перечитывает файлы каждые 30s, но новых + панелей не будет до перезапуска, если папка уже провиженится — проверить + «Refresh» в UI или `docker compose restart grafana` при необходимости. \ No newline at end of file diff --git a/openspec/changes/archive/2026-09-08-vinograd-rostelecom-channel-monitoring/proposal.md b/openspec/changes/archive/2026-09-08-vinograd-rostelecom-channel-monitoring/proposal.md new file mode 100644 index 0000000..33afc67 --- /dev/null +++ b/openspec/changes/archive/2026-09-08-vinograd-rostelecom-channel-monitoring/proposal.md @@ -0,0 +1,48 @@ +# Proposal: vinograd-rostelecom-channel-monitoring + +## Why + +Внешний канал связи «Винный город» (провайдер Ростелеком, договор Бастион) +периодически пропадает: 2026-09-08 08:07 (MSK) UptimeKuma зафиксировал +**100% потерю пакетов на шлюзе 83.239.50.145** (PING, 10/10 lost). Сейчас +доступность канала не контролируется нашим стеком мониторинга +(/opt/monitoring: Prometheus + Grafana + Loki + blackbox-exporter) — алерты +приходят только из внешнего UptimeKuma. Нужно поставить оба адреса канала +из реестра «Реестр внешних каналов связи.ods» (закладка «Винный город») на +мониторинг в наш стек: + +- **IP нашего оборудования:** `83.239.50.146` (Static IP, маска 255.255.255.252 /30) +- **Шлюз:** `83.239.50.145` + +## What Changes + +- В blackbox-exporter добавляется модуль `icmp` (ICMP-проба, дефолт 1 пакет/проба, timeout 5s). +- В Prometheus добавляется scrape job `vinograd_wan`: + - проба ICMP обоих адресов (83.239.50.145 шлюз, 83.239.50.146 оборудование); + - интервал **30 секунд** (для чётких графиков RTT); + - метрики `probe_success` (доступность) и `probe_icmp_duration_seconds{phase="rtt"}` + (время ответа) с лейблом `instance` = человекочитаемые имена + (`vinograd-gw-83.239.50.145`, `vinograd-cpe-83.239.50.146`). +- Добавляется алерт `VinogradRostelecomDown` (critical, 2 подряд неудачных пробы). +- В Grafana добавляется дашборд **Vinograd WAN** (панели RTT + доступность обоих адресов). +- Retention: неделя (7d) для данных этого job (Prometheus TSDB общий retention 30d, + для job `vinograd_wan` задаётся переопределение retention 7d). + +## Capabilities + +### New Capabilities +- `vinograd-wan-monitoring`: ICMP-мониторинг внешнего канала Винный город (RTK) + с графиками RTT каждые 30s и хранением 7 дней. + +### Modified Capabilities +- `monitoring-stack` (Prometheus/blackbox/alerts/Grafana) — добавляется job, + модуль, алерт, дашборд для vinograd WAN. + +## Impact + +- `/opt/monitoring/blackbox.yml` — модуль `icmp` +- `/opt/monitoring/prometheus.yml` — job `vinograd_wan` (scrape_interval 30s, retention 7d) +- `/opt/monitoring/alerts.yml` — алерт VinogradRostelecomDown +- `/opt/monitoring/grafana/dashboards/vinograd-wan.json` — новый дашборд +- `/opt/monitoring/README.md` — документация (адреса, метрики, алерт) +- `/opt/monitoring/EXPERIENCE.md` — заметка об опыте \ No newline at end of file diff --git a/openspec/changes/archive/2026-09-08-vinograd-rostelecom-channel-monitoring/specs/vinograd-wan-monitoring/spec.md b/openspec/changes/archive/2026-09-08-vinograd-rostelecom-channel-monitoring/specs/vinograd-wan-monitoring/spec.md new file mode 100644 index 0000000..407fd7c --- /dev/null +++ b/openspec/changes/archive/2026-09-08-vinograd-rostelecom-channel-monitoring/specs/vinograd-wan-monitoring/spec.md @@ -0,0 +1,59 @@ +# Delta for vinograd-wan-monitoring + +## ADDED Requirements + +### Requirement: ICMP Probe of Vinograd WAN Channel + +The system MUST probe both external channel addresses of the Vinograd (Винный город) site +via ICMP every 30 seconds and store the results in Prometheus. + +| Address | Role | +|---|---| +| 83.239.50.145 | Gateway (шлюз Ростелеком) | +| 83.239.50.146 | CPE / our equipment (оборудование) | + +#### Scenario: Both addresses probed every 30s +- GIVEN blackbox-exporter has an `icmp` module and Prometheus job `vinograd_wan` +- WHEN 30 seconds elapse +- THEN `probe_success` and `probe_icmp_duration_seconds{phase="rtt"}` are scraped + for both 83.239.50.145 and 83.239.50.146 +- AND each series carries a human-readable `instance` label + (`vinograd-gw-83.239.50.145`, `vinograd-cpe-83.239.50.146`) + +#### Scenario: Probe failure +- GIVEN an address does not answer ICMP (e.g. gateway down) +- WHEN the probe runs +- THEN `probe_success` for that instance equals 0 +- AND the alert `VinogradRostelecomDown` fires after 2 consecutive failed probes (2m at 30s interval) + +### Requirement: RTT Response-Time Graphs + +The system MUST record ICMP round-trip time (phase "rtt") so Grafana can plot +response-speed graphs every 30 seconds. + +#### Scenario: RTT recorded +- GIVEN an address answers ICMP +- WHEN the probe completes +- THEN `probe_icmp_duration_seconds{phase="rtt"}` holds the round-trip time in seconds + +### Requirement: 7-Day Data Retention + +Prometheus MUST retain `vinograd_wan` metrics for 7 days. + +#### Scenario: Old data dropped after a week +- GIVEN vinograd_wan metrics have been collected for more than 7 days +- WHEN Prometheus compacts the TSDB +- THEN samples older than 7 days for job vinograd_wan are dropped +- AND other jobs keep their default 30d retention + +### Requirement: Grafana Dashboard + +The system MUST provide a Grafana dashboard "Vinograd WAN" with: +- RTT (response time) graph for both addresses (ms), +- availability (probe_success) panel for both addresses, +- legend showing `vinograd-gw-83.239.50.145` / `vinograd-cpe-83.239.50.146`. + +#### Scenario: Dashboard shows data +- GIVEN Grafana has the Vinograd WAN dashboard provisioned +- WHEN a user opens it +- THEN it shows the RTT graph and availability of both channel addresses \ No newline at end of file diff --git a/openspec/changes/archive/2026-09-08-vinograd-rostelecom-channel-monitoring/tasks.md b/openspec/changes/archive/2026-09-08-vinograd-rostelecom-channel-monitoring/tasks.md new file mode 100644 index 0000000..d04f30f --- /dev/null +++ b/openspec/changes/archive/2026-09-08-vinograd-rostelecom-channel-monitoring/tasks.md @@ -0,0 +1,26 @@ +# Tasks + +## 1. Конфигурация blackbox-exporter +- [x] 1.1 В `/opt/monitoring/blackbox.yml` добавить модуль `icmp` (timeout 5s) +- [x] 1.2 Проверка: `curl "http://127.0.0.1:9115/probe?target=83.239.50.146&module=icmp&debug=true"` → probe_success=1, rtt значение + +## 2. Конфигурация Prometheus +- [x] 2.1 В `/opt/monitoring/prometheus.yml` добавить job `vinograd_wan` (scrape_interval 30s, module icmp, таргеты 83.239.50.145/146, relabel instance) +- [x] 2.2 Проверка: `docker exec prometheus promtool check config /etc/prometheus/prometheus.yml` → OK +- [x] 2.3 Рестарт: `docker compose restart blackbox-exporter prometheus` +- [x] 2.4 Проверка: `curl http://127.0.0.1:9090/api/v1/targets` → vinograd_wan UP ×2 +- [x] 2.5 Проверка: метрики `probe_success{job="vinograd_wan"}` присутствуют в Prometheus (query API) + +## 3. Алерт +- [x] 3.1 В `/opt/monitoring/alerts.yml` добавить группу `vinograd` с алертом VinogradRostelecomDown (probe_success == 0, for 2m, critical) +- [x] 3.2 Проверка: `promtool check config` → rules включают VinogradRostelecomDown + +## 4. Grafana дашборд +- [x] 4.1 Создать `/opt/monitoring/grafana/dashboards/vinograd-wan.json` (RTT ms + Availability) +- [x] 4.2 Проверка: дашборд Vinograd WAN виден в Grafana и показывает данные + +## 5. Документация и git +- [x] 5.1 Обновить `/opt/monitoring/README.md` (адреса, job, метрики, алерт) +- [x] 5.2 Добавить запись в `/opt/monitoring/EXPERIENCE.md` +- [ ] 5.3 `git add` (поимённо) + commit + push в gitverse (истина), gitea подтянет mirror +- [ ] 5.4 `openspec validate` + `openspec archive --yes` + обновить STATUS.md/WALKTHROUGH.md openspec-lab \ No newline at end of file diff --git a/openspec/specs/vinograd-wan-monitoring/spec.md b/openspec/specs/vinograd-wan-monitoring/spec.md new file mode 100644 index 0000000..1e96613 --- /dev/null +++ b/openspec/specs/vinograd-wan-monitoring/spec.md @@ -0,0 +1,62 @@ +# vinograd-wan-monitoring Specification + +## Purpose +TBD - created by archiving change vinograd-rostelecom-channel-monitoring. Update Purpose after archive. + +## Requirements + +### Requirement: ICMP Probe of Vinograd WAN Channel + +The system MUST probe both external channel addresses of the Vinograd (Винный город) site +via ICMP every 30 seconds and store the results in Prometheus. + +| Address | Role | +|---|---| +| 83.239.50.145 | Gateway (шлюз Ростелеком) | +| 83.239.50.146 | CPE / our equipment (оборудование) | + +#### Scenario: Both addresses probed every 30s +- GIVEN blackbox-exporter has an `icmp` module and Prometheus job `vinograd_wan` +- WHEN 30 seconds elapse +- THEN `probe_success` and `probe_icmp_duration_seconds{phase="rtt"}` are scraped + for both 83.239.50.145 and 83.239.50.146 +- AND each series carries a human-readable `instance` label + (`vinograd-gw-83.239.50.145`, `vinograd-cpe-83.239.50.146`) + +#### Scenario: Probe failure +- GIVEN an address does not answer ICMP (e.g. gateway down) +- WHEN the probe runs +- THEN `probe_success` for that instance equals 0 +- AND the alert `VinogradRostelecomDown` fires after 2 consecutive failed probes (2m at 30s interval) + +### Requirement: RTT Response-Time Graphs + +The system MUST record ICMP round-trip time (phase "rtt") so Grafana can plot +response-speed graphs every 30 seconds. + +#### Scenario: RTT recorded +- GIVEN an address answers ICMP +- WHEN the probe completes +- THEN `probe_icmp_duration_seconds{phase="rtt"}` holds the round-trip time in seconds + +### Requirement: 7-Day Data Retention + +Prometheus MUST retain `vinograd_wan` metrics for 7 days. + +#### Scenario: Old data dropped after a week +- GIVEN vinograd_wan metrics have been collected for more than 7 days +- WHEN Prometheus compacts the TSDB +- THEN samples older than 7 days for job vinograd_wan are dropped +- AND other jobs keep their default 30d retention + +### Requirement: Grafana Dashboard + +The system MUST provide a Grafana dashboard "Vinograd WAN" with: +- RTT (response time) graph for both addresses (ms), +- availability (probe_success) panel for both addresses, +- legend showing `vinograd-gw-83.239.50.145` / `vinograd-cpe-83.239.50.146`. + +#### Scenario: Dashboard shows data +- GIVEN Grafana has the Vinograd WAN dashboard provisioned +- WHEN a user opens it +- THEN it shows the RTT graph and availability of both channel addresses