Skip to content

Prometheus Metrics

ChannelWatch exposes a standard Prometheus metrics endpoint at /metrics. Every metric carries per-DVR labels so you can build dashboards that show individual server health alongside aggregate totals.

GET /metrics

The endpoint is unauthenticated and returns text in the standard Prometheus exposition format. Point your Prometheus scrape config at it directly:

scrape_configs:
- job_name: channelwatch
static_configs:
- targets: ['channelwatch-host:8501']
scrape_interval: 30s

Every metric includes four labels that identify the DVR it came from:

LabelExample valueDescription
dvr_ida1b2c3d4Stable 8-character ID derived from md5(host:port)[:8]
dvr_nameLiving RoomUser-editable display name
host192.168.1.50DVR host as configured
port8089DVR port as configured

An additional scope label is set to "all" on aggregate series (see below).

MetricTypeDescription
channelwatch_dvr_connectedGauge1 if the DVR task is alive and connected, 0 otherwise
channelwatch_dvr_last_event_seconds_agoGaugeSeconds since the last SSE event or successful poll from this DVR
channelwatch_dvr_task_restarts_totalCounterNumber of times the DVR’s asyncio task has been restarted

channelwatch_dvr_last_event_seconds_ago is the key metric for the readiness probe. When it exceeds staleness_threshold_seconds (default 300), the watchdog marks the DVR unhealthy.

MetricTypeDescription
channelwatch_active_streamsGaugeNumber of active streams on this DVR right now
channelwatch_alerts_sent_totalCounterTotal alerts sent, labeled by dvr_id and alert_type
channelwatch_notification_errors_totalCounterFailed notification deliveries, labeled by dvr_id and provider
MetricTypeDescription
channelwatch_disk_free_bytesGaugeFree disk space reported by this DVR
channelwatch_disk_total_bytesGaugeTotal disk capacity reported by this DVR
channelwatch_disk_free_percentGaugeFree disk space as a percentage
MetricTypeDescription
channelwatch_uptime_secondsGaugeSeconds since ChannelWatch started
channelwatch_config_reloads_totalCounterNumber of hot-reload events since startup

All per-DVR metrics also have an aggregate counterpart with scope="all" and no dvr_id/dvr_name/host/port labels. These aggregate series are kept for backward compatibility with dashboards built before per-DVR labels were introduced.

For example, channelwatch_active_streams{scope="all"} gives the total active stream count across all DVRs. If you only have one DVR, the per-DVR and aggregate values are identical.

ChannelWatch ships a Grafana dashboard JSON file at dev/dashboards/channelwatch-overview.json in the product repository. Import it into Grafana v10+ via Dashboards > Import > Upload JSON file.

The dashboard includes panels for:

  • Per-DVR connection status (green/red status grid)
  • Active streams per DVR (time series)
  • Disk usage per DVR and aggregate (gauge + time series)
  • Recent alert rate (counter delta)
  • Notification delivery errors (counter delta)
groups:
- name: channelwatch
rules:
- alert: DVRStale
expr: channelwatch_dvr_last_event_seconds_ago > 300
for: 2m
labels:
severity: warning
annotations:
summary: "DVR {{ $labels.dvr_name }} has not received events"
description: "Last event was {{ $value | humanizeDuration }} ago"
- alert: DVRDisconnected
expr: channelwatch_dvr_connected == 0
for: 1m
labels:
severity: critical
annotations:
summary: "DVR {{ $labels.dvr_name }} is disconnected"