unpoller_unpoller/pkg/promunifi/udm.go

149 lines
6.3 KiB
Go

package promunifi
import (
"github.com/prometheus/client_golang/prometheus"
"github.com/unpoller/unifi"
)
// These are shared by all four device types: UDM, UAP, USG, USW.
type unifiDevice struct {
Info *prometheus.Desc
Uptime *prometheus.Desc
Temperature *prometheus.Desc
Storage *prometheus.Desc
TotalMaxPower *prometheus.Desc // sw only
FanLevel *prometheus.Desc // sw only
TotalTxBytes *prometheus.Desc
TotalRxBytes *prometheus.Desc
TotalBytes *prometheus.Desc
BytesR *prometheus.Desc // ap only
BytesD *prometheus.Desc // ap only
TxBytesD *prometheus.Desc // ap only
RxBytesD *prometheus.Desc // ap only
Counter *prometheus.Desc
Loadavg1 *prometheus.Desc
Loadavg5 *prometheus.Desc
Loadavg15 *prometheus.Desc
MemBuffer *prometheus.Desc
MemTotal *prometheus.Desc
MemUsed *prometheus.Desc
CPU *prometheus.Desc
Mem *prometheus.Desc
}
func descDevice(ns string) *unifiDevice {
labels := []string{"type", "site_name", "name", "source"}
infoLabels := []string{"version", "model", "serial", "mac", "ip", "id"}
return &unifiDevice{
Info: prometheus.NewDesc(ns+"info", "Device Information", append(labels, infoLabels...), nil),
Uptime: prometheus.NewDesc(ns+"uptime_seconds", "Device Uptime", labels, nil),
Temperature: prometheus.NewDesc(ns+"temperature_celsius", "Temperature",
append(labels, "temp_area", "temp_type"), nil),
Storage: prometheus.NewDesc(ns+"storage", "Storage",
append(labels, "mountpoint", "storage_name", "storage_reading"), nil),
TotalMaxPower: prometheus.NewDesc(ns+"max_power_total", "Total Max Power", labels, nil),
FanLevel: prometheus.NewDesc(ns+"fan_level", "Fan Level", labels, nil),
TotalTxBytes: prometheus.NewDesc(ns+"transmit_bytes_total", "Total Transmitted Bytes", labels, nil),
TotalRxBytes: prometheus.NewDesc(ns+"receive_bytes_total", "Total Received Bytes", labels, nil),
TotalBytes: prometheus.NewDesc(ns+"bytes_total", "Total Bytes Transferred", labels, nil),
BytesR: prometheus.NewDesc(ns+"rate_bytes", "Transfer Rate", labels, nil),
BytesD: prometheus.NewDesc(ns+"d_bytes", "Total Bytes D???", labels, nil),
TxBytesD: prometheus.NewDesc(ns+"d_tranmsit_bytes", "Transmit Bytes D???", labels, nil),
RxBytesD: prometheus.NewDesc(ns+"d_receive_bytes", "Receive Bytes D???", labels, nil),
Counter: prometheus.NewDesc(ns+"stations", "Number of Stations", append(labels, "station_type"), nil),
Loadavg1: prometheus.NewDesc(ns+"load_average_1", "System Load Average 1 Minute", labels, nil),
Loadavg5: prometheus.NewDesc(ns+"load_average_5", "System Load Average 5 Minutes", labels, nil),
Loadavg15: prometheus.NewDesc(ns+"load_average_15", "System Load Average 15 Minutes", labels, nil),
MemUsed: prometheus.NewDesc(ns+"memory_used_bytes", "System Memory Used", labels, nil),
MemTotal: prometheus.NewDesc(ns+"memory_installed_bytes", "System Installed Memory", labels, nil),
MemBuffer: prometheus.NewDesc(ns+"memory_buffer_bytes", "System Memory Buffer", labels, nil),
CPU: prometheus.NewDesc(ns+"cpu_utilization_ratio", "System CPU % Utilized", labels, nil),
Mem: prometheus.NewDesc(ns+"memory_utilization_ratio", "System Memory % Utilized", labels, nil),
}
}
// UDM is a collection of stats from USG, USW and UAP. It has no unique stats.
func (u *promUnifi) exportUDM(r report, d *unifi.UDM) {
if !d.Adopted.Val || d.Locating.Val {
return
}
labels := []string{d.Type, d.SiteName, d.Name, d.SourceName}
infoLabels := []string{d.Version, d.Model, d.Serial, d.Mac, d.IP, d.ID}
// Shared data (all devices do this).
u.exportBYTstats(r, labels, d.TxBytes, d.RxBytes)
u.exportSYSstats(r, labels, d.SysStats, d.SystemStats)
u.exportSTAcount(r, labels, d.UserNumSta, d.GuestNumSta, d.NumDesktop, d.NumMobile, d.NumHandheld)
// Switch Data
u.exportUSWstats(r, labels, d.Stat.Sw)
u.exportPRTtable(r, labels, d.PortTable)
// Gateway Data
u.exportWANPorts(r, labels, d.Wan1, d.Wan2)
u.exportUSGstats(r, labels, d.Stat.Gw, d.SpeedtestStatus, d.Uplink)
// Dream Machine System Data.
r.send([]*metric{
{u.Device.Info, gauge, 1.0, append(labels, infoLabels...)},
{u.Device.Uptime, gauge, d.Uptime, labels},
})
// UDM pro has special temp sensors. UDM non-pro may not have temp; not sure.
for _, t := range d.Temperatures {
r.send([]*metric{{u.Device.Temperature, gauge, t.Value, append(labels, t.Name, t.Type)}})
}
// UDM pro and UXG have hard drives.
for _, t := range d.Storage {
r.send([]*metric{
{u.Device.Storage, gauge, t.Size.Val, append(labels, t.MountPoint, t.Name, "size")},
{u.Device.Storage, gauge, t.Used.Val, append(labels, t.MountPoint, t.Name, "used")},
})
}
// Wireless Data - UDM (non-pro) only
if d.Stat.Ap != nil && d.VapTable != nil {
u.exportUAPstats(r, labels, d.Stat.Ap, d.BytesD, d.TxBytesD, d.RxBytesD, d.BytesR)
u.exportVAPtable(r, labels, *d.VapTable)
u.exportRADtable(r, labels, *d.RadioTable, *d.RadioTableStats)
}
}
// Shared by all.
func (u *promUnifi) exportBYTstats(r report, labels []string, tx, rx unifi.FlexInt) {
r.send([]*metric{
{u.Device.TotalTxBytes, counter, tx, labels},
{u.Device.TotalRxBytes, counter, rx, labels},
{u.Device.TotalBytes, counter, tx.Val + rx.Val, labels},
})
}
// Shared by all, pass 2 or 5 stats.
func (u *promUnifi) exportSTAcount(r report, labels []string, stas ...unifi.FlexInt) {
r.send([]*metric{
{u.Device.Counter, gauge, stas[0], append(labels, "user")},
{u.Device.Counter, gauge, stas[1], append(labels, "guest")},
})
if len(stas) > 2 { // nolint: gomnd
r.send([]*metric{
{u.Device.Counter, gauge, stas[2], append(labels, "desktop")},
{u.Device.Counter, gauge, stas[3], append(labels, "mobile")},
{u.Device.Counter, gauge, stas[4], append(labels, "handheld")},
})
}
}
// Shared by all.
func (u *promUnifi) exportSYSstats(r report, labels []string, s unifi.SysStats, ss unifi.SystemStats) {
r.send([]*metric{
{u.Device.Loadavg1, gauge, s.Loadavg1, labels},
{u.Device.Loadavg5, gauge, s.Loadavg5, labels},
{u.Device.Loadavg15, gauge, s.Loadavg15, labels},
{u.Device.MemUsed, gauge, s.MemUsed, labels},
{u.Device.MemTotal, gauge, s.MemTotal, labels},
{u.Device.MemBuffer, gauge, s.MemBuffer, labels},
{u.Device.CPU, gauge, ss.CPU.Val / 100.0, labels},
{u.Device.Mem, gauge, ss.Mem.Val / 100.0, labels},
})
}