SIRINVIDEO CCTV Документация администратора и пользователя На сайт 2026.08

Мониторинг и метрики

Что смотреть ежедневно, какие показатели важны и как подключить внешний мониторинг.

Наблюдать за системой можно с трёх сторон: админка (быстрый ежедневный обход), JSON API (для внешней системы мониторинга) и метрики ноды в формате Prometheus (для сбора временных рядов и оповещений).

Где какие метрики

Метрики в формате Prometheus отдаёт стриминговая нода — эндпоинт /metrics на её HTTP-порту. Контрол-плейн (Plane) такого эндпоинта не имеет: его показатели доступны только через авторизованный JSON API и админку. Не ищите /metrics на Plane — его там нет.

Ежедневный обход#

Пять проверок, занимают пару минут. В админке всё это — раздел Мониторинг и раздел Ноды.

Что проверить Где смотреть Норма
Доступность нод Мониторинг → Состояние Все ноды доступны, «Требуют внимания» — ноль
Камеры в эфире Мониторинг → Состояние Число совпадает с числом включённых камер
Лицензии Ноды → карточка → Лицензия Нет нод без лицензии и в состоянии grace
Заполнение дисков Ноды → карточка → Хранилища Заполнение стабильно у порога вытеснения, растёт не скачками
Ошибки в журналах Мониторинг → Логи Plane, Ноды → карточка → Логи Нет повторяющихся ошибок

То же самое одной командой, если удобнее в терминале:

BASE=https://cctv.example.com
TOKEN=$(curl -sS -X POST "$BASE/api/v1/auth/login" -H 'Content-Type: application/json' \
  -d '{"login":"admin","password":"ВАШ-ПАРОЛЬ"}' \
  | python3 -c 'import sys,json;print(json.load(sys.stdin)["token"])')

curl -sS "$BASE/api/v1/monitor/fleet/summary" -H "Authorization: Bearer $TOKEN" \
  | python3 -m json.tool
{
  "seq": 1841,
  "sampled_at": "2026-08-18T09:14:22Z",
  "nodes_total": 3, "nodes_reachable": 3, "stream_samples_stale": 0,
  "streams_total": 412, "streams_live": 410, "streams_degraded": 2, "streams_failing": 0,
  "cameras_total": 206, "cameras_live": 205, "cameras_unavailable": 1,
  "nodes_unlicensed": 0, "nodes_grace": 0
}

Это самая полезная одиночная проверка: одним запросом видно и доступность нод, и состояние камер, и лицензии.

Показатели ноды в админке#

Ноды → нода → Обзор показывает срез телеметрии. Значения означают следующее.

Показатель Что это На что смотреть
CPU процесса Сколько ядер занимает сам сервис ноды Сравнивайте с числом рабочих ядер: 8 из 16 — половина запаса израсходована
CPU хоста Загрузка всего сервера, включая посторонние процессы Если хоста загружено много, а процесса — мало, конкурент за ресурсы вне системы
RSS процесса Занятая процессом оперативная память Должна выходить на плато и держаться; постоянный рост — повод завести обращение
Память хоста Свободная память сервера Меньше 10 % свободной — риск вытеснения в своп и рывков видео
Ядра CPU (тепловая карта) Загрузка каждого рабочего ядра Перекос (одно ядро горячее, остальные простаивают) — почти всегда ошибка в параметре cores
Открытые FD Файловые дескрипторы процесса Растут с числом камер и зрителей; резкий рост без роста нагрузки — утечка соединений
Ошибки UDP, потери ядра и очереди Потери на приёме UDP Любой устойчивый рост означает потерю кадров — см. Производительность
RX в очереди Данные, не забранные из сокета Устойчиво ненулевое значение = нода не успевает разбирать входящий поток
Перекос по ядрам лечится одним параметром

Если тепловая карта показывает, что работает только первое ядро, у ноды выставлено cores 1 или другое малое значение. cores 0 означает «использовать все производительные ядра» — это правильное значение по умолчанию. Меняется в админке: Ноды → нода → Сеть и TLS → Рабочие ядра (применяется при следующем перезапуске ноды).

Вкладка Сессии показывает текущих зрителей этой ноды: протокол, клиент, исходящий трафик, потери, джиттер и отставание. Устойчивые потери у одного клиента — проблема его канала; потери сразу у всех — проблема ноды или сети до неё.

Подключение внешней системы мониторинга#

Что опрашивать у Plane#

Все эндпоинты, кроме /health, требуют токена суперадминистратора.

Эндпоинт Период опроса Что даёт
GET /health 15–30 с Живость Plane и доступность базы. Без авторизации — идеально для проверки доступности
GET /api/v1/monitor/fleet/summary 30–60 с Сводка по флоту: ноды, камеры, потоки, лицензии
GET /api/v1/monitor/plane 1–5 мин История ресурсов Plane: 900 точек с шагом 2 с (последние 30 минут)
GET /api/v1/nodes 60 с Список нод: state, version, last_seen_at
GET /api/v1/sessions по необходимости Кто и что смотрит прямо сейчас
# живость — самая простая проверка, годится для любого монитора доступности
curl -sS -o /dev/null -w '%{http_code}\n' "$BASE/health"
# 200 — сервис жив и база доступна; 503 — база недоступна

# ресурсы Plane: последняя точка истории
curl -sS "$BASE/api/v1/monitor/plane" -H "Authorization: Bearer $TOKEN" \
  | python3 -c 'import sys,json;s=json.load(sys.stdin)["samples"][-1];print(s["proc_cpu_cores"], s["rss_mb"], s["open_fds"], s["db_pool_in_use"], "/", s["db_pool_max"])'
