Flussonic Media Server documentation

Contents

Events API

Events in Flussonic

Flussonic has a system of internal events with routing and handling, and convenient and flexible tools to configure it.

Events are initiated in different parts of the system and can be used in different scenarios.

To configure event-related settings, add into the Flussonic configuration file a directive notify and the option sink where you define the receiver of events:

  • To use your custom handler, specify the path to the handler in sink.
  • To write event to a log file, specify the path to the file in sink.

Then use various options to filter events before they come to a handler or log.

On this page:

Configuring event logging

In addition to the main log, Flussonic allows you to create as many log files as you need and to log events according to your filtering settings.

To write events to a custom file, add the notify directive and use the sink log:// option to specify the file, for example:

notify log_name {
    sink log://log/crash.log;
    verbose debug;
}

Where:

  • log_name — just the setting's name. It's good to give it a meaningful name.
  • sink — the file where event information is logged.
  • verbose — the level of logging according to event importance. Can be debug (the most detailed logging), info, or alert (only serious events).

Excluding events from logs

To exclude some types of events, use the except option. For example, the following configuration will not write to the log all events concerning streams (and write other events, such as Flussonic server events):

notify log_name {
    sink log://log/crash.log;
    except media=*;
    verbose debug;
}

Configuring event handlers

Each event handler can be declared in config:

notify handler_name {
    sink http://backend.local/notify.php;
}

Such configuration creates an event handler with the name handler_name and it sends ALL events to

HTTP URL http://backend.local/notify.php.

In this configuration all Flussonic events will be send in JSON format as a list of objects. On a high loaded system it can generate enormous amount of events most of which are not required.

We can reduce event traffic by better configuration:

notify handler_name {
    sink http://backend.local/notify.php;
    only event=stream_started,stream_stopped,source_ready,source_lost;
}

This configuration will send only four specific events to this handler.

Event handler calls are synchronous: an event will not be sent to the handler if the handler hasn't handled the previous event batch.

The event configuration block supports the following configuration options:

sink
The specification of the handler. It can be http://URL, https://URL, path_to_lua_script.lua
<dt>only</dt>
<dd>The white list of limitations. You can specify several <code>key=value</code>  or <code>key=value1,value2</code> options on each <code>only</code> line.
You can filter events by their <code>event</code> field, by <code>media</code> field or any other like <code>country</code> or <code>ip</code>.
Usually it is <code>event</code> and <code>media</code>. You should read more explicit explanation of this <code>only</code> behaviour.</dd>

<dt>except</dt>
<dd>The black list of limitations. Events matched by any of <code>except</code> fields will not be passed to handler.</dd>

<dt>buffer</dt>
<dd>Not recommended.</dd>

All other configuration options in this block will be passed to the specified sink handler. In a LUA script they can be accessed via the args table. When using HTTP backend you pass them along with other parameters.

Here goes some extra configuration options:

sign_key
You can specify signature key for HTTP event sink. When Flussonic will prepare HTTP POST with JSON body, it will add this secret key to then end of body, make SHA1 hash from it and add it in hex form as a header X-Signature. This can be used for verifying that it is a Flussonic posting events.

Event filtering

You can pre-filter events before passing them to handlers. It is very important mechanism, try to use it, because it reduce load on your event handler. Each event is prefiltered in the emitter thread before being passed to handler.

Here goes rules for filtering:

  • if ANY except directive fully matches event, it is dropped and not sent to handler;
  • if there are no only directives, events are sent to handler;
  • if there are only directive then event is passed to handler if ANY directive fully matches the event.

Full match of event and directive means that ALL key=value pairs in directive are equal to values in event. If directive has key=value1,value2,value3 pair, then it means that event MUST have ANY of these values to match this directive.

Examples:

  • only event=stream_started; matches {event: "stream_started", media: "cbc"}
  • only event=stream_started,stream_stopped; matches {event: "stream_started", media: "cbc"}
  • only event=stream_started,stream_stopped media=tnt; NOT matches {event: "stream_started", media: "cbc"}
  • only event=stream_started media=cbc group=news; NOT matches {event: "stream_started", media: "cbc"}

The list of available events

Here is a list of known events:

server_started
The server has started
<dt>listener_start</dt>
<dd>Flussonic starts listening on some port</dd>

<dt>listener_failure</dt>
<dd>Flussonic failed to listen on a port</dd>

<dt>config_reloaded</dt>
<dd>The configuration was reloaded</dd>

<dt>session_opened</dt>
<dd>A session was opened</dd>

<dt>session_closed</dt>
<dd>A session was closed</dd>

<dt>file_opened</dt>
<dd>A file was opened</dd>

<dt>file_closed</dt>
<dd>A file was closed</dd>

<dt>stream_started</dt>
<dd>A stream has started</dd>

<dt>stream_stop</dt>
<dd>A stream has received the command to stop via API</dd>

<dt>stream_stopped</dt>
<dd>A stream was stopped</dd>

<dt>stream_reconfigured</dt>
<dd>A stream configuration was updated</dd>

<dt>stream_motion_started</dt>
<dd>(Applies to IP cameras) Detected motion has started</dd>

<dt>stream_motion_stopped</dt>
<dd>(Applies to IP cameras) Detected motion has stopped</dd>

