Skip to content

Контроль отправки

media.push.supervisor

Sapsan может активно отправлять поток дальше: на CDN и стриминговые площадки по RTMP, на другой сервер по SRT или RIST, в сеть по UDP (мультикаст/юникаст). У потока может быть несколько пушей одновременно.

Переподключение

Собственной политики повторов у пушера нет — его переподнимает стрим. Раз в пять секунд стрим сверяет работающие отправки с конфигурацией и заменяет умершего пушера новым; счётчик reconnects считает именно такие замены. Поэтому отправка на недоступный адресат не «сдаётся» и не требует ручного перезапуска: она будет подниматься, пока пуш включён.

Что реконнектом не считается:

  • правка настройки пуша — пушер тоже перезапускается, но это решение оператора, а не отказ канала;
  • выключение и включение (enabled: false) — выключение не удаление: настройка и накопленные счётчики остаются, отправки нет.

Выключение и удаление

Выключенный пуш остаётся в конфигурации со своим именем: статистика показывает его со статусом «выключен», счётчики заморожены на последних значениях, включение продолжает счёт с них же. Удаление ключа удаляет и статистику: счётчики привязаны к имени.

Мониторинг

У каждого пуша своя статистика — адресат, статус, причина отказа, скорость, байты, ошибки, реконнекты. Разбор полей, серии Prometheus и рецепты алертинга — на странице Статистика.

Что дальше

Статистика пушей

Отправка наружу считается отдельно от приёма и по каждому пушу: ключ статистики — пара «имя стрима, имя пуша», та же, что и в конфигурации. Один стрим может уходить на пять адресатов, и «стрим отдаёт 40 Мбит/с» не отвечает на вопрос, доходит ли он до конкретного из них.

Опция «статистика пушей»

Витрина пушей — отдельная лицензионная опция. Она режет только каналы отдачи: секцию pushes и плоские push_* в Admin API, серии stream_push_* в скрейпе ноды и во встроенном Prometheus-сервере. Сам сбор не останавливается, и в телеметрию Retroview счётчики уходят всегда — разбор в Retroview доступен и без опции.

Секция pushes

GET /streamer/api-v4/streams/stats/{name} (и элемент списка GET /streamer/api-v4/streams/stats) несёт объект по имени пуша:

"pushes": {
  "cdn-main": {
    "status": "running",
    "proto": "udp",
    "url": "udp://127.0.0.1:5500",
    "opened_at": "2026-08-13T11:17:53Z",
    "bitrate_kbit": 2113.4,
    "bytes_total": 19053048,
    "datagrams_total": 14478
  },
  "youtube": {
    "status": "error",
    "proto": "rtmp",
    "url": "rtmp://198.51.100.7/live/secret-key",
    "error": "rtmp connect failed: timeout after 5s",
    "reconnects_total": 22
  },
  "backup-dc": {"status": "disabled", "proto": "srt", "url": "srt://203.0.113.10:9000"}
}
Поле Что означает Как использовать
status running, error или disabled не running дольше N минут — алерт; disabled штатен, это выключенный оператором пуш
error причина статуса error первое, что читать при разборе: «connect failed», отказ публикации, отказ рукопожатия
proto, url транспорт и адресат в том виде, как их задал оператор видно, куда именно уходит поток
opened_at момент старта текущего пушера молодеет на каждом реконнекте — канал флапает
bitrate_kbit измеренная скорость отправки заметно ниже битрейта стрима — отправка не успевает
errors_rate ошибки отправки в секунду растёт при живом соединении — приёмник или канал деградируют
bytes_total отправлено байт нарастающим итогом сверка объёма отдачи по направлениям
errors_total ошибки отправки нарастающим итогом —
reconnects_total подъёмы умершего пушера растёт при status: running — канал рвётся и восстанавливается
retransmitted_packets_total ретрансмиты транспорта (SRT, RIST) растут — потери на пути к приёмнику
rtt_ms, rtt_max_ms RTT до адресата: текущий и максимум за жизнь текущего пушера; только у SRT-пуша, реконнект считает максимум заново RTT заметно выше заданной латентности — поднимайте латентность пуша
error_events кольцо последних событий: ошибки отправки (момент, текст) и остановки пушера (момент, причина); ведётся только у пушей с тегом владельца user_id_<имя> в labels хронология рядом с полем error — первой причиной текущего отказа
closures_by_reason итог остановок пушера по причинам: error, peer_closed, disabled, reconfigure, server_restart операторские остановки отличимы от смерти адресата причиной
datagrams_total, frames_total отправленные единицы: датаграммы у пакетных транспортов, кадры у RTMP —

Нулевые поля в ответе опускаются: у RTMP-пуша нет датаграмм, у UDP — кадров и ретрансмитов.

Рядом со счётчиками стрима, полями верхнего уровня того же ответа, лежат три суммы по всем пушам — push_bytes_total, push_errors_total, push_reconnects_total. Они отвечают на вопрос «сколько стрим отдал вообще», не заставляя обходить карту.

Активные пуши

