food-market/deploy/prometheus/alerts.yml
nns cf760fab10
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
feat(s26): flaky-test detection + observability dashboards (8/8 ✓ 10/10 cert)
После 24 спринтов regress-suite разросся; нестабильность блокирует
доверие. Этот спринт: ловит flaky тесты, добавляет observability
(Grafana + Prometheus alerts + RUNBOOK), сертифицирует 10× cert-прогон.

1. tests/regression/find-flaky.sh — 10× прогон + JSON-агрегатор →
   docs/flaky-tests.md (per-test pass/fail sequence + reproduce).
2. OrgFactory.signupWithRetry теперь honors Retry-After header
   (api-client.ts:ApiError.retryAfterSec). Stage rate-limit поднят:
   RATE_SIGNUP_HOUR=5000, RATE_PER_IP_MIN=5000 (~/food-market-stage/deploy/.env).
3. fullyParallel=true + workers=4 = тесты идут в недетерминированном
   порядке; isolation работает (OrgFactory per-test).
4. workers=4 даёт **2.4× ускорение** (66.6s → 27.7s). Worker-scoped
   фикстура lib/worker-org.ts добавлена как opt-in.
5. deploy/grafana/dashboards/quality-watchdog.json (10 панелей:
   smoke success ratio 7d, incidents, multi-tenant violations,
   current emoji, p95 by endpoint, step failures, RPS, DB p95,
   docs posted, disk free) + dashboards/README.md.
   quality-watchdog.sh пишет Prometheus textfile экспорт в
   ~/.fm-watchdog/textfile/quality_watchdog.prom для node_exporter.
6. deploy/prometheus/alerts.yml — 10 правил, 4 группы (uptime,
   errors, database, quality-watchdog). MultiTenantViolation = P0.
   deploy/prometheus/prometheus.yml — reference config.
7. docs/RUNBOOK.md +178 строк: action per alert (api-down,
   rps-drop, http-errors-spike/growing, doc-posting-errors,
   db-p95-high, disk-free-low, watchdog-red, multi-tenant-violation,
   watchdog-incident). Junior-friendly с конкретными командами.

**Cert-прогон (10× workers=4):** 420/420 passed, 0 flaky, avg 30.1s/run,
total 300.6s (< 5min budget).

Изменения вне репо:
- ~/food-market-stage/deploy/.env — RATE_* limits bumped.
- ~/quality-watchdog.sh — добавлен .prom textfile экспорт.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-08 14:44:19 +05:00

