169 lines
5.1 KiB
Go
169 lines
5.1 KiB
Go
package datadogunifi
|
|
|
|
import (
|
|
"github.com/unifi-poller/unifi"
|
|
)
|
|
|
|
// reportClient generates Unifi Client datapoints for InfluxDB.
|
|
// These points can be passed directly to influx.
|
|
func (u *DatadogUnifi) reportClient(r report, s *unifi.Client) { // nolint: funlen
|
|
tags := []string{
|
|
tag("mac", s.Mac),
|
|
tag("site_name", s.SiteName),
|
|
tag("source", s.SourceName),
|
|
tag("ap_name", s.ApName),
|
|
tag("gw_name", s.GwName),
|
|
tag("sw_name", s.SwName),
|
|
tag("oui", s.Oui),
|
|
tag("radio_name", s.RadioName),
|
|
tag("radio", s.Radio),
|
|
tag("radio_proto", s.RadioProto),
|
|
tag("name", s.Name),
|
|
tag("fixed_ip", s.FixedIP),
|
|
tag("sw_port", s.SwPort.Txt),
|
|
tag("os_class", s.OsClass.Txt),
|
|
tag("os_name", s.OsName.Txt),
|
|
tag("dev_cat", s.DevCat.Txt),
|
|
tag("dev_id", s.DevID.Txt),
|
|
tag("dev_vendor", s.DevVendor.Txt),
|
|
tag("dev_family", s.DevFamily.Txt),
|
|
tag("is_wired", s.IsWired.Txt),
|
|
tag("is_guest", s.IsGuest.Txt),
|
|
tag("use_fixedip", s.UseFixedIP.Txt),
|
|
tag("channel", s.Channel.Txt),
|
|
tag("vlan", s.Vlan.Txt),
|
|
tag("hostname", s.Name),
|
|
tag("radio_desc", s.RadioDescription),
|
|
tag("ip", s.IP),
|
|
tag("essid", s.Essid),
|
|
tag("bssid", s.Bssid),
|
|
}
|
|
|
|
data := map[string]float64{
|
|
"anomalies": float64(s.Anomalies),
|
|
"channel": s.Channel.Val,
|
|
"satisfaction": s.Satisfaction.Val,
|
|
"bytes_r": float64(s.BytesR),
|
|
"ccq": float64(s.Ccq),
|
|
"noise": float64(s.Noise),
|
|
"roam_count": float64(s.RoamCount),
|
|
"rssi": float64(s.Rssi),
|
|
"rx_bytes": float64(s.RxBytes),
|
|
"rx_bytes_r": float64(s.RxBytesR),
|
|
"rx_packets": float64(s.RxPackets),
|
|
"rx_rate": float64(s.RxRate),
|
|
"signal": float64(s.Signal),
|
|
"tx_bytes": float64(s.TxBytes),
|
|
"tx_bytes_r": float64(s.TxBytesR),
|
|
"tx_packets": float64(s.TxPackets),
|
|
"tx_retries": float64(s.TxRetries),
|
|
"tx_power": float64(s.TxPower),
|
|
"tx_rate": float64(s.TxRate),
|
|
"uptime": float64(s.Uptime),
|
|
"wifi_tx_attempts": float64(s.WifiTxAttempts),
|
|
"wired-rx_bytes": float64(s.WiredRxBytes),
|
|
"wired-rx_bytes-r": float64(s.WiredRxBytesR),
|
|
"wired-rx_packets": float64(s.WiredRxPackets),
|
|
"wired-tx_bytes": float64(s.WiredTxBytes),
|
|
"wired-tx_bytes-r": float64(s.WiredTxBytesR),
|
|
"wired-tx_packets": float64(s.WiredTxPackets),
|
|
}
|
|
metricName := metricNamespace("clients")
|
|
reportGaugeForMap(r, metricName, data, tags)
|
|
}
|
|
|
|
// totalsDPImap: controller, site, name (app/cat name), dpi.
|
|
type totalsDPImap map[string]map[string]map[string]unifi.DPIData
|
|
|
|
func (u *DatadogUnifi) reportClientDPI(r report, s *unifi.DPITable, appTotal, catTotal totalsDPImap) {
|
|
for _, dpi := range s.ByApp {
|
|
category := unifi.DPICats.Get(dpi.Cat)
|
|
application := unifi.DPIApps.GetApp(dpi.Cat, dpi.App)
|
|
fillDPIMapTotals(appTotal, application, s.SourceName, s.SiteName, dpi)
|
|
fillDPIMapTotals(catTotal, category, s.SourceName, s.SiteName, dpi)
|
|
|
|
tags := []string{
|
|
tag("category", category),
|
|
tag("application", application),
|
|
tag("name", s.Name),
|
|
tag("mac", s.MAC),
|
|
tag("site_name", s.SiteName),
|
|
tag("source", s.SourceName),
|
|
}
|
|
data := map[string]float64{
|
|
"tx_packets": float64(dpi.TxPackets),
|
|
"rx_packets": float64(dpi.RxPackets),
|
|
"tx_bytes": float64(dpi.TxBytes),
|
|
"rx_bytes": float64(dpi.RxBytes),
|
|
}
|
|
metricName := metricNamespace("clientdpi")
|
|
reportGaugeForMap(r, metricName, data, tags)
|
|
}
|
|
}
|
|
|
|
// fillDPIMapTotals fills in totals for categories and applications. maybe clients too.
|
|
// This allows less processing in InfluxDB to produce total transfer data per cat or app.
|
|
func fillDPIMapTotals(m totalsDPImap, name, controller, site string, dpi unifi.DPIData) {
|
|
if m[controller] == nil {
|
|
m[controller] = make(map[string]map[string]unifi.DPIData)
|
|
}
|
|
|
|
if m[controller][site] == nil {
|
|
m[controller][site] = make(map[string]unifi.DPIData)
|
|
}
|
|
|
|
existing := m[controller][site][name]
|
|
existing.TxPackets += dpi.TxPackets
|
|
existing.RxPackets += dpi.RxPackets
|
|
existing.TxBytes += dpi.TxBytes
|
|
existing.RxBytes += dpi.RxBytes
|
|
m[controller][site][name] = existing
|
|
}
|
|
|
|
func reportClientDPItotals(r report, appTotal, catTotal totalsDPImap) {
|
|
type all []struct {
|
|
kind string
|
|
val totalsDPImap
|
|
}
|
|
|
|
// This produces 7000+ metrics per site. Disabled for now.
|
|
if appTotal != nil {
|
|
appTotal = nil
|
|
}
|
|
|
|
// This can allow us to aggregate other data types later, like `name` or `mac`, or anything else unifi adds.
|
|
a := all{
|
|
// This produces 7000+ metrics per site. Disabled for now.
|
|
{
|
|
kind: "application",
|
|
val: appTotal,
|
|
},
|
|
{
|
|
kind: "category",
|
|
val: catTotal,
|
|
},
|
|
}
|
|
|
|
for _, k := range a {
|
|
for controller, s := range k.val {
|
|
for site, c := range s {
|
|
for name, m := range c {
|
|
tags := []string{
|
|
tag("site_name", site),
|
|
tag("source", controller),
|
|
tag("name", name),
|
|
}
|
|
data := map[string]float64{
|
|
"tx_packets": float64(m.TxPackets),
|
|
"rx_packets": float64(m.RxPackets),
|
|
"tx_bytes": float64(m.TxBytes),
|
|
"rx_bytes": float64(m.RxBytes),
|
|
}
|
|
metricName := metricNamespace("clientdpi.totals")
|
|
reportGaugeForMap(r, metricName, data, tags)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|