Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

FieldTypeDescription
timestampUInt64Time stamp
ipIPv4Server address
nodeIdStringNode Id (IP address string)
eventTypeUInt64Event type Id
eventPayloadStringEvent payload

Stream metrics data (table

...

MediaSessionEvent)

Since build 5.2.1896 it is possible to collect a certain stream metrics data

FieldTypeDescription
timestampUInt64Time stamp
ipIPv4Server address
mediaSessionIdStringMedia session Id
streamNameStringStream name
videoProfileIdUInt32Video profile Id
videoWidthUInt32Pictiure height
videoHeightUInt32Picture width
videoFrameRateUInt32Video frame rate per second
videoKframesUInt64Key frames number (I-frame)
videoPframesUInt64P-frames number
videoBframesUInt64B-frames number
videoRateUInt64Video bitrate, bps
audioRateUInt64Audio bitrate, bps
videoSyncTimeUInt64Video synchronization value
audioSyncTimeUInt64Audio synchronization value
videoTimestampUInt64Video packet timestamp
audioTimestampUInt64Audio packet timestamp
lastKeyFrameSyncTimeUInt64Video synchronization value from the last key frame
sendNACKUInt64NACK sent count
recvNACKUInt64NACK received count
videoFramesLostUInt64Lost video frames count
audioPacketsLostUInt64Lost audio frames count
audioPlaybackSpeedFloat32Audio publishing/playback speed
videoPlaybackSpeedFloat32Video publishing/playback speed

HLS stream data (table

...

HlsStreamEvent)

Since build 5.2.1917 it is possible to collect a certain HLS stream events data

FieldTypeDescription
timestampUInt64Time stamp
ipIPv4Server address
severityUInt8Event severity level: INFO, WARNING, ERROR
messageTypeUInt16Event type
streamIdStringHLS stream Id
variantNameStringQuality variant name
segmentIdStringHLS segment Id
messageStringLogged event description

HLS segments data (table

...

HlsSegmenterEvent)

Since build 5.2.1917 it is possible to collect a certain HLS stream segments data

FieldTypeDescription
timestampUInt64Time stamp
ipIPv4Server address
streamIdStringHLS stream Id
variantNameStringQuality variant name
segmentIdStringSegment Id
segmentStartPtsUInt64Segment start PTS
videoStartPtsUInt64Video start PTS
audioStartPtsUInt64Audio start PTS
videoWidthUInt32Picture width
videoHeightUInt32Picture height
videoFrameCountUInt32Video frames count
audioPacketCountUInt32Audio packets count
segmentDurationUInt64Segment duration, ms
independentBoolIndependent segment
gapBoolGAP segment
discontinuityBoolDISCONTINUTY segment
segmentIntervalUInt64Segments interval, ms
partialBoolPartial segment
playbackSpeedFloat32Playback speed

HLS subscribers data (table

...

HlsClientEvent)

Since build 5.2.1929 it is possible to collect a certain HLS stream subscribers data

...

  • CPU from 4 physical cores, frequency from 3 GHz, for example Intel(R) Xeon(R) CPU E3-1246 v3 @ 3.50GHz
  • RAM from 32 Gb
  • HDD from 2 Tb

ClickHouse installation

...

from rpm package (CentOS, Red Hat etc)

1. Create repository file altinity_clickhouse.repo in /etc/yum.repos.d folderAdd the official repository

Code Block
languagebash
themeRDark
sudo cat <<EOF > /etc/yum.repos.d/altinity_clickhouse.repo
[altinity_clickhouse]
name=altinity_clickhouse
baseurl=https://packagecloud.io/altinity/clickhouse/el/7/$basearch
repo_gpgcheck=1
gpgcheck=0
enabled=1
gpgkey=https://packagecloud.io/altinity/clickhouse/gpgkey
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
metadata_expire=300

[altinity_clickhouse-source]
name=altinity_clickhouse-source
baseurl=https://packagecloud.io/altinity/clickhouse/el/7/SRPMS
repo_gpgcheck=1
gpgcheck=0
enabled=1
gpgkey=https://packagecloud.io/altinity/clickhouse/gpgkey
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
metadata_expire=300
EOF

...

yum install -y yum-utils
sudo yum-config-manager --add-repo https://packages.clickhouse.com/rpm/clickhouse.repo

2. Install ClickHouse

Code Block
languagebash
themeRDark
sudo yum install -y clickhouse-server clickhouse-client

3. Launch ClickHouse

Code Block
languagebash
themeRDark
sudo systemctl enable clickhouse-server
sudo systemctl start clickhouse-server

ClickHouse installation from deb package (Debian, Ubuntu etc)

1. Add the official repository

Code Block
languagebash
themeRDark
sudo yum apt-qget makecacheinstall -y apt--enablerepo='altinity_clickhouse'

...

transport-https ca-certificates dirmngr
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 8919F6BD2B48D754
echo "deb https://packages.clickhouse.com/deb stable main" | sudo tee /etc/apt/sources.list.d/clickhouse.list
sudo apt-get update

2. Install ClickHouse

Code Block
languagebash
themeRDark
sudo yumapt-get install -y clickhouse-server clickhouse-client

43. Launch ClickHouse

Code Block
languagebash
themeRDark
sudo systemctl startenable clickhouse-server

...


sudo systemctl start clickhouse-server

ClickHouse configuration for WCS builds before 5.2.1999

1. Uncomment the following string in /etc/clickhouse-server/config.xml file to listen all the server network interfaces

...

2. Set the following parameter for default user in /etc/clickhouse-server/users.xml file to temporary allow users managentmanagement

Code Block
languagexml
themeRDark
            <access_management>1</access_management>

...

Code Block
languagebash
themeRDark
systemctl restart clickhouse-server

WCS configuration

Data logging to ClickHouse is enabled by the following list of the data to collect

Code Block
themeRDark
rels_enabled=CONNECTION,STREAM,CDN,MEDIA_SESSION