<dt>source_ready</dt>
<dd>A stream has received first video frames</dd>

<dt>stream_media_info</dt>
<dd>Stream attributes (media_info) were changed</dd>

<dt>source_lost</dt>
<dd>The stream source is considered to be lost and the stream needs restarting</dd>

<dt>source_switch</dt>
<dd>A stream has switched to another source</dd>

<dt>frames_timed_out</dt>
<dd>A stream's source has stopped sending frames (but it is not restarted yet)</dd>

<dt>frames_restored</dt>
<dd>A stream's source has resumed sending frames</dd>

<dt>stream_backup</dt>
<dd>A backup file has started playing while the source is lost</dd>

<dt>publish_started</dt>
<dd>Publishing to a stream has started</dd>

<dt>publish_stopped</dt>
<dd>Publishing to a stream has finished (you can get a lot of valuable information with this event)</dd>

<dt>push_started</dt>
<dd>A stream has started sending video (push) to another source </dd>

<dt>stream_jpeg</dt>
<dd>A new JPEG thumbnail has been generated</dd>

<dt>dvr_new_fragment</dt>
<dd>The next fragment of the DVR archive was recorded on disk</dd>

<dt>dvr_deleted_fragments</dt>
<dd>Old fragments were purged from the DVR archive</dd>

<dt>dvr_new_blob</dt>
<dd>A new one-hour interval was opened for recording video to DVR</dd>

<dt>stream_force_close_gop</dt>
<dd>Stream error: invalid timestamps are coming or too low FPS</dd>

<dt>stream_rt_sync</dt>
<dd>A stream had to resync timestamps. This might be the indication of stream errors if happens too often.</dd>

<dt>stream_broken_source</dt>
<dd>Flussonic failed to read a stream from the source and restarted the stream</dd>

<dt>dvr_replication_started</dt>
<dd>DVR replication has started</dd>

<dt>dvr_hour_replication_started</dt>
<dd>Replication of a DVR one-hour interval has started</dd>

<dt>dvr_hour_replication_done</dt>
<dd>Replication of a DVR one-hour interval was completed</dd>

<dt>dvr_replication_progress</dt>
<dd>DVR replication is in progress</dd>

<dt>dvr_replication_done</dt>
<dd>DVR replication was completed</dd>

<dt>udp_pusher_does_not_fit_cbr</dt>
<dd>A stream that you send via <a href="/doc/video-playback/udp-multicast-with-constant-bitrate#configuration" orig="play/cbr-udp#configuration">UDP with constant bitrate</a> (using the configuration <code>push udp://IP_ADDRESS?cbr=...</code>) has a too high bitrate that can cause buffer overflow. As a result, a stream error or stream restart can occur. To avoid this, you can transcode the stream into smaller bitrate.</dd>     

Examples of configuring email notifications

Let's learn what you can do with events system. For example, let's receive email notifications if a stream is down.

The simplest configuration will be:

notify no_video {
    only event=stream_stopped,source_lost;
    sink /etc/flussonic/no_video.lua;
    from flussonic@streamer1.my.cdn;
    to admin@my.cdn;
    via smtp://127.0.0.1:587;
}

This configuration is enough unless you want to filter streams here.

What no_video.lua can do:

body = "Source lost on following streams: \n"

for _, event in pairs(events) do
    body = body.."  "..event.media.."\n"
end

mail.send({from = args.from, to = args.to, subject = "Source lost", body = body})

You need to install the Sendmail utility to send mail correctly:

apt-get install sendmail

Make sure that Sendmail listens on the port specified in the configuration file:

netstat -lntp
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name          
tcp        0      0 127.0.0.1:587           0.0.0.0:*               LISTEN      3507/sendmail

Specify REAL domain name as the hostname of the server:

hostname
streamer1.my.cdn

Performance-related events

The Flussonic’s event system allows setting up notifications on resource consumption and performance issues.

The events busy_port, busy_dist_port, long_gc, long_schedule_pid, and long_schedule_port are those of the Erlang’s system monitor. Refer to the Erlang documentation for their description, cases when each of them occurs, and what parameters they pass. These events can indicate performance problems.

In Flussonic, all these events belong to the system_overloaded group. The group of events is specified with the group keyword.

Sample configuration:

notify performance_handler {
    sink http://backend.local/notify.php;
    only group=system_overloaded;
}

In this example, the group=system_overloaded filter passes only the performance problems events to the handler.

Memory usage

The memory_usage event occurs when memory is used exceedingly. The event has the parameters total and used , in bytes. Flussonic sends this event when it uses more than half of all available memory. When the 80% threshold is exceeded, the event is fired with the system_overloaded group.

Reliable delivery of event notifications

To prevent notications loss, you can set up Flussonic for postponed attempts to resend notifications. If the receiving HTTP server or script does not respond, Flussonic accumulates events in a special buffer and periodically retries sending them. When the receiving server responds, Flussonic will send all the accumulated notifications.

For this, specify two options in the configuration file:

notify watcher {
   sink http://backend.local/notify.php;
   resend_notifications_limit 1000;
   resend_notifications_timeout 10;
}

where:

  • resend_notifications_limit — the number of the most recent events that will be stored in order to retry sending them. Cannot exceed 2000.
  • resend_notifications_timeout — the time interval, in seconds, over which Flussonic will try to send events again.