Тревоги уровня приложения, cAdvisor и пропавшие фоновые контейнеры; critical переживает подавление #3477

Merged
lekss361 merged 1 commit from feat/3471-app-alerts-coverage into main 2026-09-12 11:05:39 +00:00
Owner

Пункты из #3471, раздел «Маршрутизация алертов» и «Слепые зоны мониторинга». Четыре класса отказов, которые до сих пор никто не ловил.

Чего не было

В infra.yml было 16 правил, и все они про хост, контейнеры и Postgres. Доля пятисоток и латентность продукта не покрыты ничем: ошибка видна только постфактум в GlitchTip, порога срабатывания нет, дежурного она не поднимает.

Что добавлено

  • AppHighErrorRate — доля 5xx выше 5 процентов при осмысленном трафике, severity=critical, host=apps.
  • AppHighLatencyP95 — 95-й перцентиль выше 5 секунд, те же лейблы.

Пара лейблов здесь не украшение: в alertmanager.yml.tmpl под неё уже заведён маршрут telegram-clients, который зовёт дежурного поимённо и напоминает каждые 30 минут. С другими лейблами алерт уехал бы в инфраструктурную тему и утонул в шуме.

  • CadvisorDownup{job="cadvisor"} == 0 or absent(...). Без него смерть cAdvisor молча отключала бы ContainerRestartLoop и ContainerNearMemoryLimit.
  • TradeInBackgroundContainerMissing — два отдельных absent(container_last_seen{...}) на tradein-tgbot и tradein-scraper. Именно два, а не один с регуляркой: одна проверка молчала бы, пока жив хоть один из двух контейнеров.

Что починено попутно

  • Подавление больше не глушит critical. target_matchers у правила по HostAgentDown сужен до severity="warning". Раньше умерший node-exporter уносил в тишину и алерты cAdvisor, и PostgresLongTransactionCritical того же хоста.
  • Серия up перестала резаться в Alloy. В alloy-infra.alloy keep-фильтр пропускал только container_*, заодно выбрасывая up и scrape_samples_scraped. Правка в обоих relabel-правилах: второе резало служебные ряды по паре имён, потому что у них нет лейбла name. Без этого CadvisorDown не на чем было бы считать.

Проверка

Имена метрик подтверждены на живом Prometheus, а не по памяти: http_requests_total и http_request_duration_seconds_bucket существуют с лейблами app=sitefinder|mera, job=app; container_last_seen{name="tradein-tgbot"} тоже на месте. promtool check rules на итоговом файле проходит, 20 правил.

Честное ограничение

TradeInBackgroundContainerMissing ловит исчезновение контейнера, но не живой процесс с застрявшим циклом: container_last_seen обновляется, пока Docker видит контейнер запущенным. Подходящей метрики для второго случая в стеке сейчас нет, нужен heartbeat из самого цикла бота и скрапера. Это отдельная задача, в комментарии к правилу ограничение записано прямым текстом.

Пункты из #3471, раздел «Маршрутизация алертов» и «Слепые зоны мониторинга». Четыре класса отказов, которые до сих пор никто не ловил. ## Чего не было В `infra.yml` было 16 правил, и все они про хост, контейнеры и Postgres. Доля пятисоток и латентность продукта не покрыты ничем: ошибка видна только постфактум в GlitchTip, порога срабатывания нет, дежурного она не поднимает. ## Что добавлено - **`AppHighErrorRate`** — доля 5xx выше 5 процентов при осмысленном трафике, `severity=critical`, `host=apps`. - **`AppHighLatencyP95`** — 95-й перцентиль выше 5 секунд, те же лейблы. Пара лейблов здесь не украшение: в `alertmanager.yml.tmpl` под неё уже заведён маршрут `telegram-clients`, который зовёт дежурного поимённо и напоминает каждые 30 минут. С другими лейблами алерт уехал бы в инфраструктурную тему и утонул в шуме. - **`CadvisorDown`** — `up{job="cadvisor"} == 0 or absent(...)`. Без него смерть cAdvisor молча отключала бы `ContainerRestartLoop` и `ContainerNearMemoryLimit`. - **`TradeInBackgroundContainerMissing`** — два отдельных `absent(container_last_seen{...})` на `tradein-tgbot` и `tradein-scraper`. Именно два, а не один с регуляркой: одна проверка молчала бы, пока жив хоть один из двух контейнеров. ## Что починено попутно - **Подавление больше не глушит critical.** `target_matchers` у правила по `HostAgentDown` сужен до `severity="warning"`. Раньше умерший node-exporter уносил в тишину и алерты cAdvisor, и `PostgresLongTransactionCritical` того же хоста. - **Серия `up` перестала резаться в Alloy.** В `alloy-infra.alloy` keep-фильтр пропускал только `container_*`, заодно выбрасывая `up` и `scrape_samples_scraped`. Правка в обоих relabel-правилах: второе резало служебные ряды по паре имён, потому что у них нет лейбла `name`. Без этого `CadvisorDown` не на чем было бы считать. ## Проверка Имена метрик подтверждены на живом Prometheus, а не по памяти: `http_requests_total` и `http_request_duration_seconds_bucket` существуют с лейблами `app=sitefinder|mera`, `job=app`; `container_last_seen{name="tradein-tgbot"}` тоже на месте. `promtool check rules` на итоговом файле проходит, 20 правил. ## Честное ограничение `TradeInBackgroundContainerMissing` ловит исчезновение контейнера, но не живой процесс с застрявшим циклом: `container_last_seen` обновляется, пока Docker видит контейнер запущенным. Подходящей метрики для второго случая в стеке сейчас нет, нужен heartbeat из самого цикла бота и скрапера. Это отдельная задача, в комментарии к правилу ограничение записано прямым текстом.
lekss361 added 1 commit 2026-09-12 10:59:44 +00:00
feat(ops): алерты уровня приложения и три слепые зоны мониторинга
All checks were successful
CI Trade-In / changes (pull_request) Successful in 11s
CI / changes (pull_request) Successful in 14s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
655652ae1c
- AppHighErrorRate / AppHighLatencyP95 (job="app", severity=critical,
  host="apps") — доля 5xx и p95 задержки по http_requests_total /
  http_request_duration_seconds_bucket теперь ловятся Prometheus'ом, а не
  только постфактум в GlitchTip. Пара critical+apps обязательна для
  маршрута telegram-clients в alertmanager.yml.tmpl.
- Inhibit по HostAgentDown больше не гасит critical того же хоста —
  target_matchers сужен до severity="warning" (падение node-exporter
  раньше молча забирало с собой PostgresLongTransactionCritical и
  critical-алерты cAdvisor).
- cAdvisor: keep-фильтр в alloy-infra.alloy резал у него `up` наравне с
  container_*-мусором — job "cadvisor" не публиковал свою же серию `up`.
  Пропущены up/scrape_samples_scraped, добавлен CadvisorDown.
- TradeInBackgroundContainerMissing по absent(container_last_seen) на
  tradein-tgbot/tradein-scraper — эти контейнеры не HTTP-сервисы и в
  up{} не участвуют вовсе; крэш без рестарта раньше не алертился.

Не закрыто: живой, но зависший процесс tgbot/scraper (container_last_seen
не про внутренний прогресс, а про то, что Docker видит контейнер running).

Refs #3471
lekss361 merged commit 5d4d17a5e1 into main 2026-09-12 11:05:39 +00:00
lekss361 deleted branch feat/3471-app-alerts-coverage 2026-09-12 11:05:40 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#3477
No description provided.