...

ClickHouse configuration for WCS builds 5.2.1999 and newer

Since WCS build 5.2.1999 DB is created automatically when a certain WCS build is connection fron a certain IP address. All the datadases metadata are stored in the table WcsMetadata.metadata

Code Block
languagesql
themeRDark
SELECT *
FROM WcsMetadata.metadata

┌─dbName───────────────────────────────┬─ip────────────┬─hostname──────────────┬─versionNumber─┬─versionHash──────────────────────────────┐
│ test1flashphonercom_192168065_521999 │ 192.168.0.65  │ test1.flashphoner.com │ 5.2.1999      │ 93e39647113e0121dabc4283ef700814c355568f │
│ test2flashphonercom_192168039_521999 │ 192.168.0.39  │ test2.flashphoner.com │ 5.2.1999      │ 93e39647113e0121dabc4283ef700814c355568f │
└──────────────────────────────────────┴───────────────┴───────────────────────┴───────────────┴──────────────────────────────────────────┘

Therefore only the user should be created and privileges to create databases, tables and to insert data to the tables should be granted to set up ClickHouse.

1. Uncomment the following string in /etc/clickhouse-server/config.xml file to listen all the server network interfaces 

Code Block
languagexml
themeRDark
    <listen_host>::</listen_host>

2. Set the following parameter for default user in /etc/clickhouse-server/users.xml file to temporary allow users management

Code Block
languagexml
themeRDark
            <access_management>1</access_management>
            <named_collection_control>1</named_collection_control>
            <show_named_collections>1</show_named_collections>
            <show_named_collections_secrets>1</show_named_collections_secrets>

3. Restart ClickHouse

Code Block
languagebash
themeRDark
systemctl restart clickhouse-server

4. Create wcs user and grant the privileges needed

Code Block
languagebash
themeRDark
cat wcs_clickhouse_users.sql | clickhouse-client -mn
Code Block
languagesql
themeRDark
titlewcs_clickhouse_users.sql
collapsetrue
CREATE USER IF NOT EXISTS wcs IDENTIFIED BY 'wcs';
SET allow_introspection_functions = 1;
GRANT ALL ON *.* TO wcs WITH GRANT OPTION;

5. Disable users management for default user by setting the following parameter in /etc/clickhouse-server/users.xml file

Code Block
languagexml
themeRDark
            <access_management>0</access_management>

6. Restart ClickHouse

Code Block
languagebash
themeRDark
systemctl restart clickhouse-server

WCS configuration

Data logging to ClickHouse is enabled by the following list of the data to collect

Code Block
themeRDark
rels_enabled=CONNECTION,STREAM,CDN,MEDIA_SESSION

The following data types are available:

CONNECTION, STREAM, CDN, MEDIA_SESSION, HLS_SEGMENTER, HLS_STREAM, HLS_CLIENT, MIXER, AUDIO_RECOVERY, RTMP_IN_BUFFER

TypeDescription
CONNECTIONClient session events
STREAMStream events
CDNCDN events
MEDIA_SESSIONStream metrics
HLS_SEGMENTERHLS stream segment metrics
HLS_STREAMHLS stream events
HLS_CLIENTHLS clients statistics
MIXERMixer events and metrics
AUDIO_RECOVERYAudio packets recovery events
RTMP_IN_BUFFERRTMP incoming streams buffer metrics

При управлении большим количеством WCS серверов, для отладки возможных проблем с вещанием потоков, возникает необходимость централизованного сбора данных о потоках, клиентских соединениях и событий CDN. Фактически, необходимо в одной точке собрать информацию, которая пишется в логи каждого сервера. При этом само по себе логирование в промышленной эксплуатации сведено к минимуму, чтобы не давать нагрузку на дисковую подсистему сервера.

Для сбора данных в реальном времени в больших объемах хорошо подходят базы данных временных рядов. На основе одной из таких БД c открытым исходным кодом ClickHouse, в сборке 5.2.774 добавлена система удаленного сбора логов RELS (Remote Event Logging System).

Архитектура

Каждый WCS сервер отправляет данные в ClickHouse независимо, используя JDBC-драйвер и HTTP-соединение. Для оптимизации работы с БД ClickHouse, данные буферизуются и отправляются пачками по времени

Image Added

Описание таблиц данных

Данные собираются в таблицы ClickHouse, перечисленные ниже. При этом, в таблицу записывается числовой идентификатор события. Для того, чтобы отобразить события в выборках в удобном для чтения виде, каждой таблице сопоставлен словарь текстовых строк, описывающих события.

Данные соединений (таблица ConnectionEvent)

ПолеТипОписание
timestampUInt64Метка времени
ipIPv4Адрес сервера
sessionIdStringИдентификатор сессии
eventTypeUInt64Идентификатор типа события
eventPayloadStringСодержимое события

Данные о событиях потоков (таблица StreamEvent)

ПолеТипОписание
timestampUInt64Метка времени
ipIPv4Адрес сервера
sessionIdStringИдентификатор сессии
mediaSessionIdStringИдентификатор медиасессий
streamNameStringИмя потока
eventTypeUInt64Идентификатор типа события
eventPayloadStringСодержимое события

Данные CDN (таблица CDNEvent)

ПолеТипОписание
timestampUInt64Метка времени
ipIPv4Адрес сервера
nodeIdStringИдентификатор узла (строка IP адреса)
eventTypeUInt64Идентификатор типа события
eventPayloadStringСодержимое события

Данные о метриках потоков (таблица MediaSessionEvent)

В сборке 5.2.1896 добавлен сбор данных о метриках определенных потоков

