From a9a7862438c5ed828d55980e6dcbdde34198e195 Mon Sep 17 00:00:00 2001 From: davidnewhall2 Date: Fri, 29 Nov 2019 20:30:51 -0800 Subject: [PATCH] Add more to the interface --- promunifi/clients.go | 69 +++++++++++--------------- promunifi/collector.go | 85 +++++++++----------------------- promunifi/loops.go | 83 ++++++++++++++++++++++++++++++++ promunifi/report.go | 71 +++++++++++++++++++++++++++ promunifi/site.go | 98 ++++++++++++++++--------------------- promunifi/uap.go | 21 ++------ promunifi/udm.go | 15 +----- promunifi/usg.go | 107 ++++++++++++++++++----------------------- promunifi/usw.go | 51 ++++++++------------ 9 files changed, 319 insertions(+), 281 deletions(-) create mode 100644 promunifi/loops.go create mode 100644 promunifi/report.go diff --git a/promunifi/clients.go b/promunifi/clients.go index 10b9a4c4..d1014a60 100644 --- a/promunifi/clients.go +++ b/promunifi/clients.go @@ -39,27 +39,27 @@ type uclient struct { } func descClient(ns string) *uclient { - labels := []string{"name", "mac", "site_name", "gw_mac", "gw_name", "sw_mac", "sw_name", "vlan", "ip", "oui", "network", "sw_port", - "ap_mac", "ap_name", "radio_name", "radio", "radio_proto", "channel", "essid", "bssid", "radio_desc", "wired"} + labels := []string{"name", "mac", "site_name", "gw_name", "sw_name", "vlan", "ip", "oui", "network", "sw_port", "ap_name", "wired"} + labelW := append([]string{"radio_name", "radio", "radio_proto", "channel", "essid", "bssid", "radio_desc"}, labels...) return &uclient{ - Anomalies: prometheus.NewDesc(ns+"anomalies_total", "Client Anomalies", labels, nil), - BytesR: prometheus.NewDesc(ns+"transfer_rate_bytes", "Client Data Rate", labels, nil), - CCQ: prometheus.NewDesc(ns+"ccq_percent", "Client Connection Quality", labels, nil), - Noise: prometheus.NewDesc(ns+"noise_db", "Client AP Noise", labels, nil), - RoamCount: prometheus.NewDesc(ns+"roam_count_total", "Client Roam Counter", labels, nil), - RSSI: prometheus.NewDesc(ns+"rssi_db", "Client RSSI", labels, nil), + Anomalies: prometheus.NewDesc(ns+"anomalies_total", "Client Anomalies", labelW, nil), + BytesR: prometheus.NewDesc(ns+"transfer_rate_bytes", "Client Data Rate", labelW, nil), + CCQ: prometheus.NewDesc(ns+"ccq_percent", "Client Connection Quality", labelW, nil), + Noise: prometheus.NewDesc(ns+"noise_db", "Client AP Noise", labelW, nil), + RoamCount: prometheus.NewDesc(ns+"roam_count_total", "Client Roam Counter", labelW, nil), + RSSI: prometheus.NewDesc(ns+"rssi_db", "Client RSSI", labelW, nil), RxBytes: prometheus.NewDesc(ns+"receive_bytes_total", "Client Receive Bytes", labels, nil), RxBytesR: prometheus.NewDesc(ns+"receive_rate_bytes", "Client Receive Data Rate", labels, nil), RxPackets: prometheus.NewDesc(ns+"receive_packets_total", "Client Receive Packets", labels, nil), - RxRate: prometheus.NewDesc(ns+"radio_receive_rate_bps", "Client Receive Rate", labels, nil), - Signal: prometheus.NewDesc(ns+"radio_signal_db", "Client Signal Strength", labels, nil), + RxRate: prometheus.NewDesc(ns+"radio_receive_rate_bps", "Client Receive Rate", labelW, nil), + Signal: prometheus.NewDesc(ns+"radio_signal_db", "Client Signal Strength", labelW, nil), TxBytes: prometheus.NewDesc(ns+"transmit_bytes_total", "Client Transmit Bytes", labels, nil), TxBytesR: prometheus.NewDesc(ns+"transmit_rate_bytes", "Client Transmit Data Rate", labels, nil), TxPackets: prometheus.NewDesc(ns+"transmit_packets_total", "Client Transmit Packets", labels, nil), - TxPower: prometheus.NewDesc(ns+"radio_transmit_power_dbm", "Client Transmit Power", labels, nil), - TxRate: prometheus.NewDesc(ns+"radio_transmit_rate_bps", "Client Transmit Rate", labels, nil), - WifiTxAttempts: prometheus.NewDesc(ns+"wifi_attempts_transmit_total", "Client Wifi Transmit Attempts", labels, nil), - Uptime: prometheus.NewDesc(ns+"uptime_seconds", "Client Uptime", labels, nil), + TxPower: prometheus.NewDesc(ns+"radio_transmit_power_dbm", "Client Transmit Power", labelW, nil), + TxRate: prometheus.NewDesc(ns+"radio_transmit_rate_bps", "Client Transmit Rate", labelW, nil), + WifiTxAttempts: prometheus.NewDesc(ns+"wifi_attempts_transmit_total", "Client Wifi Transmit Attempts", labelW, nil), + Uptime: prometheus.NewDesc(ns+"uptime_seconds", "Client Uptime", labelW, nil), /* needs more "looking into" DpiStatsApp: prometheus.NewDesc(ns+"dpi_stats_app", "Client DPI Stats App", labels, nil), DpiStatsCat: prometheus.NewDesc(ns+"dpi_stats_cat", "Client DPI Stats Cat", labels, nil), @@ -71,22 +71,9 @@ func descClient(ns string) *uclient { } } -func (u *unifiCollector) exportClients(r report) { - if r.metrics() == nil || len(r.metrics().Clients) < 1 { - return - } - r.add() - go func() { - defer r.done() - for _, c := range r.metrics().Clients { - u.exportClient(r, c) - } - }() -} - func (u *unifiCollector) exportClient(r report, c *unifi.Client) { - labels := []string{c.Name, c.Mac, c.SiteName, c.GwMac, c.GwName, c.SwMac, c.SwName, c.Vlan.Txt, c.IP, c.Oui, c.Network, c.SwPort.Txt, - c.ApMac, c.ApName, c.RadioName, c.Radio, c.RadioProto, c.Channel.Txt, c.Essid, c.Bssid, c.RadioDescription, "false"} + labels := []string{c.Name, c.Mac, c.SiteName, c.GwName, c.SwName, c.Vlan.Txt, c.IP, c.Oui, c.Network, c.SwPort.Txt, c.ApName, "false"} + labelW := append([]string{c.RadioName, c.Radio, c.RadioProto, c.Channel.Txt, c.Essid, c.Bssid, c.RadioDescription}, labels...) if c.IsWired.Val { labels[len(labels)-1] = "true" @@ -101,27 +88,27 @@ func (u *unifiCollector) exportClient(r report, c *unifi.Client) { } else { labels[len(labels)-1] = "false" r.send([]*metricExports{ - {u.Client.Anomalies, prometheus.CounterValue, c.Anomalies, labels}, - {u.Client.CCQ, prometheus.GaugeValue, c.Ccq / 10, labels}, - {u.Client.Noise, prometheus.GaugeValue, c.Noise, labels}, - {u.Client.RoamCount, prometheus.CounterValue, c.RoamCount, labels}, - {u.Client.RSSI, prometheus.GaugeValue, c.Rssi, labels}, - {u.Client.Signal, prometheus.GaugeValue, c.Signal, labels}, - {u.Client.TxPower, prometheus.GaugeValue, c.TxPower, labels}, - {u.Client.TxRate, prometheus.GaugeValue, c.TxRate * 1000, labels}, - {u.Client.WifiTxAttempts, prometheus.CounterValue, c.WifiTxAttempts, labels}, - {u.Client.RxRate, prometheus.GaugeValue, c.RxRate * 1000, labels}, + {u.Client.Anomalies, prometheus.CounterValue, c.Anomalies, labelW}, + {u.Client.CCQ, prometheus.GaugeValue, c.Ccq / 10, labelW}, + {u.Client.Noise, prometheus.GaugeValue, c.Noise, labelW}, + {u.Client.RoamCount, prometheus.CounterValue, c.RoamCount, labelW}, + {u.Client.RSSI, prometheus.GaugeValue, c.Rssi, labelW}, + {u.Client.Signal, prometheus.GaugeValue, c.Signal, labelW}, + {u.Client.TxPower, prometheus.GaugeValue, c.TxPower, labelW}, + {u.Client.TxRate, prometheus.GaugeValue, c.TxRate * 1000, labelW}, + {u.Client.WifiTxAttempts, prometheus.CounterValue, c.WifiTxAttempts, labelW}, + {u.Client.RxRate, prometheus.GaugeValue, c.RxRate * 1000, labelW}, {u.Client.TxBytes, prometheus.CounterValue, c.TxBytes, labels}, {u.Client.TxBytesR, prometheus.GaugeValue, c.TxBytesR, labels}, {u.Client.TxPackets, prometheus.CounterValue, c.TxPackets, labels}, {u.Client.RxBytes, prometheus.CounterValue, c.RxBytes, labels}, {u.Client.RxBytesR, prometheus.GaugeValue, c.RxBytesR, labels}, {u.Client.RxPackets, prometheus.CounterValue, c.RxPackets, labels}, - {u.Client.BytesR, prometheus.GaugeValue, c.BytesR, labels}, + {u.Client.BytesR, prometheus.GaugeValue, c.BytesR, labelW}, }) } r.send([]*metricExports{ - {u.Client.Uptime, prometheus.GaugeValue, c.Uptime, labels}, + {u.Client.Uptime, prometheus.GaugeValue, c.Uptime, labelW}, /* needs more "looking into" {u.Client.DpiStatsApp, prometheus.GaugeValue, c.DpiStats.App, labels}, {u.Client.DpiStatsCat, prometheus.GaugeValue, c.DpiStats.Cat, labels}, diff --git a/promunifi/collector.go b/promunifi/collector.go index 6ed313f2..285ac72a 100644 --- a/promunifi/collector.go +++ b/promunifi/collector.go @@ -61,14 +61,7 @@ type Report struct { Start time.Time ch chan []*metricExports wg sync.WaitGroup -} - -// internal interface used to "process metrics" - can be mocked and overridden for tests. -type report interface { - send([]*metricExports) - add() - done() - metrics() *metrics.Metrics + cf UnifiCollectorCnfg } // NewUnifiCollector returns a prometheus collector that will export any available @@ -117,13 +110,17 @@ func (u *unifiCollector) Describe(ch chan<- *prometheus.Desc) { // Collect satisfies the prometheus Collector. This runs the input method to get // the current metrics (from another package) then exports them for prometheus. func (u *unifiCollector) Collect(ch chan<- prometheus.Metric) { - var err error - r := &Report{Start: time.Now(), ch: make(chan []*metricExports, buffer)} + r := &Report{ + cf: u.Config, + Start: time.Now(), + ch: make(chan []*metricExports, buffer), + } defer func() { r.wg.Wait() close(r.ch) }() + var err error if r.Metrics, err = u.Config.CollectFn(); err != nil { ch <- prometheus.NewInvalidMetric( prometheus.NewInvalidDesc(fmt.Errorf("metric fetch failed")), err) @@ -131,72 +128,36 @@ func (u *unifiCollector) Collect(ch chan<- prometheus.Metric) { } go u.exportMetrics(r, ch) - u.exportClients(r) - u.exportSites(r) - u.exportUAPs(r) - u.exportUSWs(r) - u.exportUSGs(r) - u.exportUDMs(r) + // in loops.go. + u.loopClients(r) + u.loopSites(r) + u.loopUAPs(r) + u.loopUSWs(r) + u.loopUSGs(r) + u.loopUDMs(r) } // This is closely tied to the method above with a sync.WaitGroup. // This method runs in a go routine and exits when the channel closes. -func (u *unifiCollector) exportMetrics(r *Report, ch chan<- prometheus.Metric) { +func (u *unifiCollector) exportMetrics(r report, ch chan<- prometheus.Metric) { descs := make(map[*prometheus.Desc]bool) // used as a counter - for newMetrics := range r.ch { + defer r.report(descs) + for newMetrics := range r.channel() { for _, m := range newMetrics { - r.Total++ descs[m.Desc] = true - var value float64 switch v := m.Value.(type) { case unifi.FlexInt: - value = v.Val + ch <- r.export(m, v.Val) case float64: - value = v + ch <- r.export(m, v) case int64: - value = float64(v) + ch <- r.export(m, float64(v)) case int: - value = float64(v) - + ch <- r.export(m, float64(v)) default: - r.Errors++ - if u.Config.ReportErrors { - ch <- prometheus.NewInvalidMetric(m.Desc, fmt.Errorf("not a number: %v", m.Value)) - } - continue + r.error(ch, m.Desc, m.Value) } - - if value == 0 { - r.Zeros++ - } - ch <- prometheus.MustNewConstMetric(m.Desc, m.ValueType, value, m.Labels...) } - r.wg.Done() + r.done() } - - if u.Config.LoggingFn == nil { - return - } - r.Descs, r.Elapsed = len(descs), time.Since(r.Start) - u.Config.LoggingFn(r) -} - -func (r *Report) metrics() *metrics.Metrics { - return r.Metrics -} - -// satisfy gomnd -const one = 1 - -func (r *Report) add() { - r.wg.Add(one) -} - -func (r *Report) done() { - r.wg.Done() -} - -func (r *Report) send(m []*metricExports) { - r.wg.Add(one) - r.ch <- m } diff --git a/promunifi/loops.go b/promunifi/loops.go new file mode 100644 index 00000000..e1a4dcdb --- /dev/null +++ b/promunifi/loops.go @@ -0,0 +1,83 @@ +package promunifi + +// This file contains all the loop methods for each device type, clients and sites. +// Moved them here to consolate clutter from the other files. Also, if these change, +// they usually all change at once since they're pretty much the same code. + +func (u *unifiCollector) loopSites(r report) { + if r.metrics() == nil || len(r.metrics().Sites) < 1 { + return + } + r.add() + go func() { + defer r.done() + for _, s := range r.metrics().Sites { + u.exportSite(r, s) + } + }() +} + +func (u *unifiCollector) loopUAPs(r report) { + if r.metrics() == nil || r.metrics().Devices == nil || len(r.metrics().Devices.UAPs) < 1 { + return + } + r.add() + go func() { + defer r.done() + for _, d := range r.metrics().Devices.UAPs { + u.exportUAP(r, d) + } + }() +} + +func (u *unifiCollector) loopUDMs(r report) { + if r.metrics() == nil || r.metrics().Devices == nil || len(r.metrics().Devices.UDMs) < 1 { + return + } + r.add() + go func() { + defer r.done() + for _, d := range r.metrics().Devices.UDMs { + u.exportUDM(r, d) + } + }() +} + +func (u *unifiCollector) loopUSGs(r report) { + if r.metrics() == nil || r.metrics().Devices == nil || len(r.metrics().Devices.USGs) < 1 { + return + } + r.add() + go func() { + defer r.done() + for _, d := range r.metrics().Devices.USGs { + u.exportUSG(r, d) + } + }() +} + +func (u *unifiCollector) loopUSWs(r report) { + if r.metrics() == nil || r.metrics().Devices == nil || len(r.metrics().Devices.USWs) < 1 { + return + } + r.add() + go func() { + defer r.done() + for _, d := range r.metrics().Devices.USWs { + u.exportUSW(r, d) + } + }() +} + +func (u *unifiCollector) loopClients(r report) { + if r.metrics() == nil || len(r.metrics().Clients) < 1 { + return + } + r.add() + go func() { + defer r.done() + for _, c := range r.metrics().Clients { + u.exportClient(r, c) + } + }() +} diff --git a/promunifi/report.go b/promunifi/report.go new file mode 100644 index 00000000..cc3f70b5 --- /dev/null +++ b/promunifi/report.go @@ -0,0 +1,71 @@ +package promunifi + +import ( + "fmt" + "time" + + "github.com/davidnewhall/unifi-poller/metrics" + "github.com/prometheus/client_golang/prometheus" +) + +// This file contains the report interface. +// This interface can be mocked and overrridden for tests. + +// report is an internal interface used to "process metrics" +type report interface { + send([]*metricExports) + add() + done() + metrics() *metrics.Metrics + report(descs map[*prometheus.Desc]bool) + export(m *metricExports, v float64) prometheus.Metric + channel() chan []*metricExports + error(ch chan<- prometheus.Metric, d *prometheus.Desc, v interface{}) +} + +// satisfy gomnd +const one = 1 + +func (r *Report) report(descs map[*prometheus.Desc]bool) { + if r.cf.LoggingFn == nil { + return + } + r.Descs, r.Elapsed = len(descs), time.Since(r.Start) + r.cf.LoggingFn(r) +} + +func (r *Report) export(m *metricExports, v float64) prometheus.Metric { + r.Total++ + if v == 0 { + r.Zeros++ + } + return prometheus.MustNewConstMetric(m.Desc, m.ValueType, v, m.Labels...) +} + +func (r *Report) metrics() *metrics.Metrics { + return r.Metrics +} + +func (r *Report) channel() chan []*metricExports { + return r.ch +} + +func (r *Report) error(ch chan<- prometheus.Metric, d *prometheus.Desc, v interface{}) { + r.Errors++ + if r.cf.ReportErrors { + ch <- prometheus.NewInvalidMetric(d, fmt.Errorf("not a number: %v", v)) + } +} + +func (r *Report) add() { + r.wg.Add(one) +} + +func (r *Report) done() { + r.wg.Add(-one) +} + +func (r *Report) send(m []*metricExports) { + r.wg.Add(one) + r.ch <- m +} diff --git a/promunifi/site.go b/promunifi/site.go index 5f9f81cc..40cf5237 100644 --- a/promunifi/site.go +++ b/promunifi/site.go @@ -34,7 +34,7 @@ type site struct { } func descSite(ns string) *site { - labels := []string{"subsystem", "status", "name", "desc", "site_name"} + labels := []string{"subsystem", "status", "site_name"} return &site{ NumUser: prometheus.NewDesc(ns+"users", "Number of Users", labels, nil), NumGuest: prometheus.NewDesc(ns+"guests", "Number of Guests", labels, nil), @@ -64,82 +64,68 @@ func descSite(ns string) *site { } } -func (u *unifiCollector) exportSites(r report) { - if r.metrics() == nil || len(r.metrics().Sites) < 1 { - return - } - r.add() - go func() { - defer r.done() - for _, s := range r.metrics().Sites { - u.exportSite(r, s) - } - }() -} - func (u *unifiCollector) exportSite(r report, s *unifi.Site) { - labels := []string{s.Name, s.Desc, s.SiteName} for _, h := range s.Health { - l := append([]string{h.Subsystem, h.Status}, labels...) + labels := []string{h.Subsystem, h.Status, s.SiteName} switch h.Subsystem { case "www": r.send([]*metricExports{ - {u.Site.TxBytesR, prometheus.GaugeValue, h.TxBytesR, l}, - {u.Site.RxBytesR, prometheus.GaugeValue, h.RxBytesR, l}, - {u.Site.Uptime, prometheus.GaugeValue, h.Latency, l}, - {u.Site.Latency, prometheus.GaugeValue, h.Latency.Val / 1000, l}, - {u.Site.XputUp, prometheus.GaugeValue, h.XputUp, l}, - {u.Site.XputDown, prometheus.GaugeValue, h.XputDown, l}, - {u.Site.SpeedtestPing, prometheus.GaugeValue, h.SpeedtestPing, l}, - {u.Site.Drops, prometheus.CounterValue, h.Drops, l}, + {u.Site.TxBytesR, prometheus.GaugeValue, h.TxBytesR, labels}, + {u.Site.RxBytesR, prometheus.GaugeValue, h.RxBytesR, labels}, + {u.Site.Uptime, prometheus.GaugeValue, h.Latency, labels}, + {u.Site.Latency, prometheus.GaugeValue, h.Latency.Val / 1000, labels}, + {u.Site.XputUp, prometheus.GaugeValue, h.XputUp, labels}, + {u.Site.XputDown, prometheus.GaugeValue, h.XputDown, labels}, + {u.Site.SpeedtestPing, prometheus.GaugeValue, h.SpeedtestPing, labels}, + {u.Site.Drops, prometheus.CounterValue, h.Drops, labels}, }) case "wlan": r.send([]*metricExports{ - {u.Site.TxBytesR, prometheus.GaugeValue, h.TxBytesR, l}, - {u.Site.RxBytesR, prometheus.GaugeValue, h.RxBytesR, l}, - {u.Site.NumAdopted, prometheus.GaugeValue, h.NumAdopted, l}, - {u.Site.NumDisconnected, prometheus.GaugeValue, h.NumDisconnected, l}, - {u.Site.NumPending, prometheus.GaugeValue, h.NumPending, l}, - {u.Site.NumUser, prometheus.GaugeValue, h.NumUser, l}, - {u.Site.NumGuest, prometheus.GaugeValue, h.NumGuest, l}, - {u.Site.NumIot, prometheus.GaugeValue, h.NumIot, l}, - {u.Site.NumAp, prometheus.GaugeValue, h.NumAp, l}, - {u.Site.NumDisabled, prometheus.GaugeValue, h.NumDisabled, l}, + {u.Site.TxBytesR, prometheus.GaugeValue, h.TxBytesR, labels}, + {u.Site.RxBytesR, prometheus.GaugeValue, h.RxBytesR, labels}, + {u.Site.NumAdopted, prometheus.GaugeValue, h.NumAdopted, labels}, + {u.Site.NumDisconnected, prometheus.GaugeValue, h.NumDisconnected, labels}, + {u.Site.NumPending, prometheus.GaugeValue, h.NumPending, labels}, + {u.Site.NumUser, prometheus.GaugeValue, h.NumUser, labels}, + {u.Site.NumGuest, prometheus.GaugeValue, h.NumGuest, labels}, + {u.Site.NumIot, prometheus.GaugeValue, h.NumIot, labels}, + {u.Site.NumAp, prometheus.GaugeValue, h.NumAp, labels}, + {u.Site.NumDisabled, prometheus.GaugeValue, h.NumDisabled, labels}, }) case "wan": r.send([]*metricExports{ - {u.Site.TxBytesR, prometheus.GaugeValue, h.TxBytesR, l}, - {u.Site.RxBytesR, prometheus.GaugeValue, h.RxBytesR, l}, - {u.Site.NumAdopted, prometheus.GaugeValue, h.NumAdopted, l}, - {u.Site.NumDisconnected, prometheus.GaugeValue, h.NumDisconnected, l}, - {u.Site.NumPending, prometheus.GaugeValue, h.NumPending, l}, - {u.Site.NumGw, prometheus.GaugeValue, h.NumGw, l}, - {u.Site.NumSta, prometheus.GaugeValue, h.NumSta, l}, + {u.Site.TxBytesR, prometheus.GaugeValue, h.TxBytesR, labels}, + {u.Site.RxBytesR, prometheus.GaugeValue, h.RxBytesR, labels}, + {u.Site.NumAdopted, prometheus.GaugeValue, h.NumAdopted, labels}, + {u.Site.NumDisconnected, prometheus.GaugeValue, h.NumDisconnected, labels}, + {u.Site.NumPending, prometheus.GaugeValue, h.NumPending, labels}, + {u.Site.NumGw, prometheus.GaugeValue, h.NumGw, labels}, + {u.Site.NumSta, prometheus.GaugeValue, h.NumSta, labels}, }) case "lan": r.send([]*metricExports{ - {u.Site.TxBytesR, prometheus.GaugeValue, h.TxBytesR, l}, - {u.Site.RxBytesR, prometheus.GaugeValue, h.RxBytesR, l}, - {u.Site.NumAdopted, prometheus.GaugeValue, h.NumAdopted, l}, - {u.Site.NumDisconnected, prometheus.GaugeValue, h.NumDisconnected, l}, - {u.Site.NumPending, prometheus.GaugeValue, h.NumPending, l}, - {u.Site.NumUser, prometheus.GaugeValue, h.NumUser, l}, - {u.Site.NumGuest, prometheus.GaugeValue, h.NumGuest, l}, - {u.Site.NumIot, prometheus.GaugeValue, h.NumIot, l}, - {u.Site.NumSw, prometheus.GaugeValue, h.NumSw, l}, + {u.Site.TxBytesR, prometheus.GaugeValue, h.TxBytesR, labels}, + {u.Site.RxBytesR, prometheus.GaugeValue, h.RxBytesR, labels}, + {u.Site.NumAdopted, prometheus.GaugeValue, h.NumAdopted, labels}, + {u.Site.NumDisconnected, prometheus.GaugeValue, h.NumDisconnected, labels}, + {u.Site.NumPending, prometheus.GaugeValue, h.NumPending, labels}, + {u.Site.NumUser, prometheus.GaugeValue, h.NumUser, labels}, + {u.Site.NumGuest, prometheus.GaugeValue, h.NumGuest, labels}, + {u.Site.NumIot, prometheus.GaugeValue, h.NumIot, labels}, + {u.Site.NumSw, prometheus.GaugeValue, h.NumSw, labels}, }) case "vpn": r.send([]*metricExports{ - {u.Site.RemoteUserNumActive, prometheus.GaugeValue, h.RemoteUserNumActive, l}, - {u.Site.RemoteUserNumInactive, prometheus.GaugeValue, h.RemoteUserNumInactive, l}, - {u.Site.RemoteUserRxBytes, prometheus.CounterValue, h.RemoteUserRxBytes, l}, - {u.Site.RemoteUserTxBytes, prometheus.CounterValue, h.RemoteUserTxBytes, l}, - {u.Site.RemoteUserRxPackets, prometheus.CounterValue, h.RemoteUserRxPackets, l}, - {u.Site.RemoteUserTxPackets, prometheus.CounterValue, h.RemoteUserTxPackets, l}, + {u.Site.RemoteUserNumActive, prometheus.GaugeValue, h.RemoteUserNumActive, labels}, + {u.Site.RemoteUserNumInactive, prometheus.GaugeValue, h.RemoteUserNumInactive, labels}, + {u.Site.RemoteUserRxBytes, prometheus.CounterValue, h.RemoteUserRxBytes, labels}, + {u.Site.RemoteUserTxBytes, prometheus.CounterValue, h.RemoteUserTxBytes, labels}, + {u.Site.RemoteUserRxPackets, prometheus.CounterValue, h.RemoteUserRxPackets, labels}, + {u.Site.RemoteUserTxPackets, prometheus.CounterValue, h.RemoteUserTxPackets, labels}, }) } } diff --git a/promunifi/uap.go b/promunifi/uap.go index 98d084af..0ff7a3a2 100644 --- a/promunifi/uap.go +++ b/promunifi/uap.go @@ -83,10 +83,10 @@ type uap struct { } func descUAP(ns string) *uap { - labels := []string{"ip", "version", "model", "serial", "type", "mac", "site_name", "name"} - labelA := append([]string{"stat"}, labels[6:]...) - labelV := append([]string{"vap_name", "bssid", "radio", "radio_name", "essid", "usage"}, labels[6:]...) - labelR := append([]string{"radio_name", "radio"}, labels[6:]...) + // labels := []string{"ip", "version", "model", "serial", "type", "mac", "site_name", "name"} + labelA := []string{"stat", "site_name", "name"} // stat + labels[6:] + labelV := []string{"vap_name", "bssid", "radio", "radio_name", "essid", "usage", "site_name", "name"} + labelR := []string{"radio_name", "radio", "site_name", "name"} return &uap{ // 3x each - stat table: total, guest, user ApWifiTxDropped: prometheus.NewDesc(ns+"stat_wifi_transmt_dropped_total", "Wifi Transmissions Dropped", labelA, nil), @@ -165,19 +165,6 @@ func descUAP(ns string) *uap { } } -func (u *unifiCollector) exportUAPs(r report) { - if r.metrics() == nil || r.metrics().Devices == nil || len(r.metrics().Devices.UAPs) < 1 { - return - } - r.add() - go func() { - defer r.done() - for _, d := range r.metrics().Devices.UAPs { - u.exportUAP(r, d) - } - }() -} - func (u *unifiCollector) exportUAP(r report, d *unifi.UAP) { labels := []string{d.IP, d.Version, d.Model, d.Serial, d.Type, d.Mac, d.SiteName, d.Name} // AP data. diff --git a/promunifi/udm.go b/promunifi/udm.go index ccb8cb83..e4e72091 100644 --- a/promunifi/udm.go +++ b/promunifi/udm.go @@ -67,19 +67,6 @@ func descDevice(ns string) *unifiDevice { } } -func (u *unifiCollector) exportUDMs(r report) { - if r.metrics() == nil || r.metrics().Devices == nil || len(r.metrics().Devices.UDMs) < 1 { - return - } - r.add() - go func() { - defer r.done() - for _, d := range r.metrics().Devices.UDMs { - u.exportUDM(r, d) - } - }() -} - // UDM is a collection of stats from USG, USW and UAP. It has no unique stats. func (u *unifiCollector) exportUDM(r report, d *unifi.UDM) { labels := []string{d.IP, d.Version, d.Model, d.Serial, d.Type, d.Mac, d.SiteName, d.Name} @@ -105,7 +92,7 @@ func (u *unifiCollector) exportUDM(r report, d *unifi.UDM) { {u.Device.Mem, prometheus.GaugeValue, d.SystemStats.Mem, labels}, }) u.exportUSWstats(r, labels, d.Stat.Sw) - u.exportUSGstats(r, labels, d.SpeedtestStatus) + u.exportUSGstats(r, labels, d.Stat.Gw, d.SpeedtestStatus) u.exportWANPorts(r, labels, d.Wan1, d.Wan2) u.exportPortTable(r, labels, d.PortTable) if d.Stat.Ap != nil && d.VapTable != nil { diff --git a/promunifi/usg.go b/promunifi/usg.go index e12bc129..8eafef7d 100644 --- a/promunifi/usg.go +++ b/promunifi/usg.go @@ -34,50 +34,38 @@ type usg struct { } func descUSG(ns string) *usg { - labels := []string{"ip", "version", "model", "serial", "type", "mac", "site_name", "name"} - labelWan := append([]string{"port"}, labels[6:]...) + // labels := []string{"ip", "version", "model", "serial", "type", "mac", "site_name", "name"} + // labelWan := append([]string{"port"}, labels[6:]...) + labels := []string{"port", "site_name", "name"} return &usg{ - WanRxPackets: prometheus.NewDesc(ns+"wan_receive_packets_total", "WAN Receive Packets Total", labelWan, nil), - WanRxBytes: prometheus.NewDesc(ns+"wan_receive_bytes_total", "WAN Receive Bytes Total", labelWan, nil), - WanRxDropped: prometheus.NewDesc(ns+"wan_receive_dropped_total", "WAN Receive Dropped Total", labelWan, nil), - WanRxErrors: prometheus.NewDesc(ns+"wan_receive_errors_total", "WAN Receive Errors Total", labelWan, nil), - WanTxPackets: prometheus.NewDesc(ns+"wan_transmit_packets_total", "WAN Transmit Packets Total", labelWan, nil), - WanTxBytes: prometheus.NewDesc(ns+"wan_transmit_bytes_total", "WAN Transmit Bytes Total", labelWan, nil), - WanRxBroadcast: prometheus.NewDesc(ns+"wan_receive_broadcast_total", "WAN Receive Broadcast Total", labelWan, nil), - WanRxBytesR: prometheus.NewDesc(ns+"wan_receive_rate_bytes", "WAN Receive Bytes Rate", labelWan, nil), - WanRxMulticast: prometheus.NewDesc(ns+"wan_receive_multicast_total", "WAN Receive Multicast Total", labelWan, nil), - WanSpeed: prometheus.NewDesc(ns+"wan_speed_bps", "WAN Speed", labelWan, nil), - WanTxBroadcast: prometheus.NewDesc(ns+"wan_transmit_broadcast_total", "WAN Transmit Broadcast Total", labelWan, nil), - WanTxBytesR: prometheus.NewDesc(ns+"wan_transmit_rate_bytes", "WAN Transmit Bytes Rate", labelWan, nil), - WanTxDropped: prometheus.NewDesc(ns+"wan_transmit_dropped_total", "WAN Transmit Dropped Total", labelWan, nil), - WanTxErrors: prometheus.NewDesc(ns+"wan_transmit_errors_total", "WAN Transmit Errors Total", labelWan, nil), - WanTxMulticast: prometheus.NewDesc(ns+"wan_transmit_multicast_total", "WAN Transmit Multicast Total", labelWan, nil), - WanBytesR: prometheus.NewDesc(ns+"wan_rate_bytes", "WAN Transfer Rate", labelWan, nil), + WanRxPackets: prometheus.NewDesc(ns+"wan_receive_packets_total", "WAN Receive Packets Total", labels, nil), + WanRxBytes: prometheus.NewDesc(ns+"wan_receive_bytes_total", "WAN Receive Bytes Total", labels, nil), + WanRxDropped: prometheus.NewDesc(ns+"wan_receive_dropped_total", "WAN Receive Dropped Total", labels, nil), + WanRxErrors: prometheus.NewDesc(ns+"wan_receive_errors_total", "WAN Receive Errors Total", labels, nil), + WanTxPackets: prometheus.NewDesc(ns+"wan_transmit_packets_total", "WAN Transmit Packets Total", labels, nil), + WanTxBytes: prometheus.NewDesc(ns+"wan_transmit_bytes_total", "WAN Transmit Bytes Total", labels, nil), + WanRxBroadcast: prometheus.NewDesc(ns+"wan_receive_broadcast_total", "WAN Receive Broadcast Total", labels, nil), + WanRxBytesR: prometheus.NewDesc(ns+"wan_receive_rate_bytes", "WAN Receive Bytes Rate", labels, nil), + WanRxMulticast: prometheus.NewDesc(ns+"wan_receive_multicast_total", "WAN Receive Multicast Total", labels, nil), + WanSpeed: prometheus.NewDesc(ns+"wan_speed_bps", "WAN Speed", labels, nil), + WanTxBroadcast: prometheus.NewDesc(ns+"wan_transmit_broadcast_total", "WAN Transmit Broadcast Total", labels, nil), + WanTxBytesR: prometheus.NewDesc(ns+"wan_transmit_rate_bytes", "WAN Transmit Bytes Rate", labels, nil), + WanTxDropped: prometheus.NewDesc(ns+"wan_transmit_dropped_total", "WAN Transmit Dropped Total", labels, nil), + WanTxErrors: prometheus.NewDesc(ns+"wan_transmit_errors_total", "WAN Transmit Errors Total", labels, nil), + WanTxMulticast: prometheus.NewDesc(ns+"wan_transmit_multicast_total", "WAN Transmit Multicast Total", labels, nil), + WanBytesR: prometheus.NewDesc(ns+"wan_rate_bytes", "WAN Transfer Rate", labels, nil), LanRxPackets: prometheus.NewDesc(ns+"lan_receive_packets_total", "LAN Receive Packets Total", labels, nil), LanRxBytes: prometheus.NewDesc(ns+"lan_receive_bytes_total", "LAN Receive Bytes Total", labels, nil), LanRxDropped: prometheus.NewDesc(ns+"lan_receive_dropped_total", "LAN Receive Dropped Total", labels, nil), LanTxPackets: prometheus.NewDesc(ns+"lan_transmit_packets_total", "LAN Transmit Packets Total", labels, nil), LanTxBytes: prometheus.NewDesc(ns+"lan_transmit_bytes_total", "LAN Transmit Bytes Total", labels, nil), - Latency: prometheus.NewDesc(ns+"speedtest_latency_seconds", "Speedtest Latency", labelWan, nil), - Runtime: prometheus.NewDesc(ns+"speedtest_runtime", "Speedtest Run Time", labelWan, nil), - XputDownload: prometheus.NewDesc(ns+"speedtest_download", "Speedtest Download Rate", labelWan, nil), - XputUpload: prometheus.NewDesc(ns+"speedtest_upload", "Speedtest Upload Rate", labelWan, nil), + Latency: prometheus.NewDesc(ns+"speedtest_latency_seconds", "Speedtest Latency", labels, nil), + Runtime: prometheus.NewDesc(ns+"speedtest_runtime", "Speedtest Run Time", labels, nil), + XputDownload: prometheus.NewDesc(ns+"speedtest_download", "Speedtest Download Rate", labels, nil), + XputUpload: prometheus.NewDesc(ns+"speedtest_upload", "Speedtest Upload Rate", labels, nil), } } -func (u *unifiCollector) exportUSGs(r report) { - if r.metrics() == nil || r.metrics().Devices == nil || len(r.metrics().Devices.USGs) < 1 { - return - } - r.add() - go func() { - defer r.done() - for _, d := range r.metrics().Devices.USGs { - u.exportUSG(r, d) - } - }() -} - func (u *unifiCollector) exportUSG(r report, d *unifi.USG) { labels := []string{d.IP, d.Version, d.Model, d.Serial, d.Type, d.Mac, d.SiteName, d.Name} // Gateway System Data. @@ -102,11 +90,12 @@ func (u *unifiCollector) exportUSG(r report, d *unifi.USG) { {u.Device.Mem, prometheus.GaugeValue, d.SystemStats.Mem, labels}, }) u.exportWANPorts(r, labels, d.Wan1, d.Wan2) - u.exportUSGstats(r, labels, d.SpeedtestStatus) + u.exportUSGstats(r, labels, d.Stat.Gw, d.SpeedtestStatus) } -func (u *unifiCollector) exportUSGstats(r report, labels []string, st unifi.SpeedtestStatus) { - labelWan := append([]string{"all"}, labels[6:]...) +func (u *unifiCollector) exportUSGstats(r report, labels []string, gw *unifi.Gw, st unifi.SpeedtestStatus) { + labelLan := []string{"lan", labels[6], labels[7]} + labelWan := []string{"all", labels[6], labels[7]} r.send([]*metricExports{ /* // Combined Port Stats {u.USG.WanRxPackets, prometheus.CounterValue, gw.WanRxPackets, labelWan}, @@ -115,12 +104,12 @@ func (u *unifiCollector) exportUSGstats(r report, labels []string, st unifi.Spee {u.USG.WanTxPackets, prometheus.CounterValue, gw.WanTxPackets, labelWan}, {u.USG.WanTxBytes, prometheus.CounterValue, gw.WanTxBytes, labelWan}, {u.USG.WanRxErrors, prometheus.CounterValue, gw.WanRxErrors, labelWan}, - {u.USG.LanRxPackets, prometheus.CounterValue, gw.LanRxPackets, labels}, - {u.USG.LanRxBytes, prometheus.CounterValue, gw.LanRxBytes, labels}, - {u.USG.LanTxPackets, prometheus.CounterValue, gw.LanTxPackets, labels}, - {u.USG.LanTxBytes, prometheus.CounterValue, gw.LanTxBytes, labels}, - {u.USG.LanRxDropped, prometheus.CounterValue, gw.LanRxDropped, labels}, */ + {u.USG.LanRxPackets, prometheus.CounterValue, gw.LanRxPackets, labelLan}, + {u.USG.LanRxBytes, prometheus.CounterValue, gw.LanRxBytes, labelLan}, + {u.USG.LanTxPackets, prometheus.CounterValue, gw.LanTxPackets, labelLan}, + {u.USG.LanTxBytes, prometheus.CounterValue, gw.LanTxBytes, labelLan}, + {u.USG.LanRxDropped, prometheus.CounterValue, gw.LanRxDropped, labelLan}, // Speed Test Stats {u.USG.Latency, prometheus.GaugeValue, st.Latency.Val / 1000, labelWan}, {u.USG.Runtime, prometheus.GaugeValue, st.Runtime, labelWan}, @@ -134,23 +123,23 @@ func (u *unifiCollector) exportWANPorts(r report, labels []string, wans ...unifi if !wan.Up.Val { continue // only record UP interfaces. } - l := append([]string{wan.Name}, labels[6:]...) + labelWan := []string{wan.Name, labels[6], labels[7]} r.send([]*metricExports{ - {u.USG.WanRxPackets, prometheus.CounterValue, wan.RxPackets, l}, - {u.USG.WanRxBytes, prometheus.CounterValue, wan.RxBytes, l}, - {u.USG.WanRxDropped, prometheus.CounterValue, wan.RxDropped, l}, - {u.USG.WanRxErrors, prometheus.CounterValue, wan.RxErrors, l}, - {u.USG.WanTxPackets, prometheus.CounterValue, wan.TxPackets, l}, - {u.USG.WanTxBytes, prometheus.CounterValue, wan.TxBytes, l}, - {u.USG.WanRxBroadcast, prometheus.CounterValue, wan.RxBroadcast, l}, - {u.USG.WanRxMulticast, prometheus.CounterValue, wan.RxMulticast, l}, - {u.USG.WanSpeed, prometheus.CounterValue, wan.Speed.Val * 1000000, l}, - {u.USG.WanTxBroadcast, prometheus.CounterValue, wan.TxBroadcast, l}, - {u.USG.WanTxBytesR, prometheus.CounterValue, wan.TxBytesR, l}, - {u.USG.WanTxDropped, prometheus.CounterValue, wan.TxDropped, l}, - {u.USG.WanTxErrors, prometheus.CounterValue, wan.TxErrors, l}, - {u.USG.WanTxMulticast, prometheus.CounterValue, wan.TxMulticast, l}, - {u.USG.WanBytesR, prometheus.GaugeValue, wan.BytesR, l}, + {u.USG.WanRxPackets, prometheus.CounterValue, wan.RxPackets, labelWan}, + {u.USG.WanRxBytes, prometheus.CounterValue, wan.RxBytes, labelWan}, + {u.USG.WanRxDropped, prometheus.CounterValue, wan.RxDropped, labelWan}, + {u.USG.WanRxErrors, prometheus.CounterValue, wan.RxErrors, labelWan}, + {u.USG.WanTxPackets, prometheus.CounterValue, wan.TxPackets, labelWan}, + {u.USG.WanTxBytes, prometheus.CounterValue, wan.TxBytes, labelWan}, + {u.USG.WanRxBroadcast, prometheus.CounterValue, wan.RxBroadcast, labelWan}, + {u.USG.WanRxMulticast, prometheus.CounterValue, wan.RxMulticast, labelWan}, + {u.USG.WanSpeed, prometheus.CounterValue, wan.Speed.Val * 1000000, labelWan}, + {u.USG.WanTxBroadcast, prometheus.CounterValue, wan.TxBroadcast, labelWan}, + {u.USG.WanTxBytesR, prometheus.CounterValue, wan.TxBytesR, labelWan}, + {u.USG.WanTxDropped, prometheus.CounterValue, wan.TxDropped, labelWan}, + {u.USG.WanTxErrors, prometheus.CounterValue, wan.TxErrors, labelWan}, + {u.USG.WanTxMulticast, prometheus.CounterValue, wan.TxMulticast, labelWan}, + {u.USG.WanBytesR, prometheus.GaugeValue, wan.BytesR, labelWan}, }) } } diff --git a/promunifi/usw.go b/promunifi/usw.go index 66d81ebc..b345323c 100644 --- a/promunifi/usw.go +++ b/promunifi/usw.go @@ -92,19 +92,6 @@ func descUSW(ns string) *usw { } } -func (u *unifiCollector) exportUSWs(r report) { - if r.metrics() == nil || r.metrics().Devices == nil || len(r.metrics().Devices.USWs) < 1 { - return - } - r.add() - go func() { - defer r.done() - for _, d := range r.metrics().Devices.USWs { - u.exportUSW(r, d) - } - }() -} - func (u *unifiCollector) exportUSW(r report, d *unifi.USW) { labels := []string{d.IP, d.Version, d.Model, d.Serial, d.Type, d.Mac, d.SiteName, d.Name} if d.HasTemperature.Val { @@ -166,31 +153,31 @@ func (u *unifiCollector) exportPortTable(r report, labels []string, pt []unifi.P continue } // Copy labels, and add four new ones. - l := append([]string{p.PortIdx.Txt, p.Name, p.Mac, p.IP}, labels[6:]...) + labelP := []string{p.PortIdx.Txt, p.Name, p.Mac, p.IP, labels[6], labels[7]} if p.PoeEnable.Val && p.PortPoe.Val { r.send([]*metricExports{ - {u.USW.PoeCurrent, prometheus.GaugeValue, p.PoeCurrent, l}, - {u.USW.PoePower, prometheus.GaugeValue, p.PoePower, l}, - {u.USW.PoeVoltage, prometheus.GaugeValue, p.PoeVoltage, l}, + {u.USW.PoeCurrent, prometheus.GaugeValue, p.PoeCurrent, labelP}, + {u.USW.PoePower, prometheus.GaugeValue, p.PoePower, labelP}, + {u.USW.PoeVoltage, prometheus.GaugeValue, p.PoeVoltage, labelP}, }) } r.send([]*metricExports{ - {u.USW.RxBroadcast, prometheus.CounterValue, p.RxBroadcast, l}, - {u.USW.RxBytes, prometheus.CounterValue, p.RxBytes, l}, - {u.USW.RxBytesR, prometheus.GaugeValue, p.RxBytesR, l}, - {u.USW.RxDropped, prometheus.CounterValue, p.RxDropped, l}, - {u.USW.RxErrors, prometheus.CounterValue, p.RxErrors, l}, - {u.USW.RxMulticast, prometheus.CounterValue, p.RxMulticast, l}, - {u.USW.RxPackets, prometheus.CounterValue, p.RxPackets, l}, - {u.USW.Satisfaction, prometheus.GaugeValue, p.Satisfaction, l}, - {u.USW.Speed, prometheus.GaugeValue, p.Speed.Val * 1000000, l}, - {u.USW.TxBroadcast, prometheus.CounterValue, p.TxBroadcast, l}, - {u.USW.TxBytes, prometheus.CounterValue, p.TxBytes, l}, - {u.USW.TxBytesR, prometheus.GaugeValue, p.TxBytesR, l}, - {u.USW.TxDropped, prometheus.CounterValue, p.TxDropped, l}, - {u.USW.TxErrors, prometheus.CounterValue, p.TxErrors, l}, - {u.USW.TxMulticast, prometheus.CounterValue, p.TxMulticast, l}, + {u.USW.RxBroadcast, prometheus.CounterValue, p.RxBroadcast, labelP}, + {u.USW.RxBytes, prometheus.CounterValue, p.RxBytes, labelP}, + {u.USW.RxBytesR, prometheus.GaugeValue, p.RxBytesR, labelP}, + {u.USW.RxDropped, prometheus.CounterValue, p.RxDropped, labelP}, + {u.USW.RxErrors, prometheus.CounterValue, p.RxErrors, labelP}, + {u.USW.RxMulticast, prometheus.CounterValue, p.RxMulticast, labelP}, + {u.USW.RxPackets, prometheus.CounterValue, p.RxPackets, labelP}, + {u.USW.Satisfaction, prometheus.GaugeValue, p.Satisfaction, labelP}, + {u.USW.Speed, prometheus.GaugeValue, p.Speed.Val * 1000000, labelP}, + {u.USW.TxBroadcast, prometheus.CounterValue, p.TxBroadcast, labelP}, + {u.USW.TxBytes, prometheus.CounterValue, p.TxBytes, labelP}, + {u.USW.TxBytesR, prometheus.GaugeValue, p.TxBytesR, labelP}, + {u.USW.TxDropped, prometheus.CounterValue, p.TxDropped, labelP}, + {u.USW.TxErrors, prometheus.CounterValue, p.TxErrors, labelP}, + {u.USW.TxMulticast, prometheus.CounterValue, p.TxMulticast, labelP}, }) } }