mirror of
https://github.com/unpoller/unpoller.git
synced 2026-03-31 06:33:57 -04:00
Collect port anomalies from the UniFi v2 API endpoint
/proxy/network/v2/api/site/{site}/ports/port-anomalies and export
them to all output plugins (Prometheus, InfluxDB, DataDog, OpenTelemetry).
Metrics exported per port:
- port_anomaly_count – number of anomaly events
- port_anomaly_last_seen – unix timestamp of last event
Labels: site_name, source, device_mac, port_idx, anomaly_type
Bumps github.com/unpoller/unifi/v5 to v5.24.0 which adds GetPortAnomalies.
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -52,6 +52,7 @@ type promUnifi struct {
|
||||
Controller *controller
|
||||
FirewallPolicy *firewallpolicy
|
||||
Topology *topology
|
||||
PortAnomaly *portanomaly
|
||||
// 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
|
||||
@@ -219,6 +220,7 @@ func (u *promUnifi) Run(c poller.Collect) error {
|
||||
u.Controller = descController(u.Namespace + "_")
|
||||
u.FirewallPolicy = descFirewallPolicy(u.Namespace + "_")
|
||||
u.Topology = descTopology(u.Namespace + "_")
|
||||
u.PortAnomaly = descPortAnomaly(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).",
|
||||
@@ -307,7 +309,7 @@ func (t *target) Describe(ch chan<- *prometheus.Desc) {
|
||||
// Describe satisfies the prometheus Collector. This returns all of the
|
||||
// metric descriptions that this packages produces.
|
||||
func (u *promUnifi) Describe(ch chan<- *prometheus.Desc) {
|
||||
for _, f := range []any{u.Client, u.Device, u.UAP, u.USG, u.USW, u.PDU, u.Site, u.SpeedTest, u.DHCPLease, u.WAN, u.FirewallPolicy, u.Topology} {
|
||||
for _, f := range []any{u.Client, u.Device, u.UAP, u.USG, u.USW, u.PDU, u.Site, u.SpeedTest, u.DHCPLease, u.WAN, u.FirewallPolicy, u.Topology, u.PortAnomaly} {
|
||||
v := reflect.Indirect(reflect.ValueOf(f))
|
||||
|
||||
// Loop each struct member and send it to the provided channel.
|
||||
@@ -490,6 +492,15 @@ func (u *promUnifi) loopExports(r report) {
|
||||
}
|
||||
}
|
||||
|
||||
portAnomalies := make([]*unifi.PortAnomaly, 0, len(m.PortAnomalies))
|
||||
for _, a := range m.PortAnomalies {
|
||||
if anomaly, ok := a.(*unifi.PortAnomaly); ok {
|
||||
portAnomalies = append(portAnomalies, anomaly)
|
||||
}
|
||||
}
|
||||
|
||||
u.exportPortAnomalies(r, portAnomalies)
|
||||
|
||||
u.exportClientDPItotals(r, appTotal, catTotal)
|
||||
}
|
||||
|
||||
|
||||
39
pkg/promunifi/port_anomalies.go
Normal file
39
pkg/promunifi/port_anomalies.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package promunifi
|
||||
|
||||
import (
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/unpoller/unifi/v5"
|
||||
)
|
||||
|
||||
type portanomaly struct {
|
||||
AnomalyCount *prometheus.Desc
|
||||
AnomalyLastSeen *prometheus.Desc
|
||||
}
|
||||
|
||||
func descPortAnomaly(ns string) *portanomaly {
|
||||
labels := []string{"site_name", "source", "device_mac", "port_idx", "anomaly_type"}
|
||||
|
||||
nd := prometheus.NewDesc
|
||||
|
||||
return &portanomaly{
|
||||
AnomalyCount: nd(ns+"port_anomaly_count", "Number of anomaly events on this port", labels, nil),
|
||||
AnomalyLastSeen: nd(ns+"port_anomaly_last_seen", "Unix timestamp of the last anomaly event on this port", labels, nil),
|
||||
}
|
||||
}
|
||||
|
||||
func (u *promUnifi) exportPortAnomalies(r report, anomalies []*unifi.PortAnomaly) {
|
||||
for _, a := range anomalies {
|
||||
labels := []string{
|
||||
a.SiteName,
|
||||
a.SourceName,
|
||||
a.DeviceMAC,
|
||||
a.PortIdx.Txt,
|
||||
a.AnomalyType,
|
||||
}
|
||||
|
||||
r.send([]*metric{
|
||||
{u.PortAnomaly.AnomalyCount, gauge, a.Count.Val, labels},
|
||||
{u.PortAnomaly.AnomalyLastSeen, gauge, a.LastSeen.Val, labels},
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user