fix(metrics): тревога, когда бэкенд Меры лёг, а лэндинг ещё открывается (#2214)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 21s
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 / changes (pull_request) Successful in 24s
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Successful in 3m23s
CI / backend-tests (pull_request) Successful in 8m17s

Мёртвый или зависший tradein-backend не давал ни одного сигнала вне Poincare.
GlitchTip-монитор 6 смотрит на лэндинг meraocenka.ru, а его отдаёт фронт из
пререндер-кэша (x-nextjs-cache: HIT) — при мёртвом бэкенде там 200. Монитор 2
(gendsgn.ru/health) проверяет бэкенд Птицы. AppHighErrorRate и
AppHighLatencyP95 считают метрики самого бэкенда и при его смерти молчат.

Новое правило MeraBackendDown: up{job="app",app="mera"} == 0 или серия
пропала, 5 минут, severity critical + host apps — маршрут telegram-clients,
тема 158. Считается и доставляется на Beget. Порог 5 минут откалиброван по
истории up за 26.08–17.09: 140 провалов, самый длинный — 4 нулевые точки
(~2 минуты, окна деплоя).

Юнит-тесты promtool: мёртвый бэкенд — тревога; окно деплоя и упавшая Птица —
тишина; цель пропала из скрейпа — тревога.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
bot-backend 2026-09-17 12:38:14 +05:00
parent 34642e1dd5
commit 26a7f1c163
2 changed files with 89 additions and 0 deletions

View file

@ -215,6 +215,40 @@ groups:
- name: app - name: app
interval: 60s interval: 60s
rules: rules:
# Бэкенд «Меры» лежит или завис (#2214). До этого правила такой отказ не
# давал ни одного сигнала вне Poincare. GlitchTip-монитор 6 смотрит на
# лэндинг meraocenka.ru, а его отдаёт tradein-frontend из пререндер-кэша
# (x-nextjs-cache: HIT) — при мёртвом бэкенде там по-прежнему 200.
# Монитор 2 (gendsgn.ru/health) — это бэкенд «Птицы». Два правила ниже
# считают метрики, которые отдаёт сам бэкенд: мёртвый не отдаёт, и они
# молчат по построению.
#
# Скрейп идёт с Poincare (Alloy), но решение и доставка — здесь, на Beget.
# Зависший event loop даёт таймаут скрейпа (20s), удалённый контейнер —
# ошибку DNS; в обоих случаях up=0. Смерть всего хоста ловят
# HostAgentDown/RemoteWriteStalled; `absent()` — на случай, когда цель
# тихо пропала из alloy-apps.alloy.
#
# for: 5m — по истории up{app="mera"} 26.0817.09 (61 857 точек): 140
# провалов, все короткие (окна деплоя), самый длинный — 4 нулевые точки
# подряд, ~2 минуты до восстановления. 5 минут — запас в 2.5 раза.
#
# Чего правило НЕ видит: публичный путь до бэкенда (DNS, TLS, Caddy).
# Для лэндинга его проверяет монитор 6; монитора на публичную ручку
# бэкенда (meraocenka.ru/trade-in/api/public/mera/stats) пока нет — он
# заводится в UI GlitchTip, а не кодом.
- alert: MeraBackendDown
expr: |
up{job="app", app="mera"} == 0
or absent(up{job="app", app="mera"})
for: 5m
labels:
severity: critical
host: apps
annotations:
summary: "Бэкенд «Меры» не отвечает"
description: "Агент на Poincare 5 минут не может снять /metrics с tradein-backend (up=0), либо цель пропала из скрейпа. Проверь `docker ps` и /health изнутри сети. Лэндинг meraocenka.ru может открываться из кэша и при мёртвом бэкенде — это не признак жизни."
# Гейт по RPS внутри знаменателя — тот же приём, что у # Гейт по RPS внутри знаменателя — тот же приём, что у
# PostgresLowHotUpdateRatio: делит только там, где трафик уже есть, # PostgresLowHotUpdateRatio: делит только там, где трафик уже есть,
# иначе один упавший запрос при нулевой нагрузке даёт 100% и будит # иначе один упавший запрос при нулевой нагрузке даёт 100% и будит

View file

@ -115,3 +115,58 @@ tests:
exp_annotations: exp_annotations:
summary: "Ни одного живого воркера Celery" summary: "Ни одного живого воркера Celery"
description: "celery-exporter работает, но не видит ни одного heartbeat от воркера Site Finder. Все periodic-таски (парсинг, аналитика, синк слоёв) встали." description: "celery-exporter работает, но не видит ни одного heartbeat от воркера Site Finder. Все periodic-таски (парсинг, аналитика, синк слоёв) встали."
# #2214: tradein-backend умер, хост и агент живы — агент шлёт up=0.
# До MeraBackendDown этот случай не давал ни одного сигнала вне Poincare.
- interval: 30s
input_series:
- series: 'up{job="app",app="mera",instance="tradein-backend:8000",host="apps"}'
values: '1x9 0x40'
alert_rule_test:
- eval_time: 15m
alertname: MeraBackendDown
exp_alerts:
- exp_labels:
severity: critical
host: apps
job: app
app: mera
instance: tradein-backend:8000
exp_annotations:
summary: "Бэкенд «Меры» не отвечает"
description: "Агент на Poincare 5 минут не может снять /metrics с tradein-backend (up=0), либо цель пропала из скрейпа. Проверь `docker ps` и /health изнутри сети. Лэндинг meraocenka.ru может открываться из кэша и при мёртвом бэкенде — это не признак жизни."
# Окно деплоя: самый длинный провал за 26.0817.09 — 4 нулевые точки подряд
# (~2 минуты). Тревоги быть не должно. Заодно упавший бэкенд «Птицы» не должен
# поднимать тревогу про «Меру».
- interval: 30s
input_series:
- series: 'up{job="app",app="mera",instance="tradein-backend:8000",host="apps"}'
values: '1x19 0 0 0 0 1x40'
- series: 'up{job="app",app="sitefinder",instance="gendesign-backend-1:8000",host="apps"}'
values: '0x64'
alert_rule_test:
- eval_time: 11m
alertname: MeraBackendDown
exp_alerts: []
- eval_time: 30m
alertname: MeraBackendDown
exp_alerts: []
# Цель пропала из скрейпа (агент жив, «Птица» снимается), серии «Меры» нет.
- interval: 30s
input_series:
- series: 'up{job="app",app="sitefinder",instance="gendesign-backend-1:8000",host="apps"}'
values: '1x40'
alert_rule_test:
- eval_time: 10m
alertname: MeraBackendDown
exp_alerts:
- exp_labels:
severity: critical
host: apps
job: app
app: mera
exp_annotations:
summary: "Бэкенд «Меры» не отвечает"
description: "Агент на Poincare 5 минут не может снять /metrics с tradein-backend (up=0), либо цель пропала из скрейпа. Проверь `docker ps` и /health изнутри сети. Лэндинг meraocenka.ru может открываться из кэша и при мёртвом бэкенде — это не признак жизни."