Статистика¶
Sapsan всегда собирает полный набор счётчиков — лицензия и задача определяют лишь то, через какой канал вы их читаете. Каналов четыре:
| Канал | Что даёт | Доступность |
|---|---|---|
| Admin API | мгновенный снапшот в JSON: что со стримом прямо сейчас | всем |
| Встроенный Prometheus-сервер | готовый датасорс для Grafana с историей в несколько часов — графики без развёртывания TSDB | всем |
| Prometheus-скрейп | сырые метрики для вашей собственной TSDB и Grafana | опция «расширенные счётчики» |
| Retroview | облачный мониторинг вендора: месяцы истории, тренды, готовые алерты, сверка потребления | подписка |
Правило выбора простое:
- «Что происходит сейчас?» — Admin API или UI.
- «Что происходило последние часы?» — встроенный Prometheus-сервер.
- «Что было на прошлой неделе и почему упало ночью?» — Retroview.
- «Хочу свой Prometheus, Grafana и alertmanager» — опция расширенных счётчиков.
Статы стрима в Admin API¶
Список стримов¶
GET /streamer/api-v4/streams/stats возвращает по элементу на стрим — этим списком живёт страница каналов в UI, и его же удобно опрашивать скриптами.
| Поле | Что означает | Как использовать |
|---|---|---|
status, status_since |
состояние стрима и момент перехода в него | стрим не running дольше N минут — алерт |
bitrate_kbit |
измеренный media-битрейт активного входа, по таймстемпам кадров | просел заметно ниже номинала — источник деградировал. Это не сетевой throughput: файл может читаться быстрее реального времени |
source.url |
вход, который играет фактически | отличается от первого в конфиге — стрим живёт на резерве |
inputs[] |
рантайм-статус каждого сконфигурированного входа: url, status, давность проверки checked_ago_ms, битрейт, текст ошибки |
см. ниже |
dvr.from, dvr.to |
окно архива на этом сервере | to отстаёт от текущего времени — запись остановилась; from перестал двигаться вперёд — не работает чистка, впереди переполнение диска |
bytes_in, bytes_out |
кумулятивные счётчики байт с момента старта стрима | для скоростей и истории используйте встроенный Prometheus-сервер или Retroview: снапшот обнуляется рестартом |
Статусы элементов inputs[]:
active— играет сейчас;ok— резерв, живой по последней проверке;error— резерв с зафиксированной проблемой (текст — вerror);unchecked— резерв, который ещё ни разу не проверялся.
Это ответ на главный вопрос резервирования — «переключимся ли мы, когда упадёт основной». Резервы проверяются периодически (recheck_secondary_inputs_interval, см. резервные источники); алертить стоит и на error, и на unchecked, и на слишком старый checked_ago_ms — непроверенный резерв нельзя считать рабочим.
Один стрим¶
GET /streamer/api-v4/streams/stats/{name} добавляет к тем же полям диагностические секции — их нет в списке, чтобы список оставался дешёвым.
Секция input — счётчики текущего входа:
| Поле | Зачем |
|---|---|
bytes, frames, bitrate_kbit |
вход вообще приносит данные, и с какой скоростью |
retries |
переподключения к источнику: растёт — источник или сеть нестабильны |
input_switches |
переключения между входами: растёт — вход флапает, разбирайтесь с основным |
errors |
агрегатный счётчик ошибок входа: растёт — есть проблема; причина — в расширенных счётчиках или Retroview |
num_sec_on_primary_input, num_sec_on_secondary_input |
сколько секунд прожили на основном и на резерве: заметная доля резерва — основной вход систематически плох |
num_sec_no_data |
секунды без данных вовсе |
errors_lost_packets, errors_broken_payload, errors_desync, … |
причинная детализация ошибок — только с опцией «расширенные счётчики» |
Секция dvr в единичном ответе дополняется:
| Поле | Зачем |
|---|---|
recorded_hours |
часов, в которых реально есть данные. Сравните с шириной окна to - from: разница — это дыры в записи (стрим падал, запись отключали) |
bytes |
суммарный размер архива стрима на диске |
write.segments_written, write.segments_failed, write.segments_skipped |
счётчики записи фрагментов: segments_failed растёт — архив теряет данные прямо сейчас, проверяйте диск |
write.segments_written_slow / _delayed / _collapsed, write.segments_discontinuity |
профилирование записи — только с опцией «расширенные счётчики» |
Note
Снапшот Admin API обнуляется рестартом сервера. Он отвечает на вопрос «что сейчас», но не годится ни для сверки счёта, ни для разбора вчерашнего инцидента — для этого есть Retroview.
Встроенный Prometheus-сервер¶
Sapsan содержит встроенный Prometheus-сервер: HTTP API /api/v1/query, /api/v1/query_range, /api/v1/series, /api/v1/labels, /api/v1/label/{name}/values, /api/v1/status/buildinfo поверх собственного хранилища в памяти. Для Grafana это готовый датасорс: добавьте датасорс типа Prometheus, укажите URL сервера — и стройте графики, не разворачивая TSDB. Этими же запросами питаются встроенные графики UI.
Ограничения по построению:
- история — несколько часов, в памяти; после рестарта хранилище пустое. Это канал «что происходит сейчас», а не архив метрик;
- PromQL поддержан подмножеством: селекторы с матчерами лейблов,
rate/irate/increase, агрегацииsum/avg/min/max/countсby()/without(), арифметика,offset. Неподдержанная конструкция возвращает явную ошибку, а не искажённый результат; - набор серий — базовый; глубокие серии (per-PID, SRT, RTP) появляются с опцией «расширенные счётчики».
Запросы к одному серверу¶
# скорость приёма стрима, байт/с
rate(stream_input_bytes_total{stream="cam1"}[1m])
# ошибки входа за последние 5 минут
increase(stream_input_errors_total{stream="cam1"}[5m])
# архив пишется с ошибками?
increase(stream_dvr_write_segments_failed_total{stream="cam1"}[10m])
# суммарный входящий трафик сервера
sum(rate(stream_input_bytes_total[1m]))
# память, занятая стримами, по частям пайплайна
sum by (part) (stream_memory_bytes)
На одиночном сервере серии не несут лейбла node.
Запросы к central¶
Central и Sapsan-ноды образуют единый комплекс: central собирает статистику со всех нод, и его встроенный Prometheus-сервер отдаёт тот же самый API. Отличие одно, но сквозное — лейбл node:
- каждая серия несёт
node="имя-ноды"— видно, какая нода её произвела; - один стрим может дать несколько серий: кластерный стрим обслуживается частями на разных нодах;
nodeпоявляется в/api/v1/labelsи вlabel_values(node)— из него делается переменная дашборда Grafana с выпадающим списком нод.
# стрим целиком, независимо от того, на скольких нодах он живёт
sum without (node) (rate(stream_input_bytes_total{stream="cam1"}[1m]))
# входящий трафик комплекса в разбивке по нодам
sum by (node) (rate(stream_input_bytes_total[1m]))
# на каких нодах сейчас живёт стрим — смотрите лейбл node у результата
stream_input_bytes_total{stream="cam1"}
Один и тот же дашборд работает и против одиночного Sapsan, и против central: агрегируйте sum without (node) — на одиночном сервере лейбла нет, и агрегация ничего не меняет.
Prometheus-скрейп: свой мониторинг¶
Опция «расширенные счётчики»
Ручки скрейпа доступны только с лицензионной опцией расширенных счётчиков. Без неё используйте встроенный Prometheus-сервер и Retroview.
Для инсталляций с собственной инфраструктурой мониторинга Sapsan отдаёт метрики в текстовом формате Prometheus:
GET /streamer/api-v4/live-metrics— стримы и входы;GET /streamer/api-v4/sessions-metrics— сессии проигрывания;GET /streamer/api-v4/dvr/metrics— диски и каталог архива;GET /streamer/api-v4/runtime/metrics— процесс и аллокатор.
Отличия от встроенного Prometheus-сервера: история хранится у вас и ограничена только retention'ом вашей TSDB; доступна полная глубина, включая протокольные метрики per-PID/SRT/RTP; алертинг — ваш alertmanager. Счётчики монотонны и переживают наблюдение рестартов — это канал и для биллинговой сверки на вашей стороне.
Расширенные счётчики¶
Опция «расширенные счётчики» открывает причинную и протокольную детализацию сразу везде: в секциях input и dvr.write Admin API, в сериях встроенного Prometheus-сервера и в Prometheus-скрейпе. В телеметрию Retroview эти счётчики уходят всегда, независимо от опции, — поэтому разбор причин доступен в Retroview даже без неё.
Причины ошибок входа¶
errors_lost_packets, errors_broken_payload, errors_desync, errors_ts_pat, errors_decoder_reset, errors_dropped_frames, счётчики ресинков и реордеринга.
Зачем: перейти от «на входе есть ошибки» к «кто виноват». Растёт errors_lost_packets — теряет сеть; errors_broken_payload и errors_desync — портит источник; errors_decoder_reset — проблемы потока на уровне кодека. Без этой детализации вы видите только агрегатный errors.
MPEG-TS по каждому PID¶
По каждому PID транспортного потока: errors_ts_cc (нарушения continuity counter — главный индикатор потерь транспорта), errors_ts_tei, errors_ts_scrambled (не снялось скремблирование — проблемы CAM/ключей), errors_ts_psi_checksum, битые PES, вёдра джиттера PCR, недобор буфера декодера (HRD).
Зачем: это материал мониторинга вещательного класса. Алерт rate(errors_ts_cc) > 0 по каждому PID ловит деградацию транспорта раньше, чем её увидит зритель; джиттер PCR и HRD показывают, переживёт ли поток аппаратный декодер.
SRT¶
RTT и его вариация, потери и ретрансмиты в обе стороны, дропы по опозданию, заполненность буферов, таймауты keepalive.
Зачем: подбор latency под реальный канал и диагноз «кто теряет — мы или удалённая сторона». Ретрансмиты растут при стабильном RTT — потери на пути; RTT скачет — перегружен канал.
RTP/RTSP по каналам¶
Потерянные пакеты, скачки и залипания таймстемпов, NACK'и, переполнения буферов — по каждому RTP-каналу (видео/аудио) камеры.
Зачем: диагностика парка камер — какая камера сыплет, ещё до жалоб на артефакты.
Производительность записи DVR¶
segments_written_slow, segments_written_delayed, segments_written_collapsed, segments_discontinuity.
Зачем: ранний сигнал «диск не успевает». Доля slow/delayed растёт при том же трафике — деградирует хранилище; разрывы (discontinuity) означают дыры, которые вы потом увидите в recorded_hours.
Retroview¶
Retroview — облачный мониторинг вендора. Sapsan раз в минуту отправляет телеметрию — полный каталог счётчиков, включая всю расширенную детализацию — и Retroview хранит её месяцами. Настраивать на сервере ничего не нужно: канал работает вместе с лицензией.
Когда идти в Retroview, а не во встроенный Prometheus-сервер:
- история и тренды — рост трафика и числа стримов за месяцы, планирование мощностей;
- постмортемы — что происходило со стримом ночью: телеметрия переживает рестарты и не зависит от памяти сервера;
- сверка потребления — счётчики снимаются во времени внешней системой, поэтому счёт можно сверить даже если серверы перезапускались;
- разбор причин без опции расширенных счётчиков — телеметрия несёт причинную детализацию всегда;
- готовые алерты — продуктовые правила вместо самодельных.
Рецепты¶
| Вопрос | Где смотреть | Признак проблемы |
|---|---|---|
| Стрим жив? | status в API; rate(stream_input_bytes_total[1m]) во встроенном Prometheus |
статус не running; скорость приёма упала в ноль |
| Резерв готов? | inputs[] в списке статов |
status = error или unchecked; checked_ago_ms много больше интервала проверки |
| Живём на резерве? | source.url; num_sec_on_secondary_input |
URL не первый из конфига; счётчик секунд на резерве растёт |
| Вход деградирует? | input.errors, input.retries; причины — расширенные счётчики или Retroview |
счётчики растут при живом стриме |
| Архив пишется? | dvr.to в списке; dvr.write.segments_failed в единичном GET |
to отстаёт от настоящего времени; segments_failed растёт |
| В архиве дыры? | dvr.recorded_hours против окна to - from |
записанных часов заметно меньше ширины окна |
| Диски успевают? | segments_written_slow/_delayed (опция); dvr_disk_free_bytes в скрейпе |
доля медленных записей растёт; свободное место тает быстрее ожидаемого |
| Сервер здоров? | runtime/metrics: process_rss_bytes; встроенный Prometheus: stream_memory_bytes |
память монотонно растёт без роста нагрузки |
| Что было ночью? | Retroview | — |