Skip to content

Commit ebe142d

Browse files
authored
✨ Add per-port rx and tx metrics for switches (#71)
* ✨ Add per-port rx and tx metrics for switches * 🎨 add some DRY compliance for extensively repeated labels * advertise ap rx and tx as counters, not gauges * Add name label on switch port metrics
1 parent 3943609 commit ebe142d

File tree

4 files changed

+55
-50
lines changed

4 files changed

+55
-50
lines changed

README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ __There's also a GHCR mirror available if you'd prefer to not use Docker Hub. `g
3737
helm repo add charlie-haley http://charts.charliehaley.dev
3838
helm repo update
3939
helm install omada-exporter charlie-haley/omada-exporter \
40-
--set omada.host=https://192.1.1.20 \
40+
--set omada.host=https://192.1.1.20 \
4141
--set omada.username=exporter \
4242
--set omada.password=mypassword \
4343
--set omada.site=Default \
@@ -121,9 +121,11 @@ Name|Description|Labels
121121
omada_device_poe_remain_watts | The remaining amount of PoE power for the device in watts. | device, model, version, ip, mac, site, site_id, device_type
122122
omada_client_download_activity_bytes | The current download activity for the client in bytes. | client, vendor, switch_port, vlan_id, ip, mac, site, site_id, ap_name, ssid, wifi_mode
123123
omada_client_signal_dbm | The signal level for the wireless client in dBm. | client, vendor, ip, mac, ap_name, site, site_id, ssid, wifi_mode
124-
omada_port_power_watts | The current PoE usage of the port in watts. | device, device_mac, client, vendor, switch_port, switch_mac, switch_id, vlan_id, profile, site, site_id
125-
omada_port_link_status | A boolean representing the link status of the port. | device, device_mac, client, vendor, switch_port, switch_mac, switch_id, vlan_id, profile, site, site_id
126-
omada_port_link_speed_mbps | Port link speed in mbps. This is the capability of the connection, not the active throughput. | device, device_mac, client, vendor, switch_port, switch_mac, switch_id, vlan_id, profile, site, site_id
124+
omada_port_power_watts | The current PoE usage of the port in watts. | device, device_mac, client, vendor, switch_port, name, switch_mac, switch_id, vlan_id, profile, site, site_id
125+
omada_port_link_status | A boolean representing the link status of the port. | device, device_mac, client, vendor, switch_port, name, switch_mac, switch_id, vlan_id, profile, site, site_id
126+
omada_port_link_speed_mbps | Port link speed in mbps. This is the capability of the connection, not the active throughput. | device, device_mac, client, vendor, switch_port, name, switch_mac, switch_id, vlan_id, profile, site, site_id
127+
omada_port_link_rx | Bytes recieved on a port. | device, device_mac, client, vendor, switch_port, name, switch_mac, switch_id, vlan_id, profile, site, site_id
128+
omada_port_link_tx | Bytes transmitted on a port. | device, device_mac, client, vendor, switch_port, name, switch_mac, switch_id, vlan_id, profile, site, site_id
127129
omada_controller_uptime_seconds | Uptime of the controller. | controller_name, model, controller_version, firmware_version, mac
128130
omada_controller_storage_used_bytes | Storage used on the controller. | storage_name, controller_name, model, controller_version, firmware_version, mac
129131
omada_controller_storage_available_bytes | Total storage available for the controller. | storage_name, controller_name, model, controller_version, firmware_version, mac

pkg/api/port.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,6 @@ type portStatus struct {
6666
LinkSpeed float64 `json:"linkSpeed"`
6767
PoePower float64 `json:"poePower"`
6868
Poe bool `json:"poe"`
69+
Rx float64 `json:"rx"`
70+
Tx float64 `json:"tx"`
6971
}

pkg/collector/device.go

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -44,67 +44,59 @@ func (c *deviceCollector) Collect(ch chan<- prometheus.Metric) {
4444
if item.NeedUpgrade {
4545
needUpgrade = 1
4646
}
47-
ch <- prometheus.MustNewConstMetric(c.omadaDeviceUptimeSeconds, prometheus.GaugeValue, item.Uptime,
48-
item.Name, item.Model, item.Version, item.Ip, item.Mac, site, client.SiteId, item.Type)
49-
50-
ch <- prometheus.MustNewConstMetric(c.omadaDeviceCpuPercentage, prometheus.GaugeValue, item.CpuUtil,
51-
item.Name, item.Model, item.Version, item.Ip, item.Mac, site, client.SiteId, item.Type)
52-
53-
ch <- prometheus.MustNewConstMetric(c.omadaDeviceMemPercentage, prometheus.GaugeValue, item.MemUtil,
54-
item.Name, item.Model, item.Version, item.Ip, item.Mac, site, client.SiteId, item.Type)
55-
56-
ch <- prometheus.MustNewConstMetric(c.omadaDeviceNeedUpgrade, prometheus.GaugeValue, needUpgrade,
57-
item.Name, item.Model, item.Version, item.Ip, item.Mac, site, client.SiteId, item.Type)
47+
labels := []string{item.Name, item.Model, item.Version, item.Ip, item.Mac, site, client.SiteId, item.Type}
5848

49+
ch <- prometheus.MustNewConstMetric(c.omadaDeviceUptimeSeconds, prometheus.GaugeValue, item.Uptime, labels...)
50+
ch <- prometheus.MustNewConstMetric(c.omadaDeviceCpuPercentage, prometheus.GaugeValue, item.CpuUtil, labels...)
51+
ch <- prometheus.MustNewConstMetric(c.omadaDeviceMemPercentage, prometheus.GaugeValue, item.MemUtil, labels...)
52+
ch <- prometheus.MustNewConstMetric(c.omadaDeviceNeedUpgrade, prometheus.GaugeValue, needUpgrade, labels...)
5953
if item.Type == "ap" {
60-
ch <- prometheus.MustNewConstMetric(c.omadaDeviceTxRate, prometheus.GaugeValue, item.TxRate,
61-
item.Name, item.Model, item.Version, item.Ip, item.Mac, site, client.SiteId, item.Type)
62-
63-
ch <- prometheus.MustNewConstMetric(c.omadaDeviceRxRate, prometheus.GaugeValue, item.RxRate,
64-
item.Name, item.Model, item.Version, item.Ip, item.Mac, site, client.SiteId, item.Type)
54+
ch <- prometheus.MustNewConstMetric(c.omadaDeviceTxRate, prometheus.CounterValue, item.TxRate, labels...)
55+
ch <- prometheus.MustNewConstMetric(c.omadaDeviceRxRate, prometheus.CounterValue, item.RxRate, labels...)
6556
}
6657
if item.Type == "switch" {
67-
ch <- prometheus.MustNewConstMetric(c.omadaDevicePoeRemainWatts, prometheus.GaugeValue, item.PoeRemain,
68-
item.Name, item.Model, item.Version, item.Ip, item.Mac, site, client.SiteId, item.Type)
58+
ch <- prometheus.MustNewConstMetric(c.omadaDevicePoeRemainWatts, prometheus.GaugeValue, item.PoeRemain, labels...)
6959
}
7060
}
7161
}
7262

7363
func NewDeviceCollector(c *api.Client) *deviceCollector {
64+
labels := []string{"device", "model", "version", "ip", "mac", "site", "site_id", "device_type"}
65+
7466
return &deviceCollector{
7567
omadaDeviceUptimeSeconds: prometheus.NewDesc("omada_device_uptime_seconds",
7668
"Uptime of the device.",
77-
[]string{"device", "model", "version", "ip", "mac", "site", "site_id", "device_type"},
69+
labels,
7870
nil,
7971
),
8072
omadaDeviceCpuPercentage: prometheus.NewDesc("omada_device_cpu_percentage",
8173
"Percentage of device CPU used.",
82-
[]string{"device", "model", "version", "ip", "mac", "site", "site_id", "device_type"},
74+
labels,
8375
nil,
8476
),
8577
omadaDeviceMemPercentage: prometheus.NewDesc("omada_device_mem_percentage",
8678
"Percentage of device Memory used.",
87-
[]string{"device", "model", "version", "ip", "mac", "site", "site_id", "device_type"},
79+
labels,
8880
nil,
8981
),
9082
omadaDeviceNeedUpgrade: prometheus.NewDesc("omada_device_need_upgrade",
9183
"A boolean on whether the device needs an upgrade.",
92-
[]string{"device", "model", "version", "ip", "mac", "site", "site_id", "device_type"},
84+
labels,
9385
nil,
9486
),
9587
omadaDeviceTxRate: prometheus.NewDesc("omada_device_tx_rate",
9688
"The tx rate of the device.",
97-
[]string{"device", "model", "version", "ip", "mac", "site", "site_id", "device_type"},
89+
labels,
9890
nil,
9991
),
10092
omadaDeviceRxRate: prometheus.NewDesc("omada_device_rx_rate",
10193
"The rx rate of the device.",
102-
[]string{"device", "model", "version", "ip", "mac", "site", "site_id", "device_type"},
94+
labels,
10395
nil,
10496
),
10597
omadaDevicePoeRemainWatts: prometheus.NewDesc("omada_device_poe_remain_watts",
10698
"The remaining amount of PoE power for the device in watts.",
107-
[]string{"device", "model", "version", "ip", "mac", "site", "site_id", "device_type"},
99+
labels,
108100
nil,
109101
),
110102
client: c,

pkg/collector/port.go

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,17 @@ type portCollector struct {
1212
omadaPortPowerWatts *prometheus.Desc
1313
omadaPortLinkStatus *prometheus.Desc
1414
omadaPortLinkSpeedMbps *prometheus.Desc
15+
omadaPortLinkRx *prometheus.Desc
16+
omadaPortLinkTx *prometheus.Desc
1517
client *api.Client
1618
}
1719

1820
func (c *portCollector) Describe(ch chan<- *prometheus.Desc) {
1921
ch <- c.omadaPortPowerWatts
2022
ch <- c.omadaPortLinkStatus
2123
ch <- c.omadaPortLinkSpeedMbps
24+
ch <- c.omadaPortLinkRx
25+
ch <- c.omadaPortLinkTx
2226
}
2327

2428
func (c *portCollector) Collect(ch chan<- prometheus.Metric) {
@@ -38,6 +42,7 @@ func (c *portCollector) Collect(ch chan<- prometheus.Metric) {
3842
// duplicate ports to prevent this error.
3943
ports := removeDuplicates(device.Ports)
4044
for _, p := range ports {
45+
var cHostName, cVendor, cVlanID string
4146
linkSpeed := getPortByLinkSpeed(p.PortStatus.LinkSpeed)
4247

4348
portClient, err := client.GetClientByPort(device.Mac, p.Port)
@@ -47,26 +52,18 @@ func (c *portCollector) Collect(ch chan<- prometheus.Metric) {
4752

4853
port := fmt.Sprintf("%.0f", p.Port)
4954
if portClient != nil {
50-
vlanId := fmt.Sprintf("%.0f", portClient.VlanId)
51-
52-
ch <- prometheus.MustNewConstMetric(c.omadaPortPowerWatts, prometheus.GaugeValue, p.PortStatus.PoePower,
53-
device.Name, device.Mac, portClient.HostName, portClient.Vendor, port, p.SwitchMac, p.SwitchId, vlanId, p.ProfileName, site, client.SiteId)
54-
55-
ch <- prometheus.MustNewConstMetric(c.omadaPortLinkStatus, prometheus.GaugeValue, p.PortStatus.LinkStatus,
56-
device.Name, device.Mac, portClient.HostName, portClient.Vendor, port, p.SwitchMac, p.SwitchId, vlanId, p.ProfileName, site, client.SiteId)
57-
58-
ch <- prometheus.MustNewConstMetric(c.omadaPortLinkSpeedMbps, prometheus.GaugeValue, linkSpeed,
59-
device.Name, device.Mac, portClient.HostName, portClient.Vendor, port, p.SwitchMac, p.SwitchId, vlanId, p.ProfileName, site, client.SiteId)
60-
} else {
61-
ch <- prometheus.MustNewConstMetric(c.omadaPortPowerWatts, prometheus.GaugeValue, p.PortStatus.PoePower,
62-
device.Name, device.Mac, "", "", port, p.SwitchMac, p.SwitchId, "", p.ProfileName, site, client.SiteId)
55+
cHostName = portClient.HostName
56+
cVendor = portClient.Vendor
57+
cVlanID = fmt.Sprintf("%.0f", portClient.VlanId)
58+
}
6359

64-
ch <- prometheus.MustNewConstMetric(c.omadaPortLinkStatus, prometheus.GaugeValue, p.PortStatus.LinkStatus,
65-
device.Name, device.Mac, "", "", port, p.SwitchMac, p.SwitchId, "", p.ProfileName, site, client.SiteId)
60+
labels := []string{device.Name, device.Mac, cHostName, cVendor, port, p.Name, p.SwitchMac, p.SwitchId, cVlanID, p.ProfileName, site, client.SiteId}
6661

67-
ch <- prometheus.MustNewConstMetric(c.omadaPortLinkSpeedMbps, prometheus.GaugeValue, linkSpeed,
68-
device.Name, device.Mac, "", "", port, p.SwitchMac, p.SwitchId, "", p.ProfileName, site, client.SiteId)
69-
}
62+
ch <- prometheus.MustNewConstMetric(c.omadaPortPowerWatts, prometheus.GaugeValue, p.PortStatus.PoePower, labels...)
63+
ch <- prometheus.MustNewConstMetric(c.omadaPortLinkStatus, prometheus.GaugeValue, p.PortStatus.LinkStatus, labels...)
64+
ch <- prometheus.MustNewConstMetric(c.omadaPortLinkSpeedMbps, prometheus.GaugeValue, linkSpeed, labels...)
65+
ch <- prometheus.MustNewConstMetric(c.omadaPortLinkRx, prometheus.CounterValue, p.PortStatus.Rx, labels...)
66+
ch <- prometheus.MustNewConstMetric(c.omadaPortLinkTx, prometheus.CounterValue, p.PortStatus.Tx, labels...)
7067
}
7168
}
7269
}
@@ -107,20 +104,32 @@ func removeDuplicates(s []api.Port) []api.Port {
107104
}
108105

109106
func NewPortCollector(c *api.Client) *portCollector {
107+
labels := []string{"device", "device_mac", "client", "vendor", "switch_port", "name", "switch_mac", "switch_id", "vlan_id", "profile", "site", "site_id"}
108+
110109
return &portCollector{
111110
omadaPortPowerWatts: prometheus.NewDesc("omada_port_power_watts",
112111
"The current PoE usage of the port in watts.",
113-
[]string{"device", "device_mac", "client", "vendor", "switch_port", "switch_mac", "switch_id", "vlan_id", "profile", "site", "site_id"},
112+
labels,
114113
nil,
115114
),
116115
omadaPortLinkStatus: prometheus.NewDesc("omada_port_link_status",
117116
"A boolean representing the link status of the port.",
118-
[]string{"device", "device_mac", "client", "vendor", "switch_port", "switch_mac", "switch_id", "vlan_id", "profile", "site", "site_id"},
117+
labels,
119118
nil,
120119
),
121120
omadaPortLinkSpeedMbps: prometheus.NewDesc("omada_port_link_speed_mbps",
122121
"Port link speed in mbps. This is the capability of the connection, not the active throughput.",
123-
[]string{"device", "device_mac", "client", "vendor", "switch_port", "switch_mac", "switch_id", "vlan_id", "profile", "site", "site_id"},
122+
labels,
123+
nil,
124+
),
125+
omadaPortLinkRx: prometheus.NewDesc("omada_port_link_rx",
126+
"Bytes recieved on a port.",
127+
labels,
128+
nil,
129+
),
130+
omadaPortLinkTx: prometheus.NewDesc("omada_port_link_tx",
131+
"Bytes transmitted on a port.",
132+
labels,
124133
nil,
125134
),
126135
client: c,

0 commit comments

Comments
 (0)