From ab86d34cf2a556dd0afcde902d8516a6c04aa0da Mon Sep 17 00:00:00 2001 From: davidnewhall2 Date: Sun, 17 Nov 2019 03:02:25 -0800 Subject: [PATCH] add site code --- integrations/inputunifi/examples/MANUAL.md | 2 +- .../inputunifi/examples/up.conf.example | 1 + .../inputunifi/examples/up.xml.example | 1 + .../inputunifi/examples/up.yaml.example | 1 + integrations/inputunifi/promunifi/README.md | 4 +- integrations/inputunifi/promunifi/clients.go | 60 +++---- .../inputunifi/promunifi/collector.go | 11 +- integrations/inputunifi/promunifi/site.go | 161 +++++++++++++++++- 8 files changed, 203 insertions(+), 38 deletions(-) diff --git a/integrations/inputunifi/examples/MANUAL.md b/integrations/inputunifi/examples/MANUAL.md index 16038cf4..0840f9a1 100644 --- a/integrations/inputunifi/examples/MANUAL.md +++ b/integrations/inputunifi/examples/MANUAL.md @@ -104,7 +104,7 @@ is provided so the application can be easily adapted to any environment. * Value: prometheus In this mode the application opens an http interface and exports the measurements at /metrics for collection by prometheus. Enabling this - mode disables InfluxDB usage entirely. + mode disables InfluxDB usage entirely. This is BETA. http_listen default: 0.0.0.0:61317 This option controls the IP and port the http listener uses when the diff --git a/integrations/inputunifi/examples/up.conf.example b/integrations/inputunifi/examples/up.conf.example index 82c1f9b1..a89fd780 100644 --- a/integrations/inputunifi/examples/up.conf.example +++ b/integrations/inputunifi/examples/up.conf.example @@ -32,6 +32,7 @@ quiet = false # # Prometheus mode opens an HTTP server on port 61317 and exports the metrics at # /metrics for polling collection by a prometheus server. This disables influxdb. +# IMPORTANT: The prometheus mode is still beta and doesn't work very well. mode = "influx" # This controls on which ip and port /metrics is exported when mode is "prometheus". diff --git a/integrations/inputunifi/examples/up.xml.example b/integrations/inputunifi/examples/up.xml.example index f77503e5..e37f8868 100644 --- a/integrations/inputunifi/examples/up.xml.example +++ b/integrations/inputunifi/examples/up.xml.example @@ -48,6 +48,7 @@ # # Prometheus mode opens an HTTP server on port 61317 and exports the metrics at # /metrics for polling collection by a prometheus server. This disables influxdb. + # IMPORTANT: The prometheus mode is still beta and doesn't work very well. --> influx diff --git a/integrations/inputunifi/examples/up.yaml.example b/integrations/inputunifi/examples/up.yaml.example index c55b8d95..8de73177 100644 --- a/integrations/inputunifi/examples/up.yaml.example +++ b/integrations/inputunifi/examples/up.yaml.example @@ -33,6 +33,7 @@ quiet: false # # Prometheus mode opens an HTTP server on port 61317 and exports the metrics at # /metrics for polling collection by a prometheus server. This disables influxdb. +# IMPORTANT: The prometheus mode is still beta and doesn't work very well. mode: "influx" # This controls on which ip and port /metrics is exported when mode is "prometheus". diff --git a/integrations/inputunifi/promunifi/README.md b/integrations/inputunifi/promunifi/README.md index 27e9ef04..d0ca905d 100644 --- a/integrations/inputunifi/promunifi/README.md +++ b/integrations/inputunifi/promunifi/README.md @@ -1,4 +1,4 @@ # prometheus -This package provides the methods to turn UniFi measurements into prometheus -exported metrics. +This package provides the interface to turn UniFi measurements into prometheus +exported metrics. Requires the poller package for actual UniFi data collection. diff --git a/integrations/inputunifi/promunifi/clients.go b/integrations/inputunifi/promunifi/clients.go index 72ee5799..d54be9c5 100644 --- a/integrations/inputunifi/promunifi/clients.go +++ b/integrations/inputunifi/promunifi/clients.go @@ -47,123 +47,123 @@ func descClient(ns string) *client { return &client{ Anomalies: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "anomalies"), + prometheus.BuildFQName(ns, ns2, "Anomalies"), "Client Anomalies", labels, nil, ), BytesR: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "bytesr"), + prometheus.BuildFQName(ns, ns2, "BytesR"), "Client Data Rate", labels, nil, ), CCQ: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "ccq"), + prometheus.BuildFQName(ns, ns2, "CCQ"), "Client Connection Quality", labels, nil, ), Noise: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "noise"), + prometheus.BuildFQName(ns, ns2, "Noise"), "Client AP Noise", labels, nil, ), RoamCount: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "roamcount"), + prometheus.BuildFQName(ns, ns2, "RoamCount"), "Client Roam Counter", labels, nil, ), RSSI: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "rssi"), + prometheus.BuildFQName(ns, ns2, "RSSI"), "Client RSSI", labels, nil, ), RxBytes: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "rxbytes"), + prometheus.BuildFQName(ns, ns2, "RxBytes"), "Client Receive Bytes", labels, nil, ), RxBytesR: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "rxbytesr"), + prometheus.BuildFQName(ns, ns2, "RxBytesR"), "Client Receive Data Rate", labels, nil, ), RxPackets: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "rxpackets"), + prometheus.BuildFQName(ns, ns2, "RxPackets"), "Client Receive Packets", labels, nil, ), RxRate: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "rxrate"), + prometheus.BuildFQName(ns, ns2, "RxRate"), "Client Receive Rate", labels, nil, ), Signal: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "signal"), + prometheus.BuildFQName(ns, ns2, "Signal"), "Client Signal Strength", labels, nil, ), TxBytes: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "txbytes"), + prometheus.BuildFQName(ns, ns2, "TxBytes"), "Client Transmit Bytes", labels, nil, ), TxBytesR: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "txbytesr"), + prometheus.BuildFQName(ns, ns2, "TxBytesR"), "Client Transmit Data Rate", labels, nil, ), TxPackets: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "txpackets"), + prometheus.BuildFQName(ns, ns2, "TxPackets"), "Client Transmit Packets", labels, nil, ), TxPower: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "txpower"), + prometheus.BuildFQName(ns, ns2, "TxPower"), "Client Transmit Power", labels, nil, ), TxRate: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "txrate"), + prometheus.BuildFQName(ns, ns2, "TxRate"), "Client Transmit Rate", labels, nil, ), Uptime: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "uptime"), + prometheus.BuildFQName(ns, ns2, "Uptime"), "Client Uptime", labels, nil, ), WifiTxAttempts: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "wifitxattempts"), + prometheus.BuildFQName(ns, ns2, "WifiTxAttempts"), "Client Wifi Transmit Attempts", labels, nil, ), WiredRxBytes: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "wiredrxbytes"), + prometheus.BuildFQName(ns, ns2, "WiredRxBytes"), "Client Wired Receive Bytes", labels, nil, ), WiredRxBytesR: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "wiredrxbytesr"), + prometheus.BuildFQName(ns, ns2, "WiredRxBytesR"), "Client Wired Receive Data Rate", labels, nil, ), WiredRxPackets: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "wiredrxpackets"), + prometheus.BuildFQName(ns, ns2, "WiredRxPackets"), "Client Wired Receive Packets", labels, nil, ), WiredTxBytes: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "wiredtxbytes"), + prometheus.BuildFQName(ns, ns2, "WiredTxBytes"), "Client Wired Transmit Bytes", labels, nil, ), WiredTxBytesR: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "wiredtxbytesr"), + prometheus.BuildFQName(ns, ns2, "WiredTxBytesR"), "Client Wired Data Rate", labels, nil, ), WiredTxPackets: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "wiredtxpackets"), + prometheus.BuildFQName(ns, ns2, "WiredTxPackets"), "Client Wired Transmit Packets", labels, nil, ), DpiStatsApp: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "dpistatsapp"), + prometheus.BuildFQName(ns, ns2, "DpiStatsApp"), "Client DPI Stats App", labels, nil, ), DpiStatsCat: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "dpistatscat"), + prometheus.BuildFQName(ns, ns2, "DpiStatsCat"), "Client DPI Stats Cat", labels, nil, ), DpiStatsRxBytes: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "dpistatsrxbytes"), + prometheus.BuildFQName(ns, ns2, "DpiStatsRxBytes"), "Client DPI Stats Receive Bytes", labels, nil, ), DpiStatsRxPackets: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "dpistatsrxpackets"), + prometheus.BuildFQName(ns, ns2, "DpiStatsRxPackets"), "Client DPI Stats Receive Packets", labels, nil, ), DpiStatsTxBytes: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "dpistatstxbytes"), + prometheus.BuildFQName(ns, ns2, "DpiStatsTxBytes"), "Client DPI Stats Transmit Bytes", labels, nil, ), DpiStatsTxPackets: prometheus.NewDesc( - prometheus.BuildFQName(ns, ns2, "dpistatstxpackets"), + prometheus.BuildFQName(ns, ns2, "DpiStatsTxPackets"), "Client DPI Stats Transmit Packets", labels, nil, ), } diff --git a/integrations/inputunifi/promunifi/collector.go b/integrations/inputunifi/promunifi/collector.go index 2632019d..d2661c82 100644 --- a/integrations/inputunifi/promunifi/collector.go +++ b/integrations/inputunifi/promunifi/collector.go @@ -131,10 +131,15 @@ func (u *unifiCollector) export(ch chan<- prometheus.Metric, exports []*metricEx for _, e := range exports { v, ok := e.Value.(float64) if !ok { - if u.Config.ReportErrors { - ch <- prometheus.NewInvalidMetric(e.Desc, fmt.Errorf("not a number")) + j, ok := e.Value.(int64) + v = float64(j) + if !ok { + // log.Printf("not a number: %v %v", e.Value, e.Desc.String()) + if u.Config.ReportErrors { + ch <- prometheus.NewInvalidMetric(e.Desc, fmt.Errorf("not a number: %v", e.Value)) + } + continue } - return } ch <- prometheus.NewMetricWithTimestamp(ts, prometheus.MustNewConstMetric(e.Desc, e.ValueType, v, e.Labels...)) } diff --git a/integrations/inputunifi/promunifi/site.go b/integrations/inputunifi/promunifi/site.go index 77bad2ee..defaaf17 100644 --- a/integrations/inputunifi/promunifi/site.go +++ b/integrations/inputunifi/promunifi/site.go @@ -1,17 +1,174 @@ package promunifi import ( + "github.com/prometheus/client_golang/prometheus" "golift.io/unifi" ) type site struct { + NumUser *prometheus.Desc + NumGuest *prometheus.Desc + NumIot *prometheus.Desc + TxBytesR *prometheus.Desc + RxBytesR *prometheus.Desc + NumAp *prometheus.Desc + NumAdopted *prometheus.Desc + NumDisabled *prometheus.Desc + NumDisconnected *prometheus.Desc + NumPending *prometheus.Desc + NumGw *prometheus.Desc + NumSw *prometheus.Desc + NumSta *prometheus.Desc + Latency *prometheus.Desc + Drops *prometheus.Desc + XputUp *prometheus.Desc + XputDown *prometheus.Desc + SpeedtestPing *prometheus.Desc + RemoteUserNumActive *prometheus.Desc + RemoteUserNumInactive *prometheus.Desc + RemoteUserRxBytes *prometheus.Desc + RemoteUserTxBytes *prometheus.Desc + RemoteUserRxPackets *prometheus.Desc + RemoteUserTxPackets *prometheus.Desc } +// XXX: The help values can be more verbose. func descSite(ns string) *site { - return &site{} + labels := []string{"name", "desc", "site_name", "subsystem", "status", "gwversion"} + ns2 := "site" + + return &site{ + NumUser: prometheus.NewDesc( + prometheus.BuildFQName(ns, ns2, "NumUser"), + "NumUser", labels, nil, + ), + NumGuest: prometheus.NewDesc( + prometheus.BuildFQName(ns, ns2, "NumGuest"), + "NumGuest", labels, nil, + ), + NumIot: prometheus.NewDesc( + prometheus.BuildFQName(ns, ns2, "NumIot"), + "NumIot", labels, nil, + ), + TxBytesR: prometheus.NewDesc( + prometheus.BuildFQName(ns, ns2, "TxBytesR"), + "TxBytesR", labels, nil, + ), + RxBytesR: prometheus.NewDesc( + prometheus.BuildFQName(ns, ns2, "RxBytesR"), + "RxBytesR", labels, nil, + ), + NumAp: prometheus.NewDesc( + prometheus.BuildFQName(ns, ns2, "NumAp"), + "NumAp", labels, nil, + ), + NumAdopted: prometheus.NewDesc( + prometheus.BuildFQName(ns, ns2, "NumAdopted"), + "NumAdopted", labels, nil, + ), + NumDisabled: prometheus.NewDesc( + prometheus.BuildFQName(ns, ns2, "NumDisabled"), + "NumDisabled", labels, nil, + ), + NumDisconnected: prometheus.NewDesc( + prometheus.BuildFQName(ns, ns2, "NumDisconnected"), + "NumDisconnected", labels, nil, + ), + NumPending: prometheus.NewDesc( + prometheus.BuildFQName(ns, ns2, "NumPending"), + "NumPending", labels, nil, + ), + NumGw: prometheus.NewDesc( + prometheus.BuildFQName(ns, ns2, "NumGw"), + "NumGw", labels, nil, + ), + NumSw: prometheus.NewDesc( + prometheus.BuildFQName(ns, ns2, "NumSw"), + "NumSw", labels, nil, + ), + NumSta: prometheus.NewDesc( + prometheus.BuildFQName(ns, ns2, "NumSta"), + "NumSta", labels, nil, + ), + Latency: prometheus.NewDesc( + prometheus.BuildFQName(ns, ns2, "Latency"), + "Latency", labels, nil, + ), + Drops: prometheus.NewDesc( + prometheus.BuildFQName(ns, ns2, "Drops"), + "Drops", labels, nil, + ), + XputUp: prometheus.NewDesc( + prometheus.BuildFQName(ns, ns2, "XputUp"), + "XputUp", labels, nil, + ), + XputDown: prometheus.NewDesc( + prometheus.BuildFQName(ns, ns2, "XputDown"), + "XputDown", labels, nil, + ), + SpeedtestPing: prometheus.NewDesc( + prometheus.BuildFQName(ns, ns2, "SpeedtestPing"), + "SpeedtestPing", labels, nil, + ), + RemoteUserNumActive: prometheus.NewDesc( + prometheus.BuildFQName(ns, ns2, "RemoteUserNumActive"), + "RemoteUserNumActive", labels, nil, + ), + RemoteUserNumInactive: prometheus.NewDesc( + prometheus.BuildFQName(ns, ns2, "RemoteUserNumInactive"), + "RemoteUserNumInactive", labels, nil, + ), + RemoteUserRxBytes: prometheus.NewDesc( + prometheus.BuildFQName(ns, ns2, "RemoteUserRxBytes"), + "RemoteUserRxBytes", labels, nil, + ), + RemoteUserTxBytes: prometheus.NewDesc( + prometheus.BuildFQName(ns, ns2, "RemoteUserTxBytes"), + "RemoteUserTxBytes", labels, nil, + ), + RemoteUserRxPackets: prometheus.NewDesc( + prometheus.BuildFQName(ns, ns2, "RemoteUserRxPackets"), + "RemoteUserRxPackets", labels, nil, + ), + RemoteUserTxPackets: prometheus.NewDesc( + prometheus.BuildFQName(ns, ns2, "RemoteUserTxPackets"), + "RemoteUserTxPackets", labels, nil, + ), + } } // exportSite exports Network Site Data func (u *unifiCollector) exportSite(s *unifi.Site) []*metricExports { - return nil + labels := []string{s.Name, s.Desc, s.SiteName} + var m []*metricExports + for _, h := range s.Health { + l := append(labels, h.Subsystem, h.Status, h.GwVersion) + m = append(m, &metricExports{u.Site.NumUser, prometheus.CounterValue, h.NumUser.Val, l}) + m = append(m, &metricExports{u.Site.NumGuest, prometheus.CounterValue, h.NumGuest.Val, l}) + m = append(m, &metricExports{u.Site.NumIot, prometheus.CounterValue, h.NumIot.Val, l}) + m = append(m, &metricExports{u.Site.TxBytesR, prometheus.GaugeValue, h.TxBytesR.Val, l}) + m = append(m, &metricExports{u.Site.RxBytesR, prometheus.GaugeValue, h.RxBytesR.Val, l}) + m = append(m, &metricExports{u.Site.NumAp, prometheus.CounterValue, h.NumAp.Val, l}) + m = append(m, &metricExports{u.Site.NumAdopted, prometheus.CounterValue, h.NumAdopted.Val, l}) + m = append(m, &metricExports{u.Site.NumDisabled, prometheus.CounterValue, h.NumDisabled.Val, l}) + m = append(m, &metricExports{u.Site.NumDisconnected, prometheus.CounterValue, h.NumDisconnected.Val, l}) + m = append(m, &metricExports{u.Site.NumPending, prometheus.CounterValue, h.NumPending.Val, l}) + m = append(m, &metricExports{u.Site.NumGw, prometheus.CounterValue, h.NumGw.Val, l}) + m = append(m, &metricExports{u.Site.NumSw, prometheus.CounterValue, h.NumSw.Val, l}) + m = append(m, &metricExports{u.Site.NumSta, prometheus.CounterValue, h.NumSta.Val, l}) + m = append(m, &metricExports{u.Site.Latency, prometheus.GaugeValue, h.Latency.Val, l}) + m = append(m, &metricExports{u.Site.Drops, prometheus.CounterValue, h.Drops.Val, l}) + m = append(m, &metricExports{u.Site.XputUp, prometheus.GaugeValue, h.XputUp.Val, l}) + m = append(m, &metricExports{u.Site.XputDown, prometheus.GaugeValue, h.XputDown.Val, l}) + m = append(m, &metricExports{u.Site.SpeedtestPing, prometheus.GaugeValue, h.SpeedtestPing.Val, l}) + if h.Subsystem == "vpn" { + m = append(m, &metricExports{u.Site.RemoteUserNumActive, prometheus.CounterValue, h.RemoteUserNumActive.Val, l}) + m = append(m, &metricExports{u.Site.RemoteUserNumInactive, prometheus.CounterValue, h.RemoteUserNumInactive.Val, l}) + m = append(m, &metricExports{u.Site.RemoteUserRxBytes, prometheus.CounterValue, h.RemoteUserRxBytes.Val, l}) + m = append(m, &metricExports{u.Site.RemoteUserTxBytes, prometheus.CounterValue, h.RemoteUserTxBytes.Val, l}) + m = append(m, &metricExports{u.Site.RemoteUserRxPackets, prometheus.CounterValue, h.RemoteUserRxPackets.Val, l}) + m = append(m, &metricExports{u.Site.RemoteUserTxPackets, prometheus.CounterValue, h.RemoteUserTxPackets.Val, l}) + } + } + return m }