# 0.04 118 96 2 / 16

Поле proc_cpu_cores — это доля ядер, посчитанная по приросту процессорного времени, а не мгновенный снимок загрузки. Его можно использовать напрямую, без усреднения.

Токен живёт ограниченное время

Сессионный токен по умолчанию действителен 1 час (session_ttl_secs в plane.toml). Скрипт мониторинга должен получать токен заново, а не хранить его вечно: иначе через час опрос начнёт получать 401. Проверку доступности стройте на /health — она вообще не требует токена.

Для живых панелей вместо периодического опроса есть потоки событий (SSE): GET /api/v1/monitor/fleet/summary/stream, GET /api/v1/monitor/nodes, GET /api/v1/monitor/plane/stream. Полное описание всех полей и кодов ответа — Мониторинг и служебное.

Метрики ноды в формате Prometheus#

Каждая нода отдаёт метрики на своём HTTP-порту:

curl -sS http://node.example.com:8090/metrics | head -20
Метрика Тип Смысл
hastreamer_process_cpu_cores gauge Загрузка процесса в ядрах
hastreamer_worker_cores gauge Сколько рабочих ядер настроено
hastreamer_process_rss_bytes gauge Занятая память процесса
hastreamer_host_cpu_busy_ratio gauge Загрузка хоста, доля от 0 до 1
hastreamer_host_cpus gauge Логических ядер на хосте
hastreamer_mem_total_bytes, hastreamer_mem_available_bytes gauge Память хоста: всего и доступно
hastreamer_open_fds gauge Открытых файловых дескрипторов
hastreamer_uptime_seconds gauge Время работы процесса
hastreamer_streams gauge Потоков на ноде
hastreamer_sessions gauge Активных сессий раздачи
hastreamer_stream_no_data_seconds{stream="…"} gauge Секунд без данных от источника, по каждому потоку
hastreamer_stream_ingest_latency_ms{stream="…"} gauge Задержка приёма, по каждому потоку
hastreamer_udp_ingest_kernel_drops_total counter Датаграммы, потерянные в буфере ядра
hastreamer_udp_ingest_queue_dropped_total counter Датаграммы, потерянные в очереди приложения
hastreamer_udp_ingest_recv_errors_total counter Ошибки приёма UDP
hastreamer_streams_omitted gauge Потоки, для которых серии не выгружены (ограничение — 500 потоков)

Значения hastreamer_udp_ingest_* меняются только при работе с камерами по RTSP/UDP; при транспорте TCP (значение по умолчанию) они остаются нулевыми.

Эндпоинт /metrics доступен без авторизации

Так принято для систем сбора метрик, но это значит, что состав потоков и загрузка ноды видны любому, кто может открыть её HTTP-порт. Если нода доступна из интернета — ограничьте доступ к /metrics межсетевым экраном:

# разрешить сбор метрик только с адреса системы мониторинга
sudo ufw allow from <IP-системы-мониторинга> to any port 8090 proto tcp comment 'metrics scrape'

Проще всего — держать порт ноды доступным только из сети мониторинга, а видео раздавать через отдельный HTTPS-порт.

На что настраивать оповещения#

Условие Почему важно
GET /health не отвечает или отдаёт 503 Plane или база недоступны
nodes_reachable меньше nodes_total Нода выпала из флота
nodes_unlicensed или nodes_grace больше нуля Скоро остановится видео на этой ноде
cameras_unavailable растёт Камеры теряются: сеть, питание, учётные данные
hastreamer_stream_no_data_seconds больше 60 Поток жив в конфигурации, но данные не идут
Рост hastreamer_udp_ingest_*_total Потери на приёме — теряются кадры
hastreamer_process_rss_bytes подходит к пределу памяти юнита Процесс упрётся в ограничение cgroup
hastreamer_streams резко уменьшилось Часть камер отвалилась или сработал лимит лицензии

Журналы#

# Plane
sudo journalctl -u hastreamer-cctv-plane -n 100 --no-pager
sudo journalctl -u hastreamer-cctv-plane -p err --since '24 hours ago' --no-pager

# нода
sudo journalctl -u hastreamer-cctv-node -n 100 --no-pager
sudo journalctl -u hastreamer-cctv-node -f

Те же записи доступны без доступа к серверу: Мониторинг → Логи Plane и Ноды → нода → Логи. В админке журнал хранится в кольцевом буфере ограниченного размера — для долгого хранения настраивайте выгрузку journald своими средствами.

Уровень логирования — это фильтр записи, а не фильтр показа

Кнопки уровней в админке фильтруют уже сохранённые записи. Чтобы получить более подробные записи, нужно поднять уровень логирования сервиса (log_level в plane.toml или node.conf). У ноды log_level применяется без перезапуска.

Что смотреть, когда «стало хуже»#

Наблюдение Первый шаг
Видео тормозит у всех зрителей одной ноды CPU процесса и потери очереди на этой ноде — Производительность
Видео тормозит у одного зрителя Вкладка «Сессии»: потери и джиттер именно его сессии — проблема его канала
Камера то появляется, то пропадает Журнал ноды по этой камере; связность: nc -vz <адрес-камеры> 554
Админка отвечает медленно GET /api/v1/monitor/plane: db_pool_in_use близок к db_pool_max — расширьте пул
Архив внезапно стал короче Диск заполнился и включилось вытеснение — Хранилища DVR

Подробный разбор по симптомам — Диагностика неисправностей.