ПолеТипОписание
timestampUInt64Метка времени
ipIPv4Адрес сервера
mediaSessionIdStringИдентификатор медиасессий
streamNameStringИмя потока
videoProfileIdUInt32Идентификатор профиля видео
videoWidthUInt32Высота картинки
videoHeightUInt32Ширина картинки
videoFrameRateUInt32Частота кадров в секунду
videoKframesUInt64Количество ключевых кадров (I-frame)
videoPframesUInt64Количество промежуточных кадров (P-frame)
videoBframesUInt64Количество двунаправленных кадров (B-frames)
videoRateUInt64Битрейт видео, бит/с
audioRateUInt64Битрейт аудио, бит/с
videoSyncTimeUInt64Значение синхронизации видео
audioSyncTimeUInt64Значение синхронизации аудио
videoTimestampUInt64Метка времени из видеопакета
audioTimestampUInt64Метка времени из аудиопакета
lastKeyFrameSyncTimeUInt64Значение синхронизации видео из последнего ключевого кадра
sendNACKUInt64Количество отправленных NACK
recvNACKUInt64Количество полученных NACK
videoFramesLostUInt64Количество потерянных кадров видео
audioPacketsLostUInt64Количество потерянных пакетов аудио
audioPlaybackSpeedFloat32Скорость публикации/проигрывания аудио
videoPlaybackSpeedFloat32Скорость публикации/проигрывания видео

Данные о нарезке HLS потока (таблица HlsStreamEvent)

В сборке 5.2.1917 добавлен сбор данных о событиях определенных HLS потоков

ПолеТипОписание
timestampUInt64Метка времени
ipIPv4Адрес сервера
severityUInt8Уровень события: INFO, WARNING, ERROR
messageTypeUInt16Тип события
streamIdStringИдентификатор HLS потока (имя)
variantNameStringИмя варианта качества
segmentIdStringИдентификатор сегмента
messageStringОписание события в том виде, как залогировано

Данные о сегментах HLS потока (таблица HlsSegmenterEvent)

В сборке 5.2.1917 добавлен сбор данных о сегментах определенных HLS потоков

ПолеТипОписание
timestampUInt64Метка времени
ipIPv4Адрес сервера
streamIdStringИдентификатор HLS потока (имя)
variantNameStringИмя варианта качества
segmentIdStringИдентификатор сегмента
segmentStartPtsUInt64Начальный PTS сегмента
videoStartPtsUInt64Начальный PTS  видео дорожки
audioStartPtsUInt64Начальный PTS  аудио дорожки
videoWidthUInt32Ширина картинки
videoHeightUInt32Высота картинки
videoFrameCountUInt32Количество кадров видео
audioPacketCountUInt32Количество пакетов аудио
segmentDurationUInt64Длительность сегмента, мс
independentBoolНезависимый сегмент
gapBoolGAP  сегмент
discontinuityBoolDISCONTINUTY сегмент
segmentIntervalUInt64Интервал между сегментами, мс
partialBoolЧастичный сегмент
playbackSpeedFloat32Скорость проигрывания

Данные о подписчиках HLS потока (таблица HlsClientEvent)

В сборке 5.2.1929 добавлен сбор данных о подписчиках определенных HLS потоков

ПолеТипОписание
creationTimeUInt64Время подключения подписчика
responseTimeUInt64Время ответа на запрос подписчика
streamIdStringИдентификатор HLS потока (имя)
variantNameStringИмя варианта качества
uriStringURI плейлиста
localIpIPv4Адрес сервера
remoteIpIPv4Адрес клиента
remotePortUInt32TCP  порт, с которого подключился клиента
userAgentStringЗначение заголовка User-Agent, полученное от клиента
httpStatusUInt32Статус ответа на запрос клиента
clientIdUInt64Идентификатор клиентской сессии

Данные о метриках микшера (таблица MixerEvent)

В сборке 5.2.1923 добавлен сбор данных о метриках определенных микшеров

ПолеТипОписание
timestampUInt64Метка времени
mixerMediaSessionIdStringИдентификатор медиасессии микшера
mixerStreamNameStringИмя выходного потока микшера
mediaSessionIdStringИдентификатор входящего потока микшера
streamNameStringИмя входящего потока
mixerAverageTickTimeInMsInt64Среднее время одного такта микширования, мс
audioMixerSyncInt64Значение синхронизации аудио в выходном потоке микшера
videoMixerSyncInt64Значение синхронизации видео в выходном потоке микшера
nextAudioDataTimeInt64Время следующего аудио пакета
nextVideoDataTimeInt64Время следующего видео пакета
audioBufferedInt64Количество аудио пакетов в буфере входящего потока
videoBufferedInt64Количество видео пакетов в буфере входящего потока
audioDropsCounterInt64Количество отброшенных аудио пакетов входящего потока
audioDropsSizeInBytesInt64Объем отброшенных данных аудио в байтах
videoDropsCounterInt64Количество отброшенных видео пакетов входящего потока
videoDropsSizeInBytesInt64Объем отброшенных данных видео в байтах
videoFpsInt64Частота кадров выходного потока микшера в секунду
audioRateDOUBLEБитрейт аудио выходного потока микшера, бит/с
videoRateDOUBLEБитрейт видео выходного потока микшера, бит/с
eventTypeUInt32Тип события микшера
eventPayloadStringОписание события микшера

Данные о восстановлении потерянных аудио пакетов (таблица AudioRecoveryEvent)

В сборке 5.2.1969 добавлен сбор данных о восстановлении потерянных аудио пакетов

ПолеТипОписание
timestampUInt64Метка времени
mediaSessionIdStringИдентификатор медиасессии
typeUInt32Тип события
rtpTimestampUInt64Метка времени из RTP  потока

Данные о метриках буфера для входящих RTMP  потоков (таблица RtmpInBufferEvent)

В сборке 5.2.1978 добавлен сбор данных о метриках буфера входящих RTMP  потоков

