feat(promunifi): add unifi_controller_up gauge metric (closes #356) (#974)

Add a per-controller `<namespace>_controller_up` Prometheus GaugeVec with
a `source` label (controller URL or configured ID). The gauge is set to 1
after each successful poll and 0 on failure, giving operators a standard
metric to alert on controller connectivity issues.

Changes:
- pkg/poller/config.go: add ControllerStatus type and ControllerStatuses
  field to Metrics so any output plugin can consume per-controller health.
- pkg/poller/inputs.go: merge ControllerStatuses when AppendMetrics is
  called (multiple input sources).
- pkg/inputunifi/interface.go: populate ControllerStatuses with Up=true
  on success and Up=false (while still continuing) on per-controller error.
- pkg/promunifi/collector.go: declare and register a prometheus.GaugeVec
  `<namespace>_controller_up`; set the gauge for each controller status
  after every Collect cycle.

Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Cody Lee
2026-03-23 15:25:00 -05:00
committed by GitHub
parent 8c7f1cb854
commit 6c5ff5482d
4 changed files with 67 additions and 12 deletions

View File

@@ -50,6 +50,8 @@ type promUnifi struct {
DHCPLease *dhcplease
WAN *wan
Controller *controller
// controllerUp tracks per-controller poll success (1) or failure (0).
controllerUp *prometheus.GaugeVec
// This interface is passed to the Collect() method. The Collect method uses
// this interface to retrieve the latest UniFi measurements and export them.
Collector poller.Collect
@@ -213,6 +215,10 @@ func (u *promUnifi) Run(c poller.Collect) error {
u.DHCPLease = descDHCPLease(u.Namespace + "_")
u.WAN = descWAN(u.Namespace + "_")
u.Controller = descController(u.Namespace + "_")
u.controllerUp = prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: u.Namespace + "_controller_up",
Help: "Whether the last poll of the UniFi controller succeeded (1) or failed (0).",
}, []string{"source"})
mux := http.NewServeMux()
promver.Version = version.Version
@@ -221,6 +227,7 @@ func (u *promUnifi) Run(c poller.Collect) error {
webserver.UpdateOutput(&webserver.Output{Name: PluginName, Config: u.Config})
prometheus.MustRegister(collectors.NewBuildInfoCollector())
prometheus.MustRegister(u.controllerUp)
prometheus.MustRegister(u)
mux.Handle("/metrics", promhttp.HandlerFor(prometheus.DefaultGatherer,
promhttp.HandlerOpts{ErrorHandling: promhttp.ContinueOnError},
@@ -340,6 +347,18 @@ func (u *promUnifi) collect(ch chan<- prometheus.Metric, filter *poller.Filter)
return
}
// Export per-controller up/down gauge values.
if u.controllerUp != nil && r.Metrics != nil {
for _, cs := range r.Metrics.ControllerStatuses {
val := 0.0
if cs.Up {
val = 1.0
}
u.controllerUp.WithLabelValues(cs.Source).Set(val)
}
}
// Pass Report interface into our collecting and reporting methods.
go u.exportMetrics(r, ch, r.ch)