Список работающих пушей всего кластера — не обход стримов, а готовая проекция плоскости статистики:

curl -fsS -u "$ADMIN_USER:$ADMIN_PASSWORD" \
  'http://central:8080/central/api-v4/pushes/active?limit=100'

Тот же путь есть на стримере: /streamer/api-v4/pushes/active. Ключ записи — тройка «стрим, пуш, узел»: у резервной группы на одну пару стрим×пуш приходятся две записи, активная и ждущая, различаемые узлом и полем standby_status. Запись несёт адресат без секретов, транспорт, владельца из тега user_id_<имя>, когда тот задан, и текущие значения: статус, время запуска текущего пушера, скорость, ошибки, реконнекты, ретрансмиты, байты и датаграммы, отставание пушера от кольца раздачи, у SRT — RTT.

{
  "pushes": [
    {
      "stream": "tv1",
      "push": "cdn-main",
      "node": "node-7",
      "transport": "srt",
      "endpoint": "srt://203.0.113.10:9000",
      "user_id": "ivan",
      "status": "running",
      "opened_at": "2026-10-21T09:15:02Z",
      "bitrate_kbit": 2113.4,
      "rtt_ms": 34,
      "rtt_max_ms": 61,
      "error_events": [
        {"at": 1792845002, "close_reason": "error"},
        {"at": 1792845062, "error": "srt connect failed: timeout after 5s"}
      ],
      "closures_by_reason": {"error": 22, "reconfigure": 1}
    }
  ]
}

События в error_events идут от старых к новым и ограничены кольцом: переполнение вытесняет старейшие, полная хронология нигде не хранится. Кольцо привязано к пушу, а не к пушеру — события сохраняются при реконнекте. Ресурс принимает фильтры stream, push, user_id, node, transport и limit, записи идут свежими сверху по времени запуска пушера. Выключенный пуш и пуш без пушера в список не попадают; пустой ответ означает «работающих пушей нет».

События, итог остановок по причинам и протокольная SRT-глубина (stream_push_srt_*) ведутся только у выделенных пушей — тех, чья конфигурация несёт тег владельца user_id_<имя> в labels. Пуш без владельца обходится базовым семейством серий и полями статуса; снятие тега прекращает запись новых точек, уже записанные остаются до вытеснения окном стора.

Серии Prometheus

Каждый счётчик пуша — своя серия с лейблом push:

Серия Лейблы
stream_push_bytes_total stream, push, proto
stream_push_errors_total stream, push, proto
stream_push_reconnects_total stream, push, proto
stream_push_retransmitted_packets_total stream, push, proto
stream_push_closures_total stream, push, proto, reason
stream_push_datagrams_total, stream_push_frames_total stream, push, proto

Во встроенном Prometheus-сервере те же счётчики доступны с лейблами name (стрим) и push; на central к ним добавляется node. Протокольная глубина — stream_push_srt_* и stream_push_rist_* — приходит в скрейпе ноды вместе с опцией расширенных счётчиков. Серия stream_push_closures_total считает остановки пушера по причинам закрытого словаря и шире reconnects_total: тот считает только перезапуски после падения, здесь — все остановки; создаётся она тоже только у выделенных пушей.

# скорость отправки по каждому адресату
rate(stream_push_bytes_total{stream="tv1"}[1m])

# суммарная отдача стрима по всем пушам
sum by (name) (rate(stream_push_bytes_total{name="tv1"}[1m]))

# рвущиеся каналы: реконнекты за пять минут
increase(stream_push_reconnects_total[5m]) > 0

# потери на пути к приёмнику по SRT/RIST
rate(stream_push_retransmitted_packets_total[1m])

# недоступный адресат: серия остановок по ошибке отправки
increase(stream_push_closures_total{reason="error"}[5m]) > 0

Как читать состояние

  • status: error и непустой error — отправка не идёт, причина названа. Пуш при этом продолжает подниматься сам, раз в пять секунд.
  • status: running, но bitrate_kbit нулевой — соединение есть, данных нет: проверьте, идёт ли сам стрим.
  • status: running и растущий reconnects_total — канал рвётся и восстанавливается; смотрите opened_at, он показывает возраст текущего соединения.
  • растущий closures_by_reason по причине error — адресат недоступен, пушер перезапускается сам; темп виден по моментам событий в error_events. Остановки по disabled и reconfigure — операторские, отказом сети не являются.
  • rtt_max_ms у SRT-пуша заметно выше заданной латентности — задержки не хватает на восстановление потерь: поднимите латентность пуша.
  • status: disabled — пуш выключен в конфигурации. Счётчики заморожены на последних значениях, это не потеря данных.

Настройка

Передайте через central именованные pushes стрима. enabled: false приостанавливает отправку и сохраняет настройку.

Транспорт

Транспорт задаётся протоколом каждого именованного пуша. Контроль отправки сам не добавляет сетевой протокол.

Поддерживаемые кодеки

Кодеки определяет выбранный протокол: UDP, RTMP, SRT, RIST, SDI.