ПолеТипОписание
timestampUInt64Метка времени
streamClockTimeUInt64Метка времени по часам потока
mediaSessionIdStringИдентификатор медиасессии
streamNameStringИмя потока
nextAudioDataTimeInt64Метка времени следующего пакета аудио данных
nextVideoDataTimeInt64Метка времени следующего пакета видео данных
audioBufferedInt64Количество данных аудио в буфере
videoBufferedInt64Количество данных видео в буфере
maximumAllowedBufferInt64Максимальная емкость буфера
bufferingCounterInt64Счетчик буферизаций
lastAudioDataTimeInt64Время последнего пакета аудио данных
lastVideoDataTimeInt64Время последнего пакета видео данных
bufferStateUInt32Состояние буфера

Настройка

Установка и настройка ClickHouse

Требования к серверу

  • CPU не менее 4 физических ядер, частотой не менее 3 ГГц, например Intel(R) Xeon(R) CPU E3-1246 v3 @ 3.50GHz
  • RAM не менее 32 Гб
  • HDD не менее 2 Тб

Установка ClickHouse из rpm пакетов (CentOS, Red Hat etc)

1. Подключите официальный репозиторий

Code Block
languagebash
themeRDark
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://packages.clickhouse.com/rpm/clickhouse.repo

2. Установите ClickHouse

Code Block
languagebash
themeRDark
sudo yum install -y clickhouse-server clickhouse-client

3. Запустите ClickHouse

Code Block
languagebash
themeRDark
sudo systemctl enable clickhouse-server
sudo systemctl start clickhouse-server

Установка ClickHouse из deb пакетов (Debian, Ubuntu etc)

1. Подключите официальный репозиторий

Code Block
languagebash
themeRDark
sudo apt-get install -y apt-transport-https ca-certificates dirmngr
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 8919F6BD2B48D754
echo "deb https://packages.clickhouse.com/deb stable main" | sudo tee /etc/apt/sources.list.d/clickhouse.list
sudo apt-get update

2. Установите ClickHouse

Code Block
languagebash
themeRDark
sudo apt-get install -y clickhouse-server clickhouse-client

3. Запустите ClickHouse

Code Block
languagebash
themeRDark
sudo systemctl enable clickhouse-server
sudo systemctl start clickhouse-server

Настройка ClickHouse для сборок WCS до 5.2.1999

1. Для того, чтобы прослушивать входящие запросы на всех интерфесах сервера, раскомментируйте строку в файле /etc/clickhouse-server/config.xml 

Code Block
languagexml
themeRDark
    <listen_host>::</listen_host>

2. Для того, чтобы создать пользователя, укажите для пользователя default в файле /etc/clickhouse-server/users.xml параметр

Code Block
languagexml
themeRDark
            <access_management>1</access_management>

3. Перезапустите ClickHouse

Code Block
languagebash
themeRDark
systemctl restart clickhouse-server

4. Создайте базу данных wcs и таблицы в ней

Code Block
languagebash
themeRDark
cat wcs_clickhouse.sql | clickhouse-client -mn
Code Block
languagesql
themeRDark
titlewcs_clickhouse.sql
collapsetrue
CREATE DATABASE IF NOT EXISTS wcs;

DROP DICTIONARY IF EXISTS wcs.DictionaryStreamEvents;
 
DROP DICTIONARY IF EXISTS wcs.DictionaryConnectionEvents;
 
DROP DICTIONARY IF EXISTS wcs.DictionaryCDNEvents;

DROP DICTIONARY IF EXISTS wcs.DictionaryHlsStreamEventType;

DROP DICTIONARY IF EXISTS wcs.DictionaryHlsStreamEventSeverity;
 
DROP DICTIONARY IF EXISTS wcs.DictionaryMixerEvents;

DROP DICTIONARY IF EXISTS wcs.DictionaryBufferStateTypes;
 
DROP TABLE IF EXISTS wcs.StreamEvent;
 
DROP TABLE IF EXISTS wcs.ConnectionEvent;
 
DROP TABLE IF EXISTS wcs.CDNEvent;
 
DROP TABLE IF EXISTS wcs.StreamEventTypes;
 
DROP TABLE IF EXISTS wcs.ConnectionEventTypes;
 
DROP TABLE IF EXISTS wcs.CDNEventTypes;

DROP TABLE IF EXISTS wcs.MediaSessionEvents;

DROP TABLE IF EXISTS wcs.HlsStreamEvents;

DROP TABLE IF EXISTS wcs.HlsSegmenterEvents;

DROP TABLE IF EXISTS wcs.HlsStreamEventSeverity;

DROP TABLE IF EXISTS wcs.HlsStreamEventType;

DROP TABLE IF EXISTS wcs.HlsClientEvents;

DROP TABLE IF EXISTS wcs.MixerEvent;

DROP TABLE IF EXISTS wcs.MixerEventTypes;

DROP TABLE IF EXISTS wcs.RtmpInBufferEvent;

DROP TABLE IF EXISTS wcs.AudioRecoveryEvent;

DROP TABLE IF EXISTS wcs.BufferStateTypes;

CREATE TABLE wcs.ConnectionEventTypes
(
    `id` UInt32,
    `type` String
)
ENGINE = MergeTree()
ORDER BY id
SETTINGS index_granularity = 8192;
 
INSERT INTO wcs.ConnectionEventTypes VALUES (0, 'CONNECTED'), (1, 'DISCONNECTED');
 
CREATE TABLE wcs.StreamEventTypes
(
    `id` UInt32,
    `type` String
)
ENGINE = MergeTree()
ORDER BY id
SETTINGS index_granularity = 8192;
 
