76 lines
2.6 KiB
Go
76 lines
2.6 KiB
Go
|
|
package prometheus
|
||
|
|
|
||
|
|
import (
|
||
|
|
// Hybrid instrumentation rationale: direct client_golang instrumentation
|
||
|
|
// lives in app/webrtc/metrics.go (hot-path counters and histograms);
|
||
|
|
// this file owns the snapshot-style gauges. See the design doc at
|
||
|
|
// docs/design/2026-05-03-datarhei-dragon-fork-webrtc-prometheus-metrics-design.md.
|
||
|
|
"github.com/prometheus/client_golang/prometheus"
|
||
|
|
)
|
||
|
|
|
||
|
|
// WebRTCStats is a point-in-time snapshot of the WebRTC subsystem state.
|
||
|
|
// Populated by Handler.Stats() in app/webrtc and consumed by the collector
|
||
|
|
// at scrape time.
|
||
|
|
type WebRTCStats struct {
|
||
|
|
StreamCount int
|
||
|
|
PeersByStream map[string]int
|
||
|
|
UDPPortsInUse int
|
||
|
|
}
|
||
|
|
|
||
|
|
// WebRTCStatsSource is implemented by app/webrtc.Handler (via its Stats()
|
||
|
|
// method). The interface lives here so prometheus/ does not import app/webrtc,
|
||
|
|
// keeping the dependency arrow one-directional.
|
||
|
|
type WebRTCStatsSource interface {
|
||
|
|
Stats() WebRTCStats
|
||
|
|
}
|
||
|
|
|
||
|
|
type webrtcCollector struct {
|
||
|
|
core string
|
||
|
|
source WebRTCStatsSource
|
||
|
|
|
||
|
|
activeStreamsDesc *prometheus.Desc
|
||
|
|
activePeersDesc *prometheus.Desc
|
||
|
|
udpPortsInUseDesc *prometheus.Desc
|
||
|
|
}
|
||
|
|
|
||
|
|
// NewWebRTCCollector returns a prometheus.Collector that emits three gauge
|
||
|
|
// metrics at scrape time by calling source.Stats(). Register it with the
|
||
|
|
// shared Metrics registry before the /metrics endpoint starts serving.
|
||
|
|
func NewWebRTCCollector(core string, source WebRTCStatsSource) prometheus.Collector {
|
||
|
|
cl := prometheus.Labels{"core": core}
|
||
|
|
return &webrtcCollector{
|
||
|
|
core: core,
|
||
|
|
source: source,
|
||
|
|
activeStreamsDesc: prometheus.NewDesc(
|
||
|
|
"dragonfork_webrtc_active_streams",
|
||
|
|
"Streams currently registered (processes with webrtc.enabled=true running).",
|
||
|
|
nil, cl,
|
||
|
|
),
|
||
|
|
activePeersDesc: prometheus.NewDesc(
|
||
|
|
"dragonfork_webrtc_active_peers",
|
||
|
|
"Currently subscribed WHEP peers per stream.",
|
||
|
|
[]string{"stream_id"}, cl,
|
||
|
|
),
|
||
|
|
udpPortsInUseDesc: prometheus.NewDesc(
|
||
|
|
"dragonfork_webrtc_udp_ports_in_use",
|
||
|
|
"UDP ports currently allocated (2 per active stream).",
|
||
|
|
nil, cl,
|
||
|
|
),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func (c *webrtcCollector) Describe(ch chan<- *prometheus.Desc) {
|
||
|
|
ch <- c.activeStreamsDesc
|
||
|
|
ch <- c.activePeersDesc
|
||
|
|
ch <- c.udpPortsInUseDesc
|
||
|
|
}
|
||
|
|
|
||
|
|
func (c *webrtcCollector) Collect(ch chan<- prometheus.Metric) {
|
||
|
|
stats := c.source.Stats()
|
||
|
|
ch <- prometheus.MustNewConstMetric(c.activeStreamsDesc, prometheus.GaugeValue, float64(stats.StreamCount))
|
||
|
|
ch <- prometheus.MustNewConstMetric(c.udpPortsInUseDesc, prometheus.GaugeValue, float64(stats.UDPPortsInUse))
|
||
|
|
for streamID, count := range stats.PeersByStream {
|
||
|
|
ch <- prometheus.MustNewConstMetric(c.activePeersDesc, prometheus.GaugeValue, float64(count), streamID)
|
||
|
|
}
|
||
|
|
}
|