feat(backend): метрика vidconf_host_info для плашки характеристик сервера
Info-метрика (значение всегда 1, лейблы cpus/ram_mb/gpu_name/vram_mb) — источник GPU для новой панели «Характеристики сервера» в дашборде «Хост и контейнеры» (живые CPU/RAM/диск там же берутся из node-exporter, GPU node-exporter не знает). Данные — уже читаемые Settings.hw_* из .env, которые install.sh пишет по ADR-004. «—» вместо None/пустой строки — однозначный прочерк на панели вместо пустого текста.
This commit is contained in:
@@ -1,15 +1,17 @@
|
||||
"""Метрики Prometheus: латентность HTTP + gauge'и пайплайна и очередей.
|
||||
"""Метрики Prometheus: латентность HTTP + gauge'и пайплайна, очередей и железа.
|
||||
|
||||
`GET /metrics` — без авторизации (снаружи закрывается на уровне nginx, вне
|
||||
периметра backend, см. `docs/deploy/scaling.md`/monitoring-часть devops):
|
||||
Prometheus-серверы традиционно ходят напрямую в контейнер по внутренней
|
||||
сети, а не через публичный `/api/`-гейтвей.
|
||||
|
||||
Gauge'и `vidconf_pipeline_sessions`/`vidconf_celery_queue_depth` намеренно
|
||||
НЕ обновляются фоновой задачей — значения пересчитываются прямо в обработчике
|
||||
запроса при каждом scrape (см. докстринг `metrics_endpoint`), поэтому их
|
||||
асинхронные источники (БД, Redis) можно опросить обычным `await` вместо
|
||||
реализации синхронного `prometheus_client.registry.Collector`.
|
||||
Gauge'и `vidconf_pipeline_sessions`/`vidconf_celery_queue_depth`/
|
||||
`vidconf_host_info` намеренно НЕ обновляются фоновой задачей — значения
|
||||
пересчитываются прямо в обработчике запроса при каждом scrape (см.
|
||||
докстринг `metrics_endpoint`), поэтому их асинхронные источники (БД,
|
||||
Redis) можно опросить обычным `await` вместо реализации синхронного
|
||||
`prometheus_client.registry.Collector` (у `vidconf_host_info` источник
|
||||
и вовсе синхронный — настройки уже в памяти процесса).
|
||||
"""
|
||||
|
||||
import time
|
||||
@@ -20,6 +22,7 @@ from prometheus_client import CONTENT_TYPE_LATEST, Gauge, Histogram, generate_la
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from starlette.routing import Match
|
||||
|
||||
from core.config import get_settings
|
||||
from core.db import get_session
|
||||
from core.redis import redis_client
|
||||
from models.session import PIPELINE_STATUSES
|
||||
@@ -110,6 +113,42 @@ async def _refresh_celery_queue_depth_gauge() -> None:
|
||||
CELERY_QUEUE_DEPTH.labels(queue=queue).set(depth)
|
||||
|
||||
|
||||
# --- Info-метрика обнаруженного железа (install.sh, ADR-004) ---------------
|
||||
|
||||
HOST_INFO = Gauge(
|
||||
"vidconf_host_info",
|
||||
"Обнаруженное установщиком железо (info-метрика, значение всегда 1, данные в лейблах)",
|
||||
labelnames=("cpus", "ram_mb", "gpu_name", "vram_mb"),
|
||||
)
|
||||
|
||||
|
||||
def _hw_label(value: int | None) -> str:
|
||||
"""`None` (install.sh не запускался либо GPU не обнаружен) → «—», не пустая строка.
|
||||
|
||||
Пустой лейбл Grafana отрисовала бы как пустой текст на панели —
|
||||
прочерк однозначно читается как «не определено».
|
||||
"""
|
||||
return str(value) if value is not None else "—"
|
||||
|
||||
|
||||
def _refresh_host_info_gauge() -> None:
|
||||
"""Пересчитать `vidconf_host_info` по текущим `HW_*` настройкам (`core/config.py`).
|
||||
|
||||
Источник — `install.sh`, который пишет `HW_CPUS`/`HW_RAM_MB`/
|
||||
`HW_GPU_NAME`/`HW_VRAM_MB` в `.env` при установке (ADR-004). Живые
|
||||
CPU/RAM/диск хоста в дашборде «Хост и контейнеры» берутся из
|
||||
node-exporter напрямую — здесь только то, чего node-exporter не
|
||||
знает (GPU), плюс дублирование CPU/RAM install.sh для сверки.
|
||||
"""
|
||||
settings = get_settings()
|
||||
HOST_INFO.labels(
|
||||
cpus=_hw_label(settings.hw_cpus),
|
||||
ram_mb=_hw_label(settings.hw_ram_mb),
|
||||
gpu_name=settings.hw_gpu_name or "—",
|
||||
vram_mb=_hw_label(settings.hw_vram_mb),
|
||||
).set(1)
|
||||
|
||||
|
||||
@router.get("/metrics")
|
||||
async def metrics_endpoint(session: AsyncSession = Depends(get_session)) -> Response:
|
||||
"""Отдать метрики Prometheus в формате text exposition.
|
||||
@@ -122,4 +161,5 @@ async def metrics_endpoint(session: AsyncSession = Depends(get_session)) -> Resp
|
||||
"""
|
||||
await _refresh_pipeline_sessions_gauge(session)
|
||||
await _refresh_celery_queue_depth_gauge()
|
||||
_refresh_host_info_gauge()
|
||||
return Response(content=generate_latest(), media_type=CONTENT_TYPE_LATEST)
|
||||
|
||||
Reference in New Issue
Block a user