INSERT INTO wcs.StreamEventTypes VALUES (0,'CREATED'),(1,'LOCAL_SDP_CREATED'),(2,'REMOTE_SDP_RECEIVED'),(3,'ICE_STARTED'),(4,'ICE_COMPLETE'),(5,'DTLS_STARTED'),(6,'DTLS_COMPLETE'),(7,'INITIALIZED'),(8,'DISPOSING'),(9,'DISPOSED'),(10,'AUDIO_RECEIVED'),(11,'VIDEO_RECEIVED'),(12,'VIDEO_KFRAME_RECEIVED'),(13,'AUDIO_RTCP_RECEIVED'),(14,'VIDEO_RTCP_RECEIVED'),(15,'RESOLUTION_RECEIVED'),(16,'VIDEO_ENCODER_CREATED'),(17,'AUDIO_ENCODER_CREATED'),(18,'VIDEO_ENCODER_DISPOSED'),(19,'AUDIO_ENCODER_DISPOSED'),(20,'TERMINATED'),(21,'AUDIO_SENT'),(22,'VIDEO_SENT'),(23,'VIDEO_JITTER_BUFFER_STALL'),(24,'SENT_PLI'),(25,'RECEIVED_PLI'),(26,'SYNC_BUFFER_FULL'),(27,'SYNC_FORCE_FAILED'),(28,'SYNC_SHIFT'),(29,'SYNC_DEVIATION'),(30,'VIDEO_STATS'),(31,'RECORD');
 
CREATE TABLE wcs.CDNEventTypes
(
    `id` UInt32,
    `type` String
)
ENGINE = MergeTree()
ORDER BY id
SETTINGS index_granularity = 8192;
 
INSERT INTO wcs.CDNEventTypes VALUES (0, 'STATE'), (1, 'CDN_STATE'), (2, 'VERSION'), (3, 'ACL_REFRESH'), (4, 'ACL_UPDATE');
 
CREATE DICTIONARY wcs.DictionaryStreamEvents (
    `id` UInt16,
    `type` String DEFAULT ''
)
PRIMARY KEY id
SOURCE(CLICKHOUSE(
 host 'localhost'
 port 9000
 user 'default'
 password ''
 db 'wcs'
 table 'StreamEventTypes'
))   
LAYOUT(FLAT())
LIFETIME(300);
 
CREATE DICTIONARY wcs.DictionaryConnectionEvents (
    `id` UInt16,
    `type` String DEFAULT ''
)
PRIMARY KEY id
SOURCE(CLICKHOUSE(
 host 'localhost'
 port 9000
 user 'default'
 password ''
 db 'wcs'
 table 'ConnectionEventTypes'
))   
LAYOUT(FLAT())
LIFETIME(300);
 
CREATE DICTIONARY wcs.DictionaryCDNEvents (
    `id` UInt16,
    `type` String DEFAULT ''
)
PRIMARY KEY id
SOURCE(CLICKHOUSE(
 host 'localhost'
 port 9000
 user 'default'
 password ''
 db 'wcs'
 table 'CDNEventTypes'
))   
LAYOUT(FLAT())
LIFETIME(300);
 
CREATE TABLE wcs.StreamEvent
(
    `timestamp` UInt64,
    `ip` IPv4,
    `sessionId` String,
    `mediaSessionId` String,
    `streamName` String,
    `eventType` UInt64,
    `eventPayload` String
)
ENGINE = MergeTree()
ORDER BY (sessionId, mediaSessionId, streamName)
SETTINGS index_granularity = 8192;
 
CREATE TABLE wcs.ConnectionEvent
(
    `timestamp` UInt64,
    `ip` IPv4,
    `sessionId` String,
    `eventType` UInt64,
    `eventPayload` String
)
ENGINE = MergeTree()
ORDER BY (timestamp, sessionId)
SETTINGS index_granularity = 8192;
 
CREATE TABLE wcs.CDNEvent
(
    `timestamp` UInt64,
    `ip` IPv4,
    `nodeId` String,
    `eventType` UInt64,
    `eventPayload` String
)
ENGINE = MergeTree()
ORDER BY (nodeId, eventType)
SETTINGS index_granularity = 8192;

CREATE TABLE wcs.MediaSessionEvents
(
    `timestamp` UInt64,
    `ip` IPv4,
    `mediaSessionId` String,
    `streamName` String,
    `videoProfileId` UInt32,
    `videoWidth` UInt32,
    `videoHeight` UInt32,
    `videoFrameRate` UInt32,
    `videoKframes` UInt64,
    `videoPframes` UInt64,
    `videoBframes` UInt64,
    `videoRate` UInt64,
    `audioRate` UInt64,
    `videoSyncTime` UInt64,
    `audioSyncTime` UInt64,
    `videoTimestamp` UInt64,
    `audioTimestamp` UInt64,
    `lastKeyFrameSyncTime` UInt64,
    `sendNACK` UInt64,
    `recvNACK` UInt64,
    `videoFramesLost` UInt64,
    `audioPacketsLost` UInt64,
    `audioPlaybackSpeed` Float32,
    `videoPlaybackSpeed` Float32
)
ENGINE = MergeTree()
ORDER BY (mediaSessionId, streamName)
SETTINGS index_granularity = 8192;

CREATE TABLE wcs.HlsSegmenterEvents
(
    `timestamp` UInt64,
    `ip` IPv4,
    `streamId` String,
    `variantName` String,
    `segmentId` String,
    `segmentStartPts` UInt64,
    `videoStartPts` UInt64,
    `audioStartPts` UInt64,
    `videoWidth` UInt32,
    `videoHeight` UInt32,
    `videoFrameCount` UInt32,
    `audioPacketCount` UInt32,
    `segmentDuration` UInt64,
    `independent` Bool,
    `gap` Bool,
    `discontinuity` Bool,
    `segmentInterval` UInt64,
    `partial` Bool,
    `playbackSpeed` Float32
)
ENGINE = MergeTree()
ORDER BY (streamId)
SETTINGS index_granularity = 8192;

CREATE TABLE wcs.HlsStreamEventSeverity
(
    `id` UInt8,
    `type` String
)
ENGINE = MergeTree()
ORDER BY id
SETTINGS index_granularity = 8192;

INSERT INTO wcs.HlsStreamEventSeverity VALUES (0, 'INFO'), (1, 'WARNING'), (2, 'ERROR');

CREATE TABLE wcs.HlsStreamEventType
(
    `id` UInt16,
    `type` String
)
ENGINE = MergeTree()
ORDER BY id
SETTINGS index_granularity = 8192;