176 lines
8.2 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Sprint 26: Prometheus alert rules для food-market.
#
# Загружается через prometheus.yml:
# rule_files:
# - alerts.yml
#
# Каждое правило → Alertmanager → Telegram/email.
# Все runbook-ссылки указывают на docs/RUNBOOK.md в репо.
#
# Группировка: 4 группы по доменам — uptime / errors / database / quality-watchdog.
groups:
- name: food-market.uptime
interval: 30s
rules:
- alert: ApiDown
expr: up{job="food-market-api"} == 0
for: 1m
labels:
severity: critical
runbook: api-down
annotations:
summary: "food-market API не отвечает на /metrics уже 1 минуту"
description: |
Prometheus не может scrap'нуть {{ $labels.instance }} > 1 минуты.
Это означает либо процесс упал, либо порт недоступен.
runbook_url: "https://forgejo.local/nns/food-market/src/branch/main/docs/RUNBOOK.md#api-down"
- alert: RpsDropped50Percent
# RPS за 5 минут упал относительно среднего за час назад (5-минутка часовой давности).
# Защита от ложных в пиках/спадах: только когда фактическая загрузка была заметной (>0.5 rps).
expr: |
sum(rate(http_requests_received_total[5m]))
/ clamp_min(sum(rate(http_requests_received_total[5m] offset 1h)), 0.001)
< 0.5
and
sum(rate(http_requests_received_total[5m] offset 1h)) > 0.5
for: 10m
labels:
severity: warning
runbook: rps-drop
annotations:
summary: "RPS упал >50% относительно того же окна час назад"
description: |
Сейчас RPS = {{ $value | humanize }}, что меньше половины часовой давности.
Возможно: упал процесс, нет трафика от клиентов, потерян DNS.
runbook_url: "https://forgejo.local/nns/food-market/src/branch/main/docs/RUNBOOK.md#rps-drop"
- name: food-market.errors
interval: 30s
rules:
- alert: HttpErrorsSpike
# Доля 5xx-ответов > 10% от общего трафика за 5 минут.
# 10% — порог, выше которого пользователи реально замечают.
expr: |
(sum(rate(http_requests_received_total{code=~"5.."}[5m]))
/ clamp_min(sum(rate(http_requests_received_total[5m])), 0.001))
> 0.10
for: 5m
labels:
severity: critical
runbook: http-errors-spike
annotations:
summary: "Доля HTTP 5xx > 10% уже 5 минут"
description: |
Сейчас {{ $value | humanizePercentage }} от запросов возвращают 5xx.
Скорее всего сломан какой-то контроллер или зависимость.
runbook_url: "https://forgejo.local/nns/food-market/src/branch/main/docs/RUNBOOK.md#http-errors-spike"
- alert: HttpErrorRateGrowing
# Темп роста 5xx-ошибок > 10%/min.
expr: |
deriv(sum(rate(http_requests_received_total{code=~"5.."}[5m]))[5m:1m])
> 0.10 / 60
for: 10m
labels:
severity: warning
runbook: http-errors-growing
annotations:
summary: "Темп роста 5xx-ошибок > 10%/min на протяжении 10 минут"
description: |
Производная rate(5xx) положительная > 10%/min. Похоже на постепенную
деградацию (не explosion). Проверь логи: что начало падать.
runbook_url: "https://forgejo.local/nns/food-market/src/branch/main/docs/RUNBOOK.md#http-errors-growing"
- alert: DocumentPostingErrors
expr: |
sum(rate(food_market_documents_error_total[5m])) by (type)
> 0.05
for: 5m
labels:
severity: warning
runbook: doc-posting-errors
annotations:
summary: "Документы ({{ $labels.type }}) валятся чаще 1 раза в 20 секунд"
description: |
Тип={{ $labels.type }} даёт {{ $value }} ошибок/сек. Воркфлоу проведения
ломается — посмотри logs или Hangfire-failed-jobs.
runbook_url: "https://forgejo.local/nns/food-market/src/branch/main/docs/RUNBOOK.md#doc-posting-errors"
- name: food-market.database
interval: 30s
rules:
- alert: DbQueryP95High
# p95 DB-запросов > 500ms на протяжении 10 минут.
expr: |
histogram_quantile(0.95,
sum(rate(food_market_db_query_duration_seconds_bucket[5m])) by (le))
> 0.5
for: 10m
labels:
severity: warning
runbook: db-p95-high
annotations:
summary: "DB query p95 > 500ms 10 минут подряд"
description: |
p95 = {{ $value | humanizeDuration }}. Возможно: PG медленный, нет индекса,
ANALYZE устарел, или массовый insert. См. runbook.
runbook_url: "https://forgejo.local/nns/food-market/src/branch/main/docs/RUNBOOK.md#db-p95-high"
- alert: DiskFreeLow
expr: food_market_disk_free_bytes < 5 * 1024 * 1024 * 1024
for: 5m
labels:
severity: critical
runbook: disk-free-low
annotations:
summary: "Свободно < 5 ГБ на {{ $labels.mount }}"
description: |
Свободно: {{ $value | humanize1024 }}B. При достижении 0 БД встанет.
Очисти логи / запусти VACUUM FULL / расширь том.
runbook_url: "https://forgejo.local/nns/food-market/src/branch/main/docs/RUNBOOK.md#disk-free-low"
- name: food-market.quality-watchdog
interval: 1m
rules:
- alert: WatchdogLastRunRed
expr: quality_watchdog_last_run_status == 0
for: 5m
labels:
severity: warning
runbook: watchdog-red
annotations:
summary: "quality-watchdog последний прогон красный (>5 мин)"
description: |
Хотя бы один из 8 шагов упал. Посмотри docs/quality-status.md
или ~/.fm-watchdog/quality.log.
runbook_url: "https://forgejo.local/nns/food-market/src/branch/main/docs/RUNBOOK.md#watchdog-red"
- alert: MultiTenantViolation
# Multi-tenant leak — самый дорогой баг, alert немедленный.
expr: increase(quality_watchdog_step_failure_total{step="multi_tenant"}[1h]) > 0
for: 1m
labels:
severity: critical
runbook: multi-tenant-violation
annotations:
summary: "🚨 Multi-tenant LEAK обнаружен watchdog'ом"
description: |
Шаг multi_tenant failed в последнем прогоне. Org B видит данные A.
ЭТО P0. Немедленно разверни stage в read-only mode и проверь tenant-filter.
runbook_url: "https://forgejo.local/nns/food-market/src/branch/main/docs/RUNBOOK.md#multi-tenant-violation"
- alert: WatchdogIncidentCreated
expr: increase(quality_watchdog_incidents_total[1h]) > 0
for: 1m
labels:
severity: warning
runbook: watchdog-incident
annotations:
summary: "Watchdog создал incident — 2+ подряд красных прогона"
description: |
Один и тот же шаг упал 2 раза подряд. Server-Claude получит
incident-файл в очередь. Проверь ~/.fm-watchdog/incident-*.txt.
runbook_url: "https://forgejo.local/nns/food-market/src/branch/main/docs/RUNBOOK.md#watchdog-incident"