Monitoring and health signals
Monitoring and health signals
Systematic reference for what to observe on a Pixop Prime appliance, how shipped tooling interprets those observations, and what automatic remediation may do. This page separates signals (read-only facts) from actions (mutating recovery). Pair with Monitoring and troubleshooting for the short diagnostic flow and Incident response runbook for step-by-step faults.
Version gate: parameters below match /etc/pixop-live/healthcheck.env and pixop-healthcheck on qualified appliances. Timer and recover behavior can differ by recipe; confirm with pixop-preflight, systemctl status pixop-healthcheck.timer, and pixop-version.
Signal taxonomy
Signals are grouped from the host upward. Use the lowest layer that explains the symptom before opening HTTP or restarting services.
Layer A — Hypervisor (KVM only)
| Signal | Command | Operational fact |
|---|---|---|
| KVM / IOMMU / memlock | cd extract root; sudo ./scripts/pixop-install doctor on Ubuntu host | Host-side; guest tools cannot validate VFIO |
| GPU bound to VM | sudo ./scripts/pixop-install status while domain running | Expect vfio-pci on passed-through devices |
Guest signals below apply to AWS and KVM alike.
Layer B — Host VM (Amazon Linux 2023 guest)
| Signal | Tool | Pass / concern |
|---|---|---|
| OS + driver branch | pixop-preflight | Expect AL2023; NVIDIA open kernel module; some recipes target driver branch 610 (preflight warns on other branches — compare against your qualified image) |
| GPU runtime | nvidia-smi (via preflight) | Operational nvidia-smi and Docker nvidia runtime |
| Container images | preflight LIVE_IMAGE / TSDUCK_IMAGE | Digest-pinned images present locally |
| Kernel UDP buffers | preflight sysctl | net.core.rmem_max / wmem_max = 268435456 |
| Init completion | file /var/lib/pixop-live/instance-init.complete | When absent, many checks are intentionally lenient |
pixop-preflight exit codes (observable today): 0 = no FAIL; 1 = one or more FAIL. Warnings (e.g. missing license.jwt before KVM licensing) are not failures. The script header documents exit 2 for usage errors, but the installed no-argument CLI path currently ends at 0 or 1 only.
Ephemeral write probes: preflight uses setpriv as UID 1001 to prove write access under /var/lib/pixop-live/parameters and removes /.pixop-uid1001-write-probe — it does not leave probe files on success.
Layer C — systemd units
| Unit | Role | Healthy signal |
|---|---|---|
docker.service | Container runtime | active |
pixop-instance-init.service | First-boot enablement (AWS) | completed; marker file present |
pixop-live.service | Pixop LIVE container | active when stack started |
[email protected] | Primary SRT ingest | active; bind per transport policy |
[email protected] | Primary SRT egress | active; bind per transport policy |
pixop-healthcheck.timer | Schedules oneshot diagnostic | enabled and active on launched appliances |
pixop-healthcheck.service | Oneshot (not enabled directly) | triggered by timer |
Operational fact: tsduck-in@main is not PartOf / Requires pixop-live — ingest can stay up across Pixop-only restarts.
pixop-stack status aggregates pixopctl status and tsduckctl status-all.
Layer D — UDP / SRT transport
Two different questions:
- Is the appliance listening (or caller-ready)? —
tsduckctl check NAME [--type in|out] - Are bytes moving on the wire? —
pixop-flow(requires root/tcpdump; samples 1–30 s, default 2 s)
Bind check (operational fact): prefer tsduckctl check NAME (uses ss plus relay/native policy). When installed, tsduckctl transport NAME or the standalone tsduck-transport-info helper adds bind/backend detail. Native-only recipes may lack the tsduck-transport-info helper — tsduckctl transport may still be present but fails without the helper; fall back to check, ss -ulnp, and instance env under /etc/pixop-live/tsduck/ (do not paste secrets from env files into tickets). For health_check=srt-udp, the primary ingest/egress ports (defaults 5000 / 5001 unless env overrides) must be bound when the unit is active. For srt-caller, UDP listener checks are not applicable.
Reachability (peer connected, firewall open, correct passphrase) is not proven by bind checks or pixop-preflight — external path testing belongs in Transport troubleshooting.
Layer E — Internal on-guest multicast TS backbone
Defaults from /etc/pixop-live/network.env (239.0.0.x UDP multicast on the guest — not the kernel loopback interface, not customer WAN):
| Stage | Default | pixop-flow column |
|---|---|---|
| Ingress → Pixop tap | 239.0.0.1:5500 | Ingress -> Pixop |
| Pixop replacement | 239.0.0.1:5501 | Pixop -> replacement |
| Merged output | 239.0.0.1:5600 | Final merged TS |
Operational fact: pixop-flow exit 0 when measurement succeeds and tap rate is below TS_TARGET_BITRATE (default 50000000 bps in shipped network.env). Exit 3 = at or above backbone capacity at the tap measurement point. Exit 10 = capture failure. Idle source → 0.00 Mbps with exit 0.
Rates are UDP payload Mbps; SRT stages include protocol overhead and retransmissions.
Layer F — Pixop processing (HTTP)
Pixop LIVE serves local HTTP on port PIXOP_METRICS_PORT (default 8080).
| Endpoint | Format | Typical use |
|---|---|---|
/v1/metrics.json | JSON | Parsing, healthcheck, monitoring integrations |
/v1/metrics | Prometheus text | pixopctl health, legacy fallbacks |
/v1/control/status | JSON | Pipeline control state |
Security (operational fact): services bind on the appliance network namespace (--network host for the container). Local curl to 127.0.0.1:8080 is typically unauthenticated. When REST API auth is configured (NVEnc restapi.yaml — Basic password and/or Bearer token), the same routes may reject anonymous scrapes; external monitors need management network reachability plus configured credentials. Recommendation: restrict 8080 to management VLAN/VPC; never expose it to untrusted networks.
Operational vs control state: JSON status / operationalState (metrics) describe runtime health; /v1/control/status state (e.g. awaiting_job) describes pipeline control — healthcheck treats awaiting_job and zero-frame idle as non-failure even when metrics look alarming.
Fields used by pixop-healthcheck (verified in script)
pixop-healthcheck (verified in script)These are the only JSON/control fields appliance auto-recovery relies on:
| Source | Field | Use |
|---|---|---|
/v1/metrics.json | status | OK, DEGRADED, ERROR classification |
operationalState | Logged on failure | |
input.framesTotal | Zero frames + zero errors → idle | |
realtime.libavErrors.total | Decoder error gate for idle vs bad | |
/v1/control/status | state | awaiting_job → idle |
inputMode | Log context |
Prometheus fallback (when JSON missing): pixop_system_status gauge (≥2 → ERROR, 1 → DEGRADED), and first pixop_*input*frames_total for frame count.
The JSON document can include additional sections (output, processing, uptimeSeconds, version, etc.) when runtime metrics exist — see the version-appropriate API reference and metrics schema for your appliance build (match pixop-version to Pixop release notes). Do not build alerts on field names you have not verified on your build; scrape once on a known-good feed and diff against this list.
Example read-only commands:
pixopctl health
curl -sS --max-time 3 http://127.0.0.1:8080/v1/metrics.json | python3 -m json.tool | head -n 40
curl -sS --max-time 3 http://127.0.0.1:8080/v1/control/status | python3 -m json.toolpixopctl health hits /v1/metrics (Prometheus), not JSON — suitable for a quick liveness glance, not full parsing.
Layer G — Application logs
| File / command | Content |
|---|---|
/var/log/pixop-live/live.log | TERMINAL-format Pixop/NVEnc diagnostics |
pixopctl logs | journalctl -u pixop-live (lifecycle + stderr routing) |
/var/log/pixop-live/tsduck-in-main.log | TSDuck ingest |
/var/log/pixop-live/tsduck-out-egress-main.log | TSDuck egress |
pixop-pack-logs and support bundles include rotated excerpts — pixop-support-bundle.
pixop-flow reference
pixop-flow referencepixop-flow
pixop-flow --secs 5 # 1..30 inclusiveRe-invokes via sudo from the installed path (do not run sudo pixop-flow as a different path). If /var/lib/pixop-live/instance-init.complete is missing, output notes startup may be incomplete.
pixop-healthcheck timer policy
pixop-healthcheck timer policyScheduling (systemd)
| Parameter | Value | Meaning |
|---|---|---|
OnBootSec | 30s | First run after boot |
OnUnitActiveSec | 15s | Repeat interval while timer active |
AccuracySec | 5s | Timer coalescing window |
Persistent | false | Missed runs while powered off are not backfilled |
Enablement (operational fact): Shipped appliances enable pixop-healthcheck.timer during provisioning; pixop-instance-init runs systemctl enable --now pixop-healthcheck.timer on first AWS boot. Preflight FAIL if the timer is disabled on a launched appliance.
Thresholds (/etc/pixop-live/healthcheck.env)
/etc/pixop-live/healthcheck.env)| Variable | Default | Role |
|---|---|---|
PIXOP_HEALTHCHECK_RESTART | 1 | Allow pixopctl recover |
GRACE_SECS | 120 | Skip checks after pixop-live entered active |
BAD_CONSECUTIVE | 3 | Failed observations before recover |
NO_METRICS_RESTART_AFTER_SECS | 180 | Missing metrics tolerance |
RESTART_COOLDOWN_SECS | 120 | Minimum time between recoveries |
JITTER_SECS | 0 | Optional random delay |
Timer interval vs detection: the timer fires about every 15 s (OnUnitActiveSec=15, AccuracySec=5 coalescing, OnBootSec=30), but one bad tick alone does nothing. Elapsed time to recover depends on grace, how many consecutive bad ticks accumulate, cooldown, and startup — not a fixed “45 s” product SLA.
Classification rules (operational fact)
Each timer run evaluates one failed observation when either:
- Metrics present, not idle:
status=ERROR(from JSON, or Prometheuspixop_system_status≥ 2) while not in idle/awaiting_jobgate, or - Metrics absent: both JSON and Prometheus fetches empty, and wall time since last good metrics fetch exceeds
NO_METRICS_RESTART_AFTER_SECS(180 s default).
These are alternatives — not a requirement for both ERROR and missing metrics on the same tick.
- Skips entirely if
pixop-liveinactive (exit 0). - Idle:
pipeline_state=awaiting_job, orframes_total=0withlibav_errors_total=0— even ifstatus=ERROR, no restart (bad counter cleared). DEGRADED: logged; no restart; clears consecutive bad count like a good tick.- Recover action: after
bad_count >= BAD_CONSECUTIVE(3), subject toRESTART_COOLDOWN_SECS—pixopctl recoveronly; healthcheck timer keeps running; nodocker restart.
State directory: /var/lib/pixop-live/health/ (last_ok, bad_count, last_restart).
Missing-metrics limitation (not a product guarantee): when both endpoints are empty, last_ok is read from disk; if missing, the script uses current time as last_ok. Metrics that have never responded successfully since boot therefore do not advance the 180 s missing timer by themselves — monitor /v1/metrics.json availability externally if you need that guarantee.
Action warning: running /opt/pixop/bin/pixop-healthcheck manually can recover when thresholds are met — prefer read-only tools for routine checks.
What to monitor over time
Pixop does not ship a single “golden threshold” document for every deployment. Recommendation: baseline your own environment during a known-good rehearsal:
| Signal | Suggestion |
|---|---|
pixop-flow stage Mbps | Baseline each printed stage during rehearsal with your encoder on |
input.framesTotal / output.framesTotal in JSON | Trend while on-air (compare to your own baseline — field names vary by build) |
realtime.libavErrors.total | Investigate sustained rises during active video before hard-alerting |
pixop-flow Ingress -> Pixop utilization % | Near 100% of TS_TARGET_BITRATE correlates with exit 3 / drops |
| Healthcheck journal | Spikes in recovering pixop-live |
| GPU | nvidia-smi utilization/temperature via external monitor or bundle snapshots |
Use your NOC’s standard SRT metrics (RTT, loss, bandwidth) on encoders/decoders — the appliance does not replace peer-side monitoring.
Mutating helpers (signals vs actions)
| Command | Read-only? | Effect |
|---|---|---|
tsduckctl detect-video-pid main | Yes | Reports PIDs from tap |
tsduckctl detect-video-pid main --apply | No | Updates ORIGINAL_VIDEO_PID / INPUT_PCR_PID, restarts ingress |
tsduckctl tune-latency main | Yes | Reports PIPELINE_LATENCY vs pixop-timing-probe --json |
tsduckctl tune-latency main --apply | No | Writes latency (200–1500 ms envelope), restarts ingress |
pixopctl recover | No | Ingress stop + Pixop restart + ingress start |
pixop-timing-probe | Yes (capture) | Timing alignment integer / --json diagnostics on stderr |
See tsduckctl, pixop-timing-probe.
Host faults outside the media path
Use read-only checks first; deeper transport steps live in Transport troubleshooting and Incident response runbook.
pixop-live inactive or crash loop
pixop-live inactive or crash loop| Observation | Safe read-only step | Outage / action |
|---|---|---|
pixop-stack status shows pixop-live failed | systemctl status pixop-live.service; journalctl -u pixop-live.service -b --no-pager | tail -n 80 | Ingest may still be up (tsduck-in@main independent). Fix Pixop layer: pixopctl restart (SRT ingest stays up) or support-directed pixop-stack restart |
Rapid Restart=always in journal | tail -n 100 /var/log/pixop-live/live.log; pixop-preflight | Do not docker restart pixop-live. Capture bundle before repeated pixop-stack restart |
pixop-healthcheck exits 0 when pixop-live is inactive — it does not start the unit.
Docker daemon failed
| Observation | Safe read-only step | Outage / action |
|---|---|---|
pixop-preflight FAIL on Docker; no containers | systemctl status docker.service; journalctl -u docker.service -b --no-pager | tail -n 40 | Full pipeline down until Docker is healthy — operator repair is host-level; then pixop-stack start |
Log or disk pressure
| Observation | Safe read-only step | Outage / action |
|---|---|---|
| Writes fail; bundle errors | df -h; du -sh /var/log/pixop-live /var/lib/pixop-live | Rotate or archive logs per your policy; avoid deleting active *.log without support guidance. Full disk can prevent clean shutdown |
Secondary TSDuck instances (when configured): pixop-stack status and tsduckctl status-all — recover only the named instance if evidence points there.
Cross-reference table
| Question | Tool |
|---|---|
| Is the AMI layout correct? | pixop-preflight |
| Are units up? | pixop-stack status, systemctl |
| Is SRT listener ready? | tsduckctl check |
| Is TS moving internally? | pixop-flow |
| Is Pixop processing? | /v1/metrics.json, live.log |
| Did auto-heal fire? | journalctl -u pixop-healthcheck.service |
| Cold start timing? | pixop-startup-timeline |
Related
Updated about 8 hours ago