INSERT INTO wcs.HlsStreamEventType
VALUES (0, 'PLAYBACK_SPEED'), (1, 'FPS_CHANGED'), (2, 'GAP'), (3, 'RESOLUTION_CHANGED'), (4, 'DISCONTINUITY'), (5, 'TASK_SKIPPED'), (6, 'NO_KYE_FRAME'), (7, 'NO_VIDEO'), (8, 'NO_AUDIO'), (9, 'SEGMENT_INTERVAL'), (10, 'OTHER');

CREATE DICTIONARY wcs.DictionaryHlsStreamEventSeverity
(
   `id` UInt8,
   `type` String DEFAULT ''
)
PRIMARY KEY id
SOURCE(CLICKHOUSE(
 host 'localhost'
 port 9000
 user 'default'
 password ''
 db 'wcs'
 table 'HlsStreamEventSeverity'
))
LAYOUT(FLAT())
LIFETIME(300);

CREATE DICTIONARY wcs.DictionaryHlsStreamEventType
(
   `id` UInt16,
   `type` String DEFAULT ''
)
PRIMARY KEY id
SOURCE(CLICKHOUSE(
 host 'localhost'
 port 9000
 user 'default'
 password ''
 db 'wcs'
 table 'HlsStreamEventType'
))
LAYOUT(FLAT())
LIFETIME(300);

CREATE TABLE wcs.HlsStreamEvents
(
    `timestamp` UInt64,
    `ip` IPv4,
    `severity` UInt8,
    `messageType` UInt16,
    `streamId` String,
    `variantName` String,
    `segmentId` String,
    `message` String
)
ENGINE = MergeTree()
ORDER BY (streamId)
SETTINGS index_granularity = 8192; 

CREATE TABLE wcs.HlsClientEvents
(
    `creationTime` UInt64,
    `responseTime` UInt64,
    `streamId` String,
    `variantName` String,
    `uri` String,
    `localIp` IPv4,
    `remoteIp` IPv4,
    `remotePort` UInt32,
    `userAgent` String,
    `httpStatus` UInt32,
    `clientId` UInt64
)
ENGINE = MergeTree()
ORDER BY (creationTime)
SETTINGS index_granularity = 8192;

CREATE TABLE wcs.MixerEvent
(
    `timestamp` UInt64,
    `mixerMediaSessionId` String,
    `mixerStreamName` String,
    `mediaSessionId` String,
    `streamName` String,
    `mixerAverageTickTimeInMs` Int64,
    `audioMixerSync` Int64,
    `videoMixerSync` Int64,
    `nextAudioDataTime` Int64,
    `nextVideoDataTime` Int64,
    `audioBuffered` Int64,
    `videoBuffered` Int64,
    `audioDropsCounter` Int64,
    `audioDropsSizeInBytes` Int64,
    `videoDropsCounter` Int64,
    `videoDropsSizeInBytes` Int64,
    `videoFps` Int64,
    `audioRate` DOUBLE,
    `videoRate` DOUBLE,
    `eventType` UInt32,
    `eventPayload` String
)
ENGINE = MergeTree()
ORDER BY timestamp
SETTINGS index_granularity = 8192;

CREATE TABLE wcs.MixerEventTypes
(
    `id` UInt32,
    `type` String
)
ENGINE = MergeTree()
ORDER BY id
SETTINGS index_granularity = 8192;

INSERT INTO wcs.MixerEventTypes VALUES (0, 'nullEvent'), (1, 'dropBallastAudio'), (2, 'dropBallastVideo'), (3, 'audioNotBuffered'), (4, 'videoNotBuffered'), (5, 'audioBufferExhausted'), (6, 'videoBufferExhausted'), (7, 'alignStreamFailed'), (8, 'alignStreamDropAudio'), (9, 'alignStreamDropVideo'), (10, 'rateOutOfBoundsAudio'), (11, 'rateOutOfBoundsVideo');

CREATE DICTIONARY wcs.DictionaryMixerEvents (
    `id` UInt16,
    `type` String DEFAULT ''
)
PRIMARY KEY id
SOURCE(CLICKHOUSE(
 host 'localhost'
 port 9000
 user 'default'
 password ''
 db 'wcs'
 table 'MixerEventTypes'
))
LAYOUT(FLAT())
LIFETIME(300);

CREATE TABLE wcs.RtmpInBufferEvent
(
    `timestamp` UInt64,
    `streamClockTime` UInt64,
    `mediaSessionId` String,
    `streamName` String,
    `nextAudioDataTime` Int64,
    `nextVideoDataTime` Int64,
    `audioBuffered` Int64,
    `videoBuffered` Int64,
    `maximumAllowedBuffer` Int64,
    `bufferingCounter` Int64,
    `lastAudioDataTime` Int64,
    `lastVideoDataTime` Int64,
    `bufferState` UInt32
)
ENGINE = MergeTree()
ORDER BY timestamp
SETTINGS index_granularity = 8192;

CREATE TABLE wcs.BufferStateTypes
(
    `id` UInt32,
    `type` String
)
ENGINE = MergeTree()
ORDER BY id
SETTINGS index_granularity = 8192;

INSERT INTO wcs.BufferStateTypes VALUES (0, 'BUFFERING'), (1, 'HOLD'), (2, 'TERMINATED'), (3, 'OVERFLOW'), (4, 'PASSTHROUGH');

CREATE DICTIONARY wcs.DictionaryBufferStateTypes (
    `id` UInt16,
    `type` String DEFAULT ''
)
PRIMARY KEY id
SOURCE(CLICKHOUSE(
 host 'localhost'
 port 9000
 user 'default'
 password ''
 db 'wcs'
 table 'BufferStateTypes'
))
LAYOUT(FLAT())
LIFETIME(300);

CREATE TABLE wcs.AudioRecoveryEvent
(
    `timestamp` UInt64,
    `mediaSessionId` String,
    `type` UInt32,
    `rtpTimestamp` UInt64
)
ENGINE = MergeTree()
ORDER BY rtpTimestamp
SETTINGS index_granularity = 8192;

