Files
vidconf/deploy/monitoring/alerts.yml
Max Ronzhin 77ee26014d feat(monitoring): метрики CPU/RAM/диска хоста и контейнеров
Дашборд «Пайплайны пост-обработки» покрывал только прикладную логику —
нехватка памяти/CPU на сервере была видна только косвенно, по латентности API.

Добавлены node-exporter (метрики хоста) и cAdvisor (метрики по контейнерам,
профиль monitoring) — оба без публикации портов наружу, Prometheus ходит
к ним по внутренней сети compose. Новый дашборд host.json («Хост и
контейнеры») и три алерта (HostMemoryLow/HostDiskLow/HostCpuHigh) с
порогами под сервер 1gb (8 ГБ RAM, 4 CPU, 50 ГБ диска).
2026-07-28 00:21:01 +03:00

118 lines
7.8 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.
# Правила алертинга Prometheus. Подключены через
# `rule_files` в prometheus.yml. Метрики — из `backend/api/metrics.py`
# (см. комментарий в prometheus.yml про контракт имён).
#
# Проверка: алерт на искусственно заваленном пайплайне — остановить `llm`
# при активном `summarize_session` (см. `docs/deploy/monitoring.md`).
groups:
- name: vidconf-pipeline
rules:
# Растёт число сеансов, застрявших в статусе `failed`
# (`conference_sessions.pipeline_status`).
# `delta()` — корректная функция PromQL именно для gauge (не
# `increase()`, которая рассчитана на монотонные counter'ы).
- alert: PipelineFailed
expr: delta(vidconf_pipeline_sessions{status="failed"}[15m]) > 0
for: 5m
labels:
severity: critical
annotations:
summary: "Растёт число упавших сеансов пайплайна пост-обработки"
description: >-
За последние 15 минут число сеансов в статусе failed выросло
на {{ $value }}. Смотреть логи worker/worker-transcriber и
таблицу conference_sessions (pipeline_status).
# Глубина хотя бы одной из очередей Celery устойчиво растёт 15 минут
# подряд — воркеры не успевают за потоком задач (см.
# docs/deploy/scaling.md — вынос очереди в отдельную реплику).
- alert: QueueGrowing
expr: delta(vidconf_celery_queue_depth[15m]) > 0 and vidconf_celery_queue_depth > 10
for: 15m
labels:
severity: warning
annotations:
summary: "Очередь Celery «{{ $labels.queue }}» растёт 15 минут подряд"
description: >-
Текущая глубина очереди {{ $labels.queue }}: {{ $value }} задач,
рост не прекращается 15 минут — см. docs/deploy/scaling.md
(вынос очереди в отдельную реплику/масштабирование).
# LLM-сервер (llama.cpp, job `llm` — см. комментарий в prometheus.yml
# про сетевой алиас `llm`/`llm-gpu`) недоступен. Актуально ТОЛЬКО на
# инсталляциях с включённым профилем `llm`/`llm-gpu` (пресеты 35,
# `install.sh`) — целевой набор профилей по умолчанию (`media,monitoring`,
# см. .env.example) их не включает, поэтому правило закомментировано
# вместе с job `llm` в prometheus.yml (иначе `up{job="llm"}` не находит
# ни одной серии — сам по себе закомментированный job уже не даёт этому
# алерту сработать, но держать активное правило на несуществующую
# метрику вводит в заблуждение). Раскомментируйте оба вместе на
# инсталляциях с профилем `llm`/`llm-gpu`.
# - alert: LlmDown
# expr: up{job="llm"} == 0
# for: 2m
# labels:
# severity: critical
# annotations:
# summary: "LLM-сервер (llama.cpp) недоступен"
# description: >-
# Prometheus не может достучаться до llm:8080 дольше 2 минут —
# суммаризация встанет (задачи будут копиться в очереди summarize,
# см. также алерт QueueGrowing). Проверить
# `docker compose ps llm` / `llm-gpu` и `docker compose logs llm`.
# Железо хоста (job `node` — node-exporter). Пороги подобраны под
# конкретный сервер 1gb: 8 ГБ RAM, 4 CPU, 50 ГБ диска — если сервер
# сменится, пересчитать.
- name: vidconf-host
rules:
# MemAvailable — уже честная оценка Linux с учётом того, что легко
# освобождаемый page cache/buffers не в счёт (в отличие от naive
# used = total - free). 10% от 8 ГБ ≈ 800 МБ — `for: 10m`, чтобы не
# дёргать на кратковременный всплеск (например, разовый всплеск
# transcribe/summarize), но успеть среагировать до OOM killer.
- alert: HostMemoryLow
expr: (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 < 10
for: 10m
labels:
severity: warning
annotations:
summary: "Мало свободной памяти на хосте"
description: >-
Свободно {{ $value | printf "%.1f" }}% RAM дольше 10 минут
(порог 10% ≈ 800 МБ из 8 ГБ). Смотреть, какой контейнер ест
память — дашборд «Хост и контейнеры», топ по памяти (cAdvisor).
# 50 ГБ диска — 10% ≈ 5 ГБ. `for: 15m` (не мгновенно): диск не растёт
# так же резко, как память, ложные срабатывания на всплеск не грозят,
# но и разовая проверка на границе некритична — 15 минут отсекает шум.
- alert: HostDiskLow
expr: (node_filesystem_avail_bytes{mountpoint="/",fstype!="tmpfs"} / node_filesystem_size_bytes{mountpoint="/",fstype!="tmpfs"}) * 100 < 10
for: 15m
labels:
severity: warning
annotations:
summary: "Мало места на диске хоста"
description: >-
Свободно {{ $value | printf "%.1f" }}% диска дольше 15 минут
(порог 10% ≈ 5 ГБ из 50 ГБ). Частые причины на этом проекте —
записи транскрибации (`recordings`), логи docker, образы/слои
после пересборки — проверить `docker system df`.
# 4 CPU. Порог 90% и `for: 15m` — сознательно строже по времени, чем
# у памяти/диска: кратковременные пики от пайплайна пост-обработки
# (транскрибация/суммаризация) — это ожидаемая, не аварийная нагрузка,
# алерт должен ловить именно устойчивую перегрузку, а не обычный всплеск.
- alert: HostCpuHigh
expr: 100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 90
for: 15m
labels:
severity: warning
annotations:
summary: "Устойчиво высокая загрузка CPU хоста"
description: >-
Загрузка CPU {{ $value | printf "%.1f" }}% дольше 15 минут
подряд (порог 90% из 4 ядер). Смотреть топ контейнеров по CPU
(дашборд «Хост и контейнеры», cAdvisor) и латентность API —
возможно, не хватает уровня AI/ресурсов под нагрузку.