Connecting external monitoring systems¶
pss-metrics — a universal metrics exporter for Perfect Streamer
A single Python 3 CLI script that retrieves statistics from the HTTP API of the PSS web server and produces output for the most common monitoring systems:
Zabbix (UserParameter, Low-Level Discovery, zabbix_sender trapper)
Prometheus (text exposition format for the textfile collector)
InfluxDB / Telegraf (line protocol or JSON for the exec input)
Generic JSON for custom scripts and Nagios-style health checks
The exporter needs no third-party dependencies: it uses only the Python 3.6+ standard library (urllib, xml.etree, json, argparse).
Files¶
pss-metrics.py main CLI (executable)
userparameter_pss.conf.example UserParameter template for Zabbix
Installation¶
The exporter is shipped as /opt/pss/monitoring/pss-metrics.py. Make sure that Python 3.6 or later is installed:
# RHEL / Rocky / AlmaLinux
yum install -y python3
# Debian / Ubuntu
apt-get install -y python3
No additional packages are required.
Configuration¶
By default, pss-metrics connects to the node over the loopback address and determines the web server port from /opt/pss/config/pss.json. If that file can be read, it decides: the port comes from its web-server.bind-port key, and without that key it is 43971, the built-in value of the service. The file /opt/pss/config/pss_default.json is read only if there is no pss.json; if the port could not be read from either file, http://127.0.0.1:43971 is used. With the -v flag, the exporter reports which file the port was taken from. The parameters can be overridden with environment variables, the /etc/pss-metrics.conf file (key=value format) or command-line flags. Priority: CLI > env > file > defaults. PSS_URL set in any of these ways turns port auto-detection off. Before version 2.0.2.421, PSS_URL from the file did not turn auto-detection off, and a pss.json without a port key led to port 8808 from pss_default.json.
Since version 2.0.2.420, pss.json is readable only by the pss service user (the file holds passwords). An exporter run as another user (zabbix, telegraf) cannot read the port from the file and connects to port 43971; if the node’s web server runs on another port, set PSS_URL.
Supported variables:
PSS_URL full URL, e.g. http://10.0.0.1:8808 (auto by default)
PSS_USER login sent as HTTP Basic (for a proxy in front of PSS, see below)
PSS_PASS password for PSS_USER
PSS_TIMEOUT HTTP timeout, in seconds (default 5)
PSS_CACHE_DIR cache directory (default /run/pss-metrics)
PSS_CACHE_TTL cache TTL, in seconds (default 10)
PSS_CA_BUNDLE path to CA bundle for HTTPS
PSS_INSECURE 1 — disable TLS certificate verification
PSS_VERBOSE 1 — log requests to stderr
Caching: each run performs at most one HTTP GET per endpoint within the TTL window. With TTL=10 s, even hundreds of UserParameter checks per minute result in about 6 HTTP requests per minute to each API endpoint.
Quick start¶
Health check (Nagios-style exit codes):
pss-metrics.py health
# OK: total=42 running=15 stopped=27 unhealthy=0 version=<version>
Zabbix LLD discovery:
pss-metrics.py discover streams
pss-metrics.py discover inputs --running-only
pss-metrics.py discover outputs
Retrieving a single metric (for use in a Zabbix UserParameter):
pss-metrics.py get summary.running
pss-metrics.py get stream.10031.bitrate
pss-metrics.py get input.10031.1.speed1
pss-metrics.py get output.10031.1.speed
pss-metrics.py get sysmon.cpu.self-usage
pss-metrics.py get server.server-version
Full export:
pss-metrics.py dump --format=json
pss-metrics.py dump --format=prometheus
pss-metrics.py dump --format=influx
pss-metrics.py dump --format=zabbix-trapper --zabbix-host=streamer-01
Metric paths¶
pss-metrics get accepts a dot-separated path. Empty output means “no value” (for example, the metric exists only for running streams).
server.<attr> e.g. server.server-version, server.uptime
summary.<key> total | running | stopped | unhealthy |
input_bitrate_kbps | output_bitrate_kbps
sysmon.cpu.<attr> self-usage | total-usage | cores
sysmon.memory.<attr> self-usage-kb | available-kb | total-kb
sysmon.netbw.<iface>.<attr> rx-bw | tx-bw (interface name as in XML)
stream.<id>.<attr> any <stream> attribute
input.<sid>.<iid>.<attr> any <input> attribute
output.<sid>.<oid>.<attr> any <output> attribute
Useful per-stream attributes (from /data/stream/detail):
stream: state, state-str, bitrate, thread-usage, mpts
input: speed1, recv-bytes, recv-packets, recv-err,
stat-disc, stat-disc1, stat-scrambled, stat-scrambled1,
health-state-good, health-status, check-status
output: speed, sent-bytes, sent-packets, sent-err, uri, type
The rates are given in kilobits per second: speed1 on an input, speed on an output. The speed attribute exists only on UDP outputs; for the other output types the rate is derived from the increment of sent-bytes over your own polling interval.
Zabbix integration¶
Two scenarios are supported; choose the one that suits your environment.
Static UserParameter + LLD (Zabbix agent v1 / v2)
Copy userparameter_pss.conf.example to /etc/zabbix/zabbix_agentd.d/pss.conf, restart zabbix-agent and import on the server a template with LLD prototypes that use the pss.discover keys. Example bindings:
UserParameter=pss.discover[*],/opt/pss/monitoring/pss-metrics.py discover $1 UserParameter=pss.get[*],/opt/pss/monitoring/pss-metrics.py get $1 UserParameter=pss.health,/opt/pss/monitoring/pss-metrics.py health
On the Zabbix server:
Discovery rule key: pss.discover[streams] Item prototype keys: pss.get[input.{#STREAM_ID}.1.speed1] pss.get[stream.{#STREAM_ID}.bitrate] pss.get[summary.unhealthy]Trapper (push) via zabbix_sender
Run it on a timer (cron / systemd) and pipe the output:
/opt/pss/monitoring/pss-metrics.py dump --format=zabbix-trapper \ --zabbix-host="$(hostname)" \ | zabbix_sender -z zabbix.example.com -i -
Prometheus integration¶
Two options.
Textfile collector (recommended for one-shot environments).
Run a periodic export via a systemd timer or cron:
*/1 * * * * /opt/pss/monitoring/pss-metrics.py dump --format=prometheus \ > /var/lib/node_exporter/textfile_collector/pss.prom.$$ \ && mv /var/lib/node_exporter/textfile_collector/pss.prom.$$ \ /var/lib/node_exporter/textfile_collector/pss.promnode_exporter will serve the file via –collector.textfile.directory.
Direct scraping through a small wrapper (for example, socat + pss-metrics dump) or any third-party HTTP proxy of your choice.
Telegraf / InfluxDB integration¶
Telegraf inputs.exec:
[[inputs.exec]]
commands = ["/opt/pss/monitoring/pss-metrics.py dump --format=influx"]
interval = "10s"
timeout = "5s"
data_format = "influx"
For the JSON parser, use –format=json and configure data_format = “json”, specifying the field paths.
HTTPS and authentication¶
The exporter is intended to run on the node itself: the PSS web server accepts requests from the local address without authorisation. The PSS_USER/PSS_PASS variables are passed as HTTP Basic credentials, which are useful when access to the API is published through an intermediate proxy with Basic authorisation; the exporter does not pass the PSS web server’s own Digest authorisation.
Access over HTTPS:
PSS_URL=https://streamer.example.com:43981 pss-metrics.py health
Self-signed certificates: set PSS_INSECURE=1 (not recommended) or specify PSS_CA_BUNDLE=/path/to/ca.pem.
Exit codes¶
pss-metrics follows the Nagios convention:
0 OK
1 WARNING (e.g. running streams report unhealthy)
2 CRITICAL (PSS is unreachable)
3 UNKNOWN (invalid arguments / internal error)
get prints an empty string and exits with code 0 if the requested entity does not exist: Zabbix treats an empty value as “NOT_SUPPORTED” rather than as an agent failure.
Troubleshooting¶
pss-metrics.py -v health # log every HTTP request to stderr
pss-metrics.py --cache-ttl=0 … # bypass cache while debugging
rm -rf /run/pss-metrics # purge cache