5. Создайте пользователя wcs и дайте ему права на таблицы в базе данных wcs

Code Block
languagebash
themeRDark
cat wcs_clickhouse_users.sql | clickhouse-client -mn
Code Block
languagesql
themeRDark
titlewcs_clickhouse_users.sql
collapsetrue
CREATE USER IF NOT EXISTS wcs IDENTIFIED BY 'wcs';
GRANT ALL ON wcs.* TO wcs WITH GRANT OPTION;

6. Отключите управление пользователями для пользователя default, указав в файле /etc/clickhouse-server/users.xml параметр

Code Block
languagexml
themeRDark
            <access_management>0</access_management>

7. Перезапустите ClickHouse

Code Block
languagebash
themeRDark
systemctl restart clickhouse-server

Настройка ClickHouse для сборок WCS 5.2.1999 и новее

В сборке 5.2.1999 добавлено автоматическое создание БД при подключении определенной версии WCS с определенного IP адреса. Данные о всех БД хранятся в таблице WcsMetadata.metadata

Code Block
languagesql
themeRDark
SELECT *
FROM WcsMetadata.metadata

┌─dbName───────────────────────────────┬─ip────────────┬─hostname──────────────┬─versionNumber─┬─versionHash──────────────────────────────┐
│ test1flashphonercom_192168065_521999 │ 192.168.0.65  │ test1.flashphoner.com │ 5.2.1999      │ 93e39647113e0121dabc4283ef700814c355568f │
│ test2flashphonercom_192168039_521999 │ 192.168.0.39  │ test2.flashphoner.com │ 5.2.1999      │ 93e39647113e0121dabc4283ef700814c355568f │
└──────────────────────────────────────┴───────────────┴───────────────────────┴───────────────┴──────────────────────────────────────────┘

Поэтому для настройки ClickHouse необходимо только создать пользователя и дать ему права на создание Баз данных, таблиц и вставку данных в них

1. Для того, чтобы прослушивать входящие запросы на всех интерфесах сервера, раскомментируйте строку в файле /etc/clickhouse-server/config.xml 

Code Block
languagexml
themeRDark
    <listen_host>::</listen_host>

2. Для того, чтобы создать пользователя, укажите для пользователя default в файле /etc/clickhouse-server/users.xml параметры

Code Block
languagexml
themeRDark
            <access_management>1</access_management>
            <named_collection_control>1</named_collection_control>
            <show_named_collections>1</show_named_collections>
            <show_named_collections_secrets>1</show_named_collections_secrets>

3. Перезапустите ClickHouse

Code Block
languagebash
themeRDark
systemctl restart clickhouse-server

4. Создайте пользователя wcs и дайте ему необходимые права

Code Block
languagebash
themeRDark
cat wcs_clickhouse_users.sql | clickhouse-client -mn
Code Block
languagesql
themeRDark
titlewcs_clickhouse_users.sql
collapsetrue
CREATE USER IF NOT EXISTS wcs IDENTIFIED BY 'wcs';
SET allow_introspection_functions = 1;
GRANT ALL ON *.* TO wcs WITH GRANT OPTION;

5. Отключите управление пользователями для пользователя default, указав в файле /etc/clickhouse-server/users.xml параметр

Code Block
languagexml
themeRDark
            <access_management>0</access_management>

6. Перезапустите ClickHouse

Code Block
languagebash
themeRDark
systemctl restart clickhouse-server

Настройка WCS

Сбор данных в БД ClickHouse включается настройкой, в которой перечисляются типы отправляемых данных

Code Block
themeRDark
rels_enabled=CONNECTION,STREAM,CDN,MEDIA_SESSION

Доступны следующие типы данных:

CONNECTION, STREAM, CDN, MEDIA_SESSION, HLS_SEGMENTER, HLS_STREAM, HLS_CLIENT, MIXER, AUDIO_RECOVERY, _RECOVERY, RTMP_IN_BUFFER

ТипОписание
CONNECTIONСобытия клиенсткой сессии
STREAMСобытия потока
CDNСобытия CDN
MEDIA_SESSIONСобытия медиа сессии
HLS_SEGMENTERДанные о нарезке HLS потоков
HLS_STREAMСобытия HLS  потоков
HLS_CLIENTСтатистика HLS клиентов
MIXERСобытия микшера
AUDIO_RECOVERYСтатистика потерь и восстановления аудиопакетов
RTMP_IN_BUFFER
TypeDescriptionCONNECTIONClient session eventsSTREAMStream eventsCDNCDN eventsMEDIA_SESSIONStream metricsHLS_SEGMENTERHLS stream segment metricsHLS_STREAMHLS stream eventsHLS_CLIENTHLS clients statisticsMIXERMixer events and metricsAUDIO_RECOVERYAudio packets recovery eventsRTMP_IN_BUFFERRTMP incoming streams buffer metrics

...

Статистика буфера входящих RTMP потоков

ClickHouse connection setup in WCS builds before 5.2.1999

ClickHouse server, database address and protocol are set by the following parameters

Code Block
themeRDark
rels_client_type=HTTP
rels_database_address=http://clickhouseserver:8123/wcs?user=wcs&password=wcs

HTTP protocol is recommended and used by default. But it can be switched to JDBC driver if needed

Code Block
themeRDark
rels_client_type=JDBC
rels_database_address=jdbc:clickhouse://clickhouseserver:8123/wcs?user=wcs&password=wcs

ClickHouse connection setup in WCS builds 5.2.1999 and newer

ClickHouse server, user and protocol are set by the following parameters

Code Block
themeRDark
rels_client_type=HTTP
rels_database_address=http://clickhouseserver:8123/wcs?
rels_database_properties=user=wcs&password=wcs

HTTP protocol is recommended and used by default. But it can be switched to JDBC driver if needed

