Skip to content

Commit

Permalink
✨ Add per-port rx and tx metrics for switches (#71)
Browse files Browse the repository at this point in the history
* ✨ 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
  • Loading branch information
jfieber authored Jul 4, 2023
1 parent 3943609 commit ebe142d
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 50 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ __There's also a GHCR mirror available if you'd prefer to not use Docker Hub. `g
helm repo add charlie-haley http://charts.charliehaley.dev
helm repo update
helm install omada-exporter charlie-haley/omada-exporter \
--set omada.host=https://192.1.1.20 \
--set omada.host=https://192.1.1.20 \
--set omada.username=exporter \
--set omada.password=mypassword \
--set omada.site=Default \
Expand Down Expand Up @@ -121,9 +121,11 @@ Name|Description|Labels
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
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
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
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
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
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
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
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
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
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
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
omada_controller_uptime_seconds | Uptime of the controller. | controller_name, model, controller_version, firmware_version, mac
omada_controller_storage_used_bytes | Storage used on the controller. | storage_name, controller_name, model, controller_version, firmware_version, mac
omada_controller_storage_available_bytes | Total storage available for the controller. | storage_name, controller_name, model, controller_version, firmware_version, mac
Expand Down
2 changes: 2 additions & 0 deletions pkg/api/port.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,6 @@ type portStatus struct {
LinkSpeed float64 `json:"linkSpeed"`
PoePower float64 `json:"poePower"`
Poe bool `json:"poe"`
Rx float64 `json:"rx"`
Tx float64 `json:"tx"`
}
42 changes: 17 additions & 25 deletions pkg/collector/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,67 +44,59 @@ func (c *deviceCollector) Collect(ch chan<- prometheus.Metric) {
if item.NeedUpgrade {
needUpgrade = 1
}
ch <- prometheus.MustNewConstMetric(c.omadaDeviceUptimeSeconds, prometheus.GaugeValue, item.Uptime,
item.Name, item.Model, item.Version, item.Ip, item.Mac, site, client.SiteId, item.Type)

ch <- prometheus.MustNewConstMetric(c.omadaDeviceCpuPercentage, prometheus.GaugeValue, item.CpuUtil,
item.Name, item.Model, item.Version, item.Ip, item.Mac, site, client.SiteId, item.Type)

ch <- prometheus.MustNewConstMetric(c.omadaDeviceMemPercentage, prometheus.GaugeValue, item.MemUtil,
item.Name, item.Model, item.Version, item.Ip, item.Mac, site, client.SiteId, item.Type)

ch <- prometheus.MustNewConstMetric(c.omadaDeviceNeedUpgrade, prometheus.GaugeValue, needUpgrade,
item.Name, item.Model, item.Version, item.Ip, item.Mac, site, client.SiteId, item.Type)
labels := []string{item.Name, item.Model, item.Version, item.Ip, item.Mac, site, client.SiteId, item.Type}

ch <- prometheus.MustNewConstMetric(c.omadaDeviceUptimeSeconds, prometheus.GaugeValue, item.Uptime, labels...)
ch <- prometheus.MustNewConstMetric(c.omadaDeviceCpuPercentage, prometheus.GaugeValue, item.CpuUtil, labels...)
ch <- prometheus.MustNewConstMetric(c.omadaDeviceMemPercentage, prometheus.GaugeValue, item.MemUtil, labels...)
ch <- prometheus.MustNewConstMetric(c.omadaDeviceNeedUpgrade, prometheus.GaugeValue, needUpgrade, labels...)
if item.Type == "ap" {
ch <- prometheus.MustNewConstMetric(c.omadaDeviceTxRate, prometheus.GaugeValue, item.TxRate,
item.Name, item.Model, item.Version, item.Ip, item.Mac, site, client.SiteId, item.Type)

ch <- prometheus.MustNewConstMetric(c.omadaDeviceRxRate, prometheus.GaugeValue, item.RxRate,
item.Name, item.Model, item.Version, item.Ip, item.Mac, site, client.SiteId, item.Type)
ch <- prometheus.MustNewConstMetric(c.omadaDeviceTxRate, prometheus.CounterValue, item.TxRate, labels...)
ch <- prometheus.MustNewConstMetric(c.omadaDeviceRxRate, prometheus.CounterValue, item.RxRate, labels...)
}
if item.Type == "switch" {
ch <- prometheus.MustNewConstMetric(c.omadaDevicePoeRemainWatts, prometheus.GaugeValue, item.PoeRemain,
item.Name, item.Model, item.Version, item.Ip, item.Mac, site, client.SiteId, item.Type)
ch <- prometheus.MustNewConstMetric(c.omadaDevicePoeRemainWatts, prometheus.GaugeValue, item.PoeRemain, labels...)
}
}
}

func NewDeviceCollector(c *api.Client) *deviceCollector {
labels := []string{"device", "model", "version", "ip", "mac", "site", "site_id", "device_type"}

return &deviceCollector{
omadaDeviceUptimeSeconds: prometheus.NewDesc("omada_device_uptime_seconds",
"Uptime of the device.",
[]string{"device", "model", "version", "ip", "mac", "site", "site_id", "device_type"},
labels,
nil,
),
omadaDeviceCpuPercentage: prometheus.NewDesc("omada_device_cpu_percentage",
"Percentage of device CPU used.",
[]string{"device", "model", "version", "ip", "mac", "site", "site_id", "device_type"},
labels,
nil,
),
omadaDeviceMemPercentage: prometheus.NewDesc("omada_device_mem_percentage",
"Percentage of device Memory used.",
[]string{"device", "model", "version", "ip", "mac", "site", "site_id", "device_type"},
labels,
nil,
),
omadaDeviceNeedUpgrade: prometheus.NewDesc("omada_device_need_upgrade",
"A boolean on whether the device needs an upgrade.",
[]string{"device", "model", "version", "ip", "mac", "site", "site_id", "device_type"},
labels,
nil,
),
omadaDeviceTxRate: prometheus.NewDesc("omada_device_tx_rate",
"The tx rate of the device.",
[]string{"device", "model", "version", "ip", "mac", "site", "site_id", "device_type"},
labels,
nil,
),
omadaDeviceRxRate: prometheus.NewDesc("omada_device_rx_rate",
"The rx rate of the device.",
[]string{"device", "model", "version", "ip", "mac", "site", "site_id", "device_type"},
labels,
nil,
),
omadaDevicePoeRemainWatts: prometheus.NewDesc("omada_device_poe_remain_watts",
"The remaining amount of PoE power for the device in watts.",
[]string{"device", "model", "version", "ip", "mac", "site", "site_id", "device_type"},
labels,
nil,
),
client: c,
Expand Down
51 changes: 30 additions & 21 deletions pkg/collector/port.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,17 @@ type portCollector struct {
omadaPortPowerWatts *prometheus.Desc
omadaPortLinkStatus *prometheus.Desc
omadaPortLinkSpeedMbps *prometheus.Desc
omadaPortLinkRx *prometheus.Desc
omadaPortLinkTx *prometheus.Desc
client *api.Client
}

func (c *portCollector) Describe(ch chan<- *prometheus.Desc) {
ch <- c.omadaPortPowerWatts
ch <- c.omadaPortLinkStatus
ch <- c.omadaPortLinkSpeedMbps
ch <- c.omadaPortLinkRx
ch <- c.omadaPortLinkTx
}

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

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

port := fmt.Sprintf("%.0f", p.Port)
if portClient != nil {
vlanId := fmt.Sprintf("%.0f", portClient.VlanId)

ch <- prometheus.MustNewConstMetric(c.omadaPortPowerWatts, prometheus.GaugeValue, p.PortStatus.PoePower,
device.Name, device.Mac, portClient.HostName, portClient.Vendor, port, p.SwitchMac, p.SwitchId, vlanId, p.ProfileName, site, client.SiteId)

ch <- prometheus.MustNewConstMetric(c.omadaPortLinkStatus, prometheus.GaugeValue, p.PortStatus.LinkStatus,
device.Name, device.Mac, portClient.HostName, portClient.Vendor, port, p.SwitchMac, p.SwitchId, vlanId, p.ProfileName, site, client.SiteId)

ch <- prometheus.MustNewConstMetric(c.omadaPortLinkSpeedMbps, prometheus.GaugeValue, linkSpeed,
device.Name, device.Mac, portClient.HostName, portClient.Vendor, port, p.SwitchMac, p.SwitchId, vlanId, p.ProfileName, site, client.SiteId)
} else {
ch <- prometheus.MustNewConstMetric(c.omadaPortPowerWatts, prometheus.GaugeValue, p.PortStatus.PoePower,
device.Name, device.Mac, "", "", port, p.SwitchMac, p.SwitchId, "", p.ProfileName, site, client.SiteId)
cHostName = portClient.HostName
cVendor = portClient.Vendor
cVlanID = fmt.Sprintf("%.0f", portClient.VlanId)
}

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

ch <- prometheus.MustNewConstMetric(c.omadaPortLinkSpeedMbps, prometheus.GaugeValue, linkSpeed,
device.Name, device.Mac, "", "", port, p.SwitchMac, p.SwitchId, "", p.ProfileName, site, client.SiteId)
}
ch <- prometheus.MustNewConstMetric(c.omadaPortPowerWatts, prometheus.GaugeValue, p.PortStatus.PoePower, labels...)
ch <- prometheus.MustNewConstMetric(c.omadaPortLinkStatus, prometheus.GaugeValue, p.PortStatus.LinkStatus, labels...)
ch <- prometheus.MustNewConstMetric(c.omadaPortLinkSpeedMbps, prometheus.GaugeValue, linkSpeed, labels...)
ch <- prometheus.MustNewConstMetric(c.omadaPortLinkRx, prometheus.CounterValue, p.PortStatus.Rx, labels...)
ch <- prometheus.MustNewConstMetric(c.omadaPortLinkTx, prometheus.CounterValue, p.PortStatus.Tx, labels...)
}
}
}
Expand Down Expand Up @@ -107,20 +104,32 @@ func removeDuplicates(s []api.Port) []api.Port {
}

func NewPortCollector(c *api.Client) *portCollector {
labels := []string{"device", "device_mac", "client", "vendor", "switch_port", "name", "switch_mac", "switch_id", "vlan_id", "profile", "site", "site_id"}

return &portCollector{
omadaPortPowerWatts: prometheus.NewDesc("omada_port_power_watts",
"The current PoE usage of the port in watts.",
[]string{"device", "device_mac", "client", "vendor", "switch_port", "switch_mac", "switch_id", "vlan_id", "profile", "site", "site_id"},
labels,
nil,
),
omadaPortLinkStatus: prometheus.NewDesc("omada_port_link_status",
"A boolean representing the link status of the port.",
[]string{"device", "device_mac", "client", "vendor", "switch_port", "switch_mac", "switch_id", "vlan_id", "profile", "site", "site_id"},
labels,
nil,
),
omadaPortLinkSpeedMbps: prometheus.NewDesc("omada_port_link_speed_mbps",
"Port link speed in mbps. This is the capability of the connection, not the active throughput.",
[]string{"device", "device_mac", "client", "vendor", "switch_port", "switch_mac", "switch_id", "vlan_id", "profile", "site", "site_id"},
labels,
nil,
),
omadaPortLinkRx: prometheus.NewDesc("omada_port_link_rx",
"Bytes recieved on a port.",
labels,
nil,
),
omadaPortLinkTx: prometheus.NewDesc("omada_port_link_tx",
"Bytes transmitted on a port.",
labels,
nil,
),
client: c,
Expand Down

0 comments on commit ebe142d

Please sign in to comment.