From 68763d24c4573b740c554a70bce2132334d56613 Mon Sep 17 00:00:00 2001 From: Yonatan Komornik <11005061+yoniko@users.noreply.github.com> Date: Thu, 27 Jul 2023 02:06:23 -0700 Subject: [PATCH] New client metrics (#75) * Build binary in Dockerfile * Add missing client metrics * CR fixes + some refactoring * Removed `wifi_mode_fmt` and labels bugfixes --- Dockerfile | 15 ++++-- go.sum | 2 + pkg/api/client.go | 5 ++ pkg/collector/client.go | 106 +++++++++++++++++++++++++++++++++++----- 4 files changed, 113 insertions(+), 15 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2d70db9..2493e79 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,14 @@ -FROM golang:alpine3.14 +FROM golang:alpine3.14 AS build -COPY omada-exporter /usr/bin/omada-exporter +WORKDIR /src +COPY go.mod ./ +COPY go.sum ./ +RUN go mod download +COPY main.go ./ +COPY cmd ./cmd +COPY pkg ./pkg +RUN go build -o /omada-exporter -CMD ["/usr/bin/omada-exporter"] +FROM golang:alpine3.14 +COPY --from=build /omada-exporter /omada-exporter +CMD "/omada-exporter" diff --git a/go.sum b/go.sum index 25b01e4..df6ae90 100644 --- a/go.sum +++ b/go.sum @@ -218,6 +218,7 @@ github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeD github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.9.0 h1:Rrch9mh17XcxvEu9D9DEpb4isxjGBtcevQjKvxPRQIU= github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU= +github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -270,6 +271,7 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= diff --git a/pkg/api/client.go b/pkg/api/client.go index fd2baf4..e08aba4 100644 --- a/pkg/api/client.go +++ b/pkg/api/client.go @@ -104,4 +104,9 @@ type NetworkClient struct { SignalLevel float64 `json:"signalLevel"` WifiMode float64 `json:"wifiMode"` Ssid string `json:"ssid"` + Rssi float64 `json:"rssi"` + TrafficDown float64 `json:"trafficDown"` + TrafficUp float64 `json:"trafficUp"` + RxRate float64 `json:"rxRate"` + TxRate float64 `json:"txRate"` } diff --git a/pkg/collector/client.go b/pkg/collector/client.go index 032af98..d2fee39 100644 --- a/pkg/collector/client.go +++ b/pkg/collector/client.go @@ -11,6 +11,11 @@ import ( type clientCollector struct { omadaClientDownloadActivityBytes *prometheus.Desc omadaClientSignalDbm *prometheus.Desc + omadaClientRssiDbm *prometheus.Desc + omadaClientTrafficDown *prometheus.Desc + omadaClientTrafficUp *prometheus.Desc + omadaClientTxRate *prometheus.Desc + omadaClientRxRate *prometheus.Desc omadaClientConnectedTotal *prometheus.Desc client *api.Client } @@ -18,9 +23,32 @@ type clientCollector struct { func (c *clientCollector) Describe(ch chan<- *prometheus.Desc) { ch <- c.omadaClientDownloadActivityBytes ch <- c.omadaClientSignalDbm + ch <- c.omadaClientRssiDbm + ch <- c.omadaClientTrafficDown + ch <- c.omadaClientTrafficUp + ch <- c.omadaClientTxRate + ch <- c.omadaClientRxRate ch <- c.omadaClientConnectedTotal } +func FormatWifiMode(wifiMode int) string { + mapping := map[int]string { + 0: "802.11a", + 1: "802.11b", + 2: "802.11g", + 3: "802.11na", + 4: "802.11ng", + 5: "802.11ac", + 6: "802.11axa", + 7: "802.11axg", + } + formatted, ok := mapping[wifiMode] + if !ok { + return "" + } + return formatted +} + func (c *clientCollector) Collect(ch chan<- prometheus.Metric) { client := c.client config := c.client.Config @@ -32,46 +60,100 @@ func (c *clientCollector) Collect(ch chan<- prometheus.Metric) { return } - ch <- prometheus.MustNewConstMetric(c.omadaClientConnectedTotal, prometheus.GaugeValue, float64(len(clients)), - site, client.SiteId) + totals := map[string]int{} for _, item := range clients { vlanId := fmt.Sprintf("%.0f", item.VlanId) port := fmt.Sprintf("%.0f", item.Port) if item.Wireless { - wifiMode := fmt.Sprintf("%.0f", item.WifiMode) - ch <- prometheus.MustNewConstMetric(c.omadaClientDownloadActivityBytes, prometheus.GaugeValue, item.Activity, - item.HostName, item.Vendor, "", "", item.Ip, item.Mac, site, client.SiteId, item.ApName, item.Ssid, wifiMode) + wifiMode := FormatWifiMode(int(item.WifiMode)) + + CollectWirelessMetrics := func(desc *prometheus.Desc, valueType prometheus.ValueType, value float64) { + ch <- prometheus.MustNewConstMetric(desc, valueType, value, + item.HostName, item.Vendor, item.Ip, item.Mac, site, client.SiteId, "wireless", wifiMode, item.ApName, item.Ssid) + } + CollectWirelessMetrics(c.omadaClientSignalDbm, prometheus.GaugeValue, -item.SignalLevel) + CollectWirelessMetrics(c.omadaClientRssiDbm, prometheus.GaugeValue, item.Rssi) + CollectWirelessMetrics(c.omadaClientTrafficDown, prometheus.CounterValue, item.TrafficDown) + CollectWirelessMetrics(c.omadaClientTrafficUp, prometheus.CounterValue, item.TrafficUp) + CollectWirelessMetrics(c.omadaClientTxRate, prometheus.GaugeValue, item.TxRate) + CollectWirelessMetrics(c.omadaClientRxRate, prometheus.GaugeValue, item.RxRate) - ch <- prometheus.MustNewConstMetric(c.omadaClientSignalDbm, prometheus.GaugeValue, -item.SignalLevel, - item.HostName, item.Vendor, item.Ip, item.Mac, item.ApName, site, client.SiteId, item.Ssid, wifiMode) + totals[wifiMode] += 1 + ch <- prometheus.MustNewConstMetric(c.omadaClientDownloadActivityBytes, prometheus.GaugeValue, item.Activity, + item.HostName, item.Vendor, item.Ip, item.Mac, site, client.SiteId, "wireless", wifiMode, item.ApName, item.Ssid, "", "") } if !item.Wireless { + totals["wired"] += 1 ch <- prometheus.MustNewConstMetric(c.omadaClientDownloadActivityBytes, prometheus.GaugeValue, item.Activity, - item.HostName, item.Vendor, port, vlanId, item.Ip, item.Mac, site, client.SiteId, "", "", "") + item.HostName, item.Vendor, item.Ip, item.Mac, site, client.SiteId, "wired", "", "", "", port, vlanId) + } + } + + for connectionModeFmt, v := range totals { + if connectionModeFmt == "wired" { + ch <- prometheus.MustNewConstMetric(c.omadaClientConnectedTotal, prometheus.GaugeValue, float64(v), + site, client.SiteId, "wired", "") + } else { + ch <- prometheus.MustNewConstMetric(c.omadaClientConnectedTotal, prometheus.GaugeValue, float64(v), + site, client.SiteId, "wireless", connectionModeFmt) } } } func NewClientCollector(c *api.Client) *clientCollector { + client_labels := []string{"client", "vendor", "ip", "mac", "site", "site_id", "connection_mode", "wifi_mode", "ap_name", "ssid"} + wired_client_labels := append(client_labels, "switch_port", "vlan_id") + return &clientCollector{ omadaClientDownloadActivityBytes: prometheus.NewDesc("omada_client_download_activity_bytes", "The current download activity for the client in bytes.", - []string{"client", "vendor", "switch_port", "vlan_id", "ip", "mac", "site", "site_id", "ap_name", "ssid", "wifi_mode"}, + wired_client_labels, nil, ), omadaClientSignalDbm: prometheus.NewDesc("omada_client_signal_dbm", - "The signal level for the wireless client in dBm.", - []string{"client", "vendor", "ip", "mac", "ap_name", "site", "site_id", "ssid", "wifi_mode"}, + "The noise level for the wireless client in dBm.", + client_labels, + nil, + ), + + omadaClientRssiDbm: prometheus.NewDesc("omada_client_rssi_dbm", + "The RSSI for the wireless client in dBm.", + client_labels, + nil, + ), + + omadaClientTrafficDown: prometheus.NewDesc("omada_client_traffic_down_bytes", + "Total bytes received by wireless client.", + client_labels, + nil, + ), + + omadaClientTrafficUp: prometheus.NewDesc("omada_client_traffic_up_bytes", + "Total bytes sent by wireless client.", + client_labels, + nil, + ), + + omadaClientTxRate: prometheus.NewDesc("omada_client_tx_rate", + "TX rate of wireless client.", + client_labels, + nil, + ), + + omadaClientRxRate: prometheus.NewDesc("omada_client_rx_rate", + "RX rate of wireless client.", + client_labels, nil, ), omadaClientConnectedTotal: prometheus.NewDesc("omada_client_connected_total", "Total number of connected clients.", - []string{"site", "site_id"}, + []string{"site", "site_id", "connection_mode", "wifi_mode"}, nil, ), + client: c, } }