Code Block
themeRDark
rels_client_type=JDBC
rels_databaseclient_address=jdbc:clickhouse://clickhouseserver:8123/wcs?user=wcs&password=wcstype=JDBC

Stop data logging without WCS server restart

...

The data collection for a certain stream is enabled by REST API.

A REST-query should be HTTP/HTTPS POST request as follows:

  • HTTP: http://streaming.flashphoner.com:8081/rest-api/rels/startup
  • HTTPS: https://streaming.flashphoner.com:8444/rest-api/rels/startup

...

  • streaming.flashphoner.com - WCS server address
  • 8081 - the standard REST / HTTP port of the WCS server
  • 8444 - the standard HTTPS port
  • rest-api - the required part of the URL
  • /rels/startup - REST-method to use

REST methods and responses

...

Code Block
languagejs
themeRDark
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: application/json

Return codes

CodeReason
200OK
400Bad request
404Not found
500Internal server error

/rels/find_all

Get the sent data statistics

...

Code Block
languagejs
themeRDark
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: application/json

[
  {
    "type": "CONNECTION",
    "sentBytes": 1989,
    "bitrateKbps": 0,
    "sentEvents": 6,
    "queueEvents": 0
  },
  {
    "type": "STREAM",
    "sentBytes": 70766,
    "bitrateKbps": 0,
    "sentEvents": 73,
    "queueEvents": 1
  },
  {
    "type": "CDN",
    "sentBytes": 0,
    "bitrateKbps": 0,
    "sentEvents": 0,
    "queueEvents": 0
  },
  {
    "type": "MEDIA_SESSION",
    "ids": [
      "d7d6b6e4-b137-461a-8a32-d6abf2b8666e",
      "39cbf770-128a-11ef-b839-d1a1f53f8bd2"
    ],
    "sentBytes": 205794,
    "bitrateKbps": 143,
    "sentEvents": 999,
    "queueEvents": 119
  }
]

Return codes

CodeReason
200OK
404Not found
500Internal server error

/rels/terminate

Stop data collection of the certain type for the certain streams

...

Code Block
languagejs
themeRDark
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: application/json

Return codes

CodeReason
200OK
400Bad request
404Not found
500Internal server error

/rels/terminate_all

Stop the certain types data collection for all the streams

...

Code Block
languagejs
themeRDark
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: application/json

{
  "MEDIA_SESSION": [
    "39cbf770-128a-11ef-b839-d1a1f53f8bd2"
  ]
}

Return codes

CodeReason
200OK
400Bad request
404Not found
500Internal server error

Parameters

ParameterDescriptionExamplemediaSessionMEDIA_SESSION

Parameters

ParameterDescriptionExample
mediaSessionMEDIA_SESSION data collection descriptor object"mediaSession": {"frequency":100, "ids":["12345678-0000-1111"]} 
frequencydata collection frequency in ms100
idsMedissesson identifiers list for the streams which data should be collected["12345678-0000-1111","12345678-3333-4444"]
hlsSegmenterHLS_SEGMENTER data collection descriptor object"hlsSegmenter": {"ids":["stream1"]}
hlsClientHLS_CLIENT data collection descriptor object"
mediaSession
hlsClient": {"
frequency":100,
ids":["stream1"]}
mixerMIXER data collection descriptor object"mixer": {"ids":["12345678-
0000
5555-
1111
6666"]}
 
frequency
audioRecoveryAUDIO_RECOVERY data collection
frequency in ms100idsMedissesson identifiers list for the streams which data should be collected
descriptor object"audioRecovery": {"ids":["12345678-
0000-1111","12345678-3333-4444
7777-8888"]}
hlsSegmenter
rtmpInBuffer
HLS
RTMP_IN_
SEGMENTER
BUFFER data collection descriptor object"
hlsSegmenter
rtmpInBuffer": {"ids":["
stream1
12345678-9999-AAAA"]}
hlsClientHLS_CLIENT data collection descriptor object"hlsClient": {"ids":["stream1"]}mixerMIXER data collection descriptor object"mixer": {"ids":["12345678-5555-6666"]}audioRecoveryAUDIO_RECOVERY data collection descriptor object"audioRecovery": {"ids":["12345678-7777-8888"]}rtmpInBufferRTMP_IN_BUFFER data collection descriptor object"rtmpInBuffer": {"ids":["12345678-9999-AAAA"]}

Data retrieving from DB

...

Data retrieving from DB

Logging data can be retrieved using SQL queries in CliskHouse client

SQL queries examples for WCS builds before 5.2.1999

Code Block
languagesql
themeRDark
select timestamp,ip,sessionId,mediaSessionId,streamName,dictGetString('wcs.DictionaryStreamEvents','type', eventType) as eventType from wcs.StreamEvent where streamName = 'test'
Code Block
languagesql
themeRDark
select timestamp,ip,sessionId,dictGetString('wcs.DictionaryConnectionEvents','type', eventType) as eventType from wcs.ConnectionEvent
Code Block
languagesql
themeRDark
select timestamp,ip,nodeId,dictGetString('wcs.DictionaryCDNEvents','type', eventType) as eventType,eventPayload from wcs.CDNEvent

SQL queries examples for WCS builds 5.2.1999 and newer

Code Block
languagesql
themeRDark
select timestamp,ip,sessionId,mediaSessionId,streamName,dictGetString('wcs.DictionaryStreamEvents','type', eventType) as eventType from wcstest1flashphonercom_192168065_521999.StreamEvent where streamName = 'test'
Code Block
languagesql
themeRDark
select timestamp,ip,sessionId,dictGetString('wcs.DictionaryConnectionEvents','type', eventType) as eventType from wcstest1flashphonercom_192168065_521999.ConnectionEvent
Code Block
languagesql
themeRDark
select timestamp,ip,nodeId,dictGetString('wcs.DictionaryCDNEvents','type', eventType) as eventType,eventPayload from wcstest1flashphonercom_192168065_521999.CDNEvent