Первоначальная версия VidConf
This commit is contained in:
59
deploy/monitoring/alerts.yml
Normal file
59
deploy/monitoring/alerts.yml
Normal file
@@ -0,0 +1,59 @@
|
||||
# Правила алертинга 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` (пресеты 3–5,
|
||||
# `install.sh`) — на пресетах 1/2 (без AI) таргет `llm:8080` в принципе
|
||||
# не резолвится, и этот алерт будет постоянно активен, если профиль
|
||||
# `monitoring` включён без AI-профиля; для таких инсталляций правило
|
||||
# можно отключить (закомментировать) в локальной копии alerts.yml.
|
||||
- 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`.
|
||||
150
deploy/monitoring/grafana/dashboards/pipelines.json
Normal file
150
deploy/monitoring/grafana/dashboards/pipelines.json
Normal file
@@ -0,0 +1,150 @@
|
||||
{
|
||||
"title": "Пайплайны пост-обработки",
|
||||
"uid": "vidconf-pipelines",
|
||||
"editable": false,
|
||||
"timezone": "browser",
|
||||
"schemaVersion": 39,
|
||||
"version": 1,
|
||||
"time": { "from": "now-6h", "to": "now" },
|
||||
"refresh": "30s",
|
||||
"tags": ["vidconf", "pipeline"],
|
||||
"panels": [
|
||||
{
|
||||
"id": 1,
|
||||
"title": "Сеансы по статусу пайплайна",
|
||||
"description": "conference_sessions.pipeline_status (recording→transcribing→summarizing→notified|failed), метрика vidconf_pipeline_sessions.",
|
||||
"type": "timeseries",
|
||||
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 0 },
|
||||
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
||||
"fieldConfig": {
|
||||
"defaults": { "custom": { "drawStyle": "line", "fillOpacity": 10, "stacking": { "mode": "normal" } } },
|
||||
"overrides": []
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
||||
"expr": "vidconf_pipeline_sessions",
|
||||
"legendFormat": "{{status}}",
|
||||
"refId": "A"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"title": "Глубина очередей Celery",
|
||||
"description": "vidconf_celery_queue_depth{queue=...} — transcription/summarize/notify/celery (redis LLEN). Порог алерта QueueGrowing см. deploy/monitoring/alerts.yml.",
|
||||
"type": "timeseries",
|
||||
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 0 },
|
||||
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
||||
"fieldConfig": {
|
||||
"defaults": { "custom": { "drawStyle": "line", "fillOpacity": 10 } },
|
||||
"overrides": []
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
||||
"expr": "vidconf_celery_queue_depth",
|
||||
"legendFormat": "{{queue}}",
|
||||
"refId": "A"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"title": "Латентность API (p50/p95/p99 по маршрутам)",
|
||||
"description": "vidconf_http_request_duration_seconds — histogram латентности HTTP по шаблону маршрута.",
|
||||
"type": "timeseries",
|
||||
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 8 },
|
||||
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
||||
"fieldConfig": {
|
||||
"defaults": { "unit": "s", "custom": { "drawStyle": "line", "fillOpacity": 5 } },
|
||||
"overrides": []
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
||||
"expr": "histogram_quantile(0.50, sum(rate(vidconf_http_request_duration_seconds_bucket[5m])) by (le, path))",
|
||||
"legendFormat": "p50 {{path}}",
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
||||
"expr": "histogram_quantile(0.95, sum(rate(vidconf_http_request_duration_seconds_bucket[5m])) by (le, path))",
|
||||
"legendFormat": "p95 {{path}}",
|
||||
"refId": "B"
|
||||
},
|
||||
{
|
||||
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
||||
"expr": "histogram_quantile(0.99, sum(rate(vidconf_http_request_duration_seconds_bucket[5m])) by (le, path))",
|
||||
"legendFormat": "p99 {{path}}",
|
||||
"refId": "C"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"title": "Длительность шагов пайплайна (p95)",
|
||||
"description": "Ожидает метрику vidconf_pipeline_step_duration_seconds (histogram, label step) — пока не реализована (backend/api/metrics.py содержит только латентность HTTP и gauge'и статусов/очередей). Панель — заготовка под будущую инструментацию шагов transcribing/summarizing/notified; до её появления показывает «No data».",
|
||||
"type": "timeseries",
|
||||
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 8 },
|
||||
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
||||
"fieldConfig": {
|
||||
"defaults": { "unit": "s", "custom": { "drawStyle": "line", "fillOpacity": 5 } },
|
||||
"overrides": []
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
||||
"expr": "histogram_quantile(0.95, sum(rate(vidconf_pipeline_step_duration_seconds_bucket[15m])) by (le, step))",
|
||||
"legendFormat": "p95 {{step}}",
|
||||
"refId": "A"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"title": "LLM-сервер доступен (job=llm)",
|
||||
"description": "up{job=\"llm\"} — 1, если Prometheus успешно скрейпит llama.cpp (алерт LlmDown, deploy/monitoring/alerts.yml). Актуально только на инсталляциях с профилем llm/llm-gpu (пресеты 3–5).",
|
||||
"type": "stat",
|
||||
"gridPos": { "h": 4, "w": 6, "x": 0, "y": 16 },
|
||||
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"mappings": [
|
||||
{ "type": "value", "options": { "0": { "text": "DOWN", "color": "red" }, "1": { "text": "UP", "color": "green" } } }
|
||||
],
|
||||
"thresholds": { "mode": "absolute", "steps": [{ "color": "red", "value": null }, { "color": "green", "value": 1 }] }
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
||||
"expr": "up{job=\"llm\"}",
|
||||
"refId": "A"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"title": "Сеансы failed (текущее число)",
|
||||
"description": "vidconf_pipeline_sessions{status=\"failed\"} — алерт PipelineFailed срабатывает на росте за 15 минут, здесь — снимок текущего значения.",
|
||||
"type": "stat",
|
||||
"gridPos": { "h": 4, "w": 6, "x": 6, "y": 16 },
|
||||
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }, { "color": "red", "value": 1 }] }
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
||||
"expr": "vidconf_pipeline_sessions{status=\"failed\"}",
|
||||
"refId": "A"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
# Провижининг дашбордов Grafana (devops) — файлы из
|
||||
# deploy/monitoring/grafana/dashboards/ (том :ro в контейнере grafana).
|
||||
apiVersion: 1
|
||||
|
||||
providers:
|
||||
- name: vidconf
|
||||
orgId: 1
|
||||
folder: VidConf
|
||||
type: file
|
||||
disableDeletion: false
|
||||
allowUiUpdates: false
|
||||
updateIntervalSeconds: 30
|
||||
options:
|
||||
path: /var/lib/grafana/dashboards
|
||||
foldersFromFilesStructure: false
|
||||
@@ -0,0 +1,12 @@
|
||||
# Провижининг источника данных Grafana (devops) — Prometheus
|
||||
# внутри той же docker-сети compose (профиль `monitoring`).
|
||||
apiVersion: 1
|
||||
|
||||
datasources:
|
||||
- name: Prometheus
|
||||
uid: prometheus
|
||||
type: prometheus
|
||||
access: proxy
|
||||
url: http://prometheus:9090
|
||||
isDefault: true
|
||||
editable: false
|
||||
45
deploy/monitoring/prometheus.yml
Normal file
45
deploy/monitoring/prometheus.yml
Normal file
@@ -0,0 +1,45 @@
|
||||
# Конфигурация Prometheus (devops) — сбор метрик backend,
|
||||
# PostgreSQL, Redis и локального LLM-сервера. Поднимается compose-профилем
|
||||
# `monitoring` (deploy/docker-compose.yml, сервис `prometheus`).
|
||||
#
|
||||
# Имена метрик backend (`vidconf_http_request_duration_seconds`,
|
||||
# `vidconf_pipeline_sessions`, `vidconf_celery_queue_depth`) — КОНТРАКТ с
|
||||
# `backend/api/metrics.py`; правила в `alerts.yml` используют их буквально —
|
||||
# при переименовании метрик в backend поправить оба файла одновременно.
|
||||
global:
|
||||
scrape_interval: 15s
|
||||
evaluation_interval: 15s
|
||||
|
||||
rule_files:
|
||||
- /etc/prometheus/alerts.yml
|
||||
|
||||
scrape_configs:
|
||||
# Backend FastAPI: латентность HTTP по маршрутам + gauge'и пайплайна и
|
||||
# очередей Celery (см. GET /metrics, `backend/api/metrics.py`).
|
||||
- job_name: backend
|
||||
metrics_path: /metrics
|
||||
static_configs:
|
||||
- targets: ["backend:8000"]
|
||||
|
||||
# PostgreSQL (профиль monitoring — сервис postgres-exporter).
|
||||
- job_name: postgres
|
||||
static_configs:
|
||||
- targets: ["postgres-exporter:9187"]
|
||||
|
||||
# Redis (профиль monitoring — сервис redis-exporter): также источник для
|
||||
# алерта LlmDown нет, но по нему видно состояние брокера Celery отдельно
|
||||
# от глубины очередей (та берётся из backend, не отсюда).
|
||||
- job_name: redis
|
||||
static_configs:
|
||||
- targets: ["redis-exporter:9121"]
|
||||
|
||||
# Локальный LLM-сервер (llama.cpp, LLAMA_ARG_ENDPOINT_METRICS=1). Адрес
|
||||
# `llm:8080` разрешается ОДНИМ из двух compose-сервисов в зависимости от
|
||||
# выбранного при установке пресета — `llm` (CPU, профиль `llm`, уровни
|
||||
# min/medium) или `llm-gpu` (GPU, профиль `llm-gpu`, уровень max, у
|
||||
# которого в сети compose есть сетевой алиас `llm`, см. его определение в
|
||||
# deploy/docker-compose.yml) — эти профили взаимоисключающи, поэтому один
|
||||
# job без дублирования и без вечно недоступного второго таргета.
|
||||
- job_name: llm
|
||||
static_configs:
|
||||
- targets: ["llm:8080"]
|
||||
Reference in New Issue
Block a user