From 25e5f1c4b6abdd478a74bac51218a8ababbace6b Mon Sep 17 00:00:00 2001 From: davidnewhall2 Date: Sat, 30 Nov 2019 02:15:06 -0800 Subject: [PATCH 01/10] Add port ID to switch ports. --- pkg/promunifi/usw.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/promunifi/usw.go b/pkg/promunifi/usw.go index 88f7e190..a02b15f4 100644 --- a/pkg/promunifi/usw.go +++ b/pkg/promunifi/usw.go @@ -49,7 +49,7 @@ func descUSW(ns string) *usw { pns := ns + "port_" // labels := []string{"ip", "version", "model", "serial", "type", "mac", "site_name", "name"} labelS := []string{"site_name", "name"} // labels[6:] - labelP := []string{"port_num", "port_name", "port_mac", "port_ip", "site_name", "name"} + labelP := []string{"port_id", "port_num", "port_name", "port_mac", "port_ip", "site_name", "name"} return &usw{ SwRxPackets: prometheus.NewDesc(ns+"switch_receive_packets_total", "Switch Packets Received Total", labelS, nil), SwRxBytes: prometheus.NewDesc(ns+"switch_receive_bytes_total", "Switch Bytes Received Total", labelS, nil), @@ -147,11 +147,11 @@ func (u *promUnifi) exportUSWstats(r report, labels []string, sw *unifi.Sw) { func (u *promUnifi) exportPortTable(r report, labels []string, pt []unifi.Port) { // Per-port data on a switch for _, p := range pt { - if !p.Up.Val { + if !p.Up.Val || !p.Enable.Val { continue } // Copy labels, and add four new ones. - labelP := []string{p.PortIdx.Txt, p.Name, p.Mac, p.IP, labels[6], labels[7]} + labelP := []string{labels[7] + " Port " + p.PortIdx.Txt, p.PortIdx.Txt, p.Name, p.Mac, p.IP, labels[6], labels[7]} if p.PoeEnable.Val && p.PortPoe.Val { r.send([]*metric{ {u.USW.PoeCurrent, prometheus.GaugeValue, p.PoeCurrent, labelP}, From f9a4963b2352f3946e40b1516e4b15bc11076bd4 Mon Sep 17 00:00:00 2001 From: davidnewhall2 Date: Sat, 30 Nov 2019 02:47:11 -0800 Subject: [PATCH 02/10] remove a bunch of unused things from influx code --- pkg/influxunifi/clients.go | 160 +++++++++++++++------------------ pkg/influxunifi/site.go | 37 +++----- pkg/influxunifi/uap.go | 40 +++------ pkg/influxunifi/udm.go | 178 +++++++++++++------------------------ pkg/influxunifi/usg.go | 82 ++++++----------- pkg/influxunifi/usw.go | 78 ++++++---------- 6 files changed, 211 insertions(+), 364 deletions(-) diff --git a/pkg/influxunifi/clients.go b/pkg/influxunifi/clients.go index 8e35f282..0ff5fcd8 100644 --- a/pkg/influxunifi/clients.go +++ b/pkg/influxunifi/clients.go @@ -11,97 +11,79 @@ import ( // These points can be passed directly to influx. func ClientPoints(c *unifi.Client, now time.Time) ([]*influx.Point, error) { tags := map[string]string{ - "id": c.ID, - "mac": c.Mac, - "user_id": c.UserID, - "site_id": c.SiteID, - "site_name": c.SiteName, - "network_id": c.NetworkID, - "usergroup_id": c.UserGroupID, - "ap_mac": c.ApMac, - "gw_mac": c.GwMac, - "sw_mac": c.SwMac, - "ap_name": c.ApName, - "gw_name": c.GwName, - "sw_name": c.SwName, - "oui": c.Oui, - "radio_name": c.RadioName, - "radio": c.Radio, - "radio_proto": c.RadioProto, - "name": c.Name, - "fixed_ip": c.FixedIP, - "sw_port": c.SwPort.Txt, - "os_class": c.OsClass.Txt, - "os_name": c.OsName.Txt, - "dev_cat": c.DevCat.Txt, - "dev_id": c.DevID.Txt, - "dev_vendor": c.DevVendor.Txt, - "dev_family": c.DevFamily.Txt, - "is_11r": c.Is11R.Txt, - "is_wired": c.IsWired.Txt, - "is_guest": c.IsGuest.Txt, - "is_guest_by_uap": c.IsGuestByUAP.Txt, - "is_guest_by_ugw": c.IsGuestByUGW.Txt, - "is_guest_by_usw": c.IsGuestByUSW.Txt, - "noted": c.Noted.Txt, - "powersave_enabled": c.PowersaveEnabled.Txt, - "qos_policy_applied": c.QosPolicyApplied.Txt, - "use_fixedip": c.UseFixedIP.Txt, - "channel": c.Channel.Txt, - "vlan": c.Vlan.Txt, + "id": c.ID, + "mac": c.Mac, + "user_id": c.UserID, + "site_id": c.SiteID, + "site_name": c.SiteName, + "ap_mac": c.ApMac, + "gw_mac": c.GwMac, + "sw_mac": c.SwMac, + "ap_name": c.ApName, + "gw_name": c.GwName, + "sw_name": c.SwName, + "oui": c.Oui, + "radio_name": c.RadioName, + "radio": c.Radio, + "radio_proto": c.RadioProto, + "name": c.Name, + "fixed_ip": c.FixedIP, + "sw_port": c.SwPort.Txt, + "os_class": c.OsClass.Txt, + "os_name": c.OsName.Txt, + "dev_cat": c.DevCat.Txt, + "dev_id": c.DevID.Txt, + "dev_vendor": c.DevVendor.Txt, + "dev_family": c.DevFamily.Txt, + "is_wired": c.IsWired.Txt, + "is_guest": c.IsGuest.Txt, + "use_fixedip": c.UseFixedIP.Txt, + "channel": c.Channel.Txt, + "vlan": c.Vlan.Txt, } fields := map[string]interface{}{ - "anomalies": c.Anomalies, - "ip": c.IP, - "essid": c.Essid, - "bssid": c.Bssid, - "radio_desc": c.RadioDescription, - "satisfaction": c.Satisfaction.Val, - "hostname": c.Hostname, - "dpi_stats_last_updated": c.DpiStatsLastUpdated, - "last_seen_by_uap": c.LastSeenByUAP, - "last_seen_by_ugw": c.LastSeenByUGW, - "last_seen_by_usw": c.LastSeenByUSW, - "uptime_by_uap": c.UptimeByUAP, - "uptime_by_ugw": c.UptimeByUGW, - "uptime_by_usw": c.UptimeByUSW, - "assoc_time": c.AssocTime, - "bytes_r": c.BytesR, - "ccq": c.Ccq, - "first_seen": c.FirstSeen, - "idle_time": c.IdleTime, - "last_seen": c.LastSeen, - "latest_assoc_time": c.LatestAssocTime, - "network": c.Network, - "noise": c.Noise, - "note": c.Note, - "roam_count": c.RoamCount, - "rssi": c.Rssi, - "rx_bytes": c.RxBytes, - "rx_bytes_r": c.RxBytesR, - "rx_packets": c.RxPackets, - "rx_rate": c.RxRate, - "signal": c.Signal, - "tx_bytes": c.TxBytes, - "tx_bytes_r": c.TxBytesR, - "tx_packets": c.TxPackets, - "tx_retries": c.TxRetries, - "tx_power": c.TxPower, - "tx_rate": c.TxRate, - "uptime": c.Uptime, - "wifi_tx_attempts": c.WifiTxAttempts, - "wired-rx_bytes": c.WiredRxBytes, - "wired-rx_bytes-r": c.WiredRxBytesR, - "wired-rx_packets": c.WiredRxPackets, - "wired-tx_bytes": c.WiredTxBytes, - "wired-tx_bytes-r": c.WiredTxBytesR, - "wired-tx_packets": c.WiredTxPackets, - "dpi_app": c.DpiStats.App.Val, - "dpi_cat": c.DpiStats.Cat.Val, - "dpi_rx_bytes": c.DpiStats.RxBytes.Val, - "dpi_rx_packets": c.DpiStats.RxPackets.Val, - "dpi_tx_bytes": c.DpiStats.TxBytes.Val, - "dpi_tx_packets": c.DpiStats.TxPackets.Val, + "anomalies": c.Anomalies, + "ip": c.IP, + "essid": c.Essid, + "bssid": c.Bssid, + "radio_desc": c.RadioDescription, + "satisfaction": c.Satisfaction.Val, + "hostname": c.Hostname, + "bytes_r": c.BytesR, + "ccq": c.Ccq, + "first_seen": c.FirstSeen, + "idle_time": c.IdleTime, + "last_seen": c.LastSeen, + "network": c.Network, + "noise": c.Noise, + "note": c.Note, + "roam_count": c.RoamCount, + "rssi": c.Rssi, + "rx_bytes": c.RxBytes, + "rx_bytes_r": c.RxBytesR, + "rx_packets": c.RxPackets, + "rx_rate": c.RxRate, + "signal": c.Signal, + "tx_bytes": c.TxBytes, + "tx_bytes_r": c.TxBytesR, + "tx_packets": c.TxPackets, + "tx_retries": c.TxRetries, + "tx_power": c.TxPower, + "tx_rate": c.TxRate, + "uptime": c.Uptime, + "wifi_tx_attempts": c.WifiTxAttempts, + "wired-rx_bytes": c.WiredRxBytes, + "wired-rx_bytes-r": c.WiredRxBytesR, + "wired-rx_packets": c.WiredRxPackets, + "wired-tx_bytes": c.WiredTxBytes, + "wired-tx_bytes-r": c.WiredTxBytesR, + "wired-tx_packets": c.WiredTxPackets, + "dpi_app": c.DpiStats.App.Val, + "dpi_cat": c.DpiStats.Cat.Val, + "dpi_rx_bytes": c.DpiStats.RxBytes.Val, + "dpi_rx_packets": c.DpiStats.RxPackets.Val, + "dpi_tx_bytes": c.DpiStats.TxBytes.Val, + "dpi_tx_packets": c.DpiStats.TxPackets.Val, } pt, err := influx.NewPoint("clients", tags, fields, now) if err != nil { diff --git a/pkg/influxunifi/site.go b/pkg/influxunifi/site.go index 0bd647ac..466a43ac 100644 --- a/pkg/influxunifi/site.go +++ b/pkg/influxunifi/site.go @@ -14,36 +14,27 @@ func SitePoints(u *unifi.Site, now time.Time) ([]*influx.Point, error) { points := []*influx.Point{} for _, s := range u.Health { tags := map[string]string{ - "id": u.ID, - "name": u.Name, - "site_name": u.SiteName, - "desc": u.Desc, - "status": s.Status, - "subsystem": s.Subsystem, - "wan_ip": s.WanIP, - "netmask": s.Netmask, - "gw_name": s.GwName, - "gw_mac": s.GwMac, - "gw_version": s.GwVersion, - "speedtest_status": s.SpeedtestStatus, - "lan_ip": s.LanIP, - "remote_user_enabled": s.RemoteUserEnabled.Txt, - "site_to_site_enabled": s.SiteToSiteEnabled.Txt, - "nameservers": strings.Join(s.Nameservers, ","), - "gateways": strings.Join(s.Gateways, ","), - "num_new_alarms": u.NumNewAlarms.Txt, - "attr_hidden_id": u.AttrHiddenID, - "attr_no_delete": u.AttrNoDelete.Txt, + "name": u.Name, + "site_name": u.SiteName, + "desc": u.Desc, + "status": s.Status, + "subsystem": s.Subsystem, + "wan_ip": s.WanIP, + "netmask": s.Netmask, + "gw_name": s.GwName, + "gw_mac": s.GwMac, + "gw_version": s.GwVersion, + "lan_ip": s.LanIP, + "nameservers": strings.Join(s.Nameservers, ","), + "gateways": strings.Join(s.Gateways, ","), + "num_new_alarms": u.NumNewAlarms.Txt, } fields := map[string]interface{}{ - "attr_hidden_id": u.AttrHiddenID, - "attr_no_delete": u.AttrNoDelete.Val, "num_user": s.NumUser.Val, "num_guest": s.NumGuest.Val, "num_iot": s.NumIot.Val, "tx_bytes-r": s.TxBytesR.Val, "rx_bytes-r": s.RxBytesR.Val, - "status": s.Status, "num_ap": s.NumAp.Val, "num_adopted": s.NumAdopted.Val, "num_disabled": s.NumDisabled.Val, diff --git a/pkg/influxunifi/uap.go b/pkg/influxunifi/uap.go index 1744b0c0..423c00cb 100644 --- a/pkg/influxunifi/uap.go +++ b/pkg/influxunifi/uap.go @@ -14,27 +14,15 @@ func UAPPoints(u *unifi.UAP, now time.Time) ([]*influx.Point, error) { u.Stat.Ap = &unifi.Ap{} } tags := map[string]string{ - "id": u.ID, - "ip": u.IP, - "mac": u.Mac, - "device_type": u.Stat.Ap.O, - "device_oid": u.Stat.Ap.Oid, - "device_ap": u.Stat.Ap.Ap, - "site_id": u.SiteID, - "site_name": u.SiteName, - "name": u.Name, - "adopted": u.Adopted.Txt, - "cfgversion": u.Cfgversion, - "config_network_ip": u.ConfigNetwork.IP, - "config_network_type": u.ConfigNetwork.Type, - "connect_request_ip": u.ConnectRequestIP, - "device_id": u.DeviceID, - "has_eth1": u.HasEth1.Txt, - "inform_ip": u.InformIP, - "known_cfgversion": u.KnownCfgversion, - "model": u.Model, - "serial": u.Serial, - "type": u.Type, + "ip": u.IP, + "mac": u.Mac, + "site_id": u.SiteID, + "site_name": u.SiteName, + "name": u.Name, + "cfgversion": u.Cfgversion, + "model": u.Model, + "serial": u.Serial, + "type": u.Type, } fields := map[string]interface{}{ "ip": u.IP, @@ -47,7 +35,6 @@ func UAPPoints(u *unifi.UAP, now time.Time) ([]*influx.Point, error) { "user-num_sta": int(u.UserNumSta.Val), "guest-num_sta": int(u.GuestNumSta.Val), "num_sta": u.NumSta.Val, - "version": u.Version, "loadavg_1": u.SysStats.Loadavg1.Val, "loadavg_5": u.SysStats.Loadavg5.Val, "loadavg_15": u.SysStats.Loadavg15.Val, @@ -95,7 +82,7 @@ func UAPPoints(u *unifi.UAP, now time.Time) ([]*influx.Point, error) { if err != nil { return nil, err } - morePoints, err := processVAPs(u.VapTable, u.RadioTable, u.RadioTableStats, u.Name, u.ID, u.Mac, u.SiteName, now) + morePoints, err := processVAPs(u.VapTable, u.RadioTable, u.RadioTableStats, u.Name, u.Mac, u.SiteName, now) if err != nil { return nil, err } @@ -103,7 +90,7 @@ func UAPPoints(u *unifi.UAP, now time.Time) ([]*influx.Point, error) { } // processVAPs creates points for Wifi Radios. This works with several types of UAP-capable devices. -func processVAPs(vt unifi.VapTable, rt unifi.RadioTable, rts unifi.RadioTableStats, name, id, mac, sitename string, ts time.Time) ([]*influx.Point, error) { +func processVAPs(vt unifi.VapTable, rt unifi.RadioTable, rts unifi.RadioTableStats, name, mac, sitename string, ts time.Time) ([]*influx.Point, error) { tags := make(map[string]string) fields := make(map[string]interface{}) points := []*influx.Point{} @@ -112,7 +99,6 @@ func processVAPs(vt unifi.VapTable, rt unifi.RadioTable, rts unifi.RadioTableSta // from radio_tables and radio_table_stats. for _, s := range vt { tags["device_name"] = name - tags["device_id"] = id tags["device_mac"] = mac tags["site_name"] = sitename tags["ap_mac"] = s.ApMac @@ -120,13 +106,11 @@ func processVAPs(vt unifi.VapTable, rt unifi.RadioTable, rts unifi.RadioTableSta tags["id"] = s.ID tags["name"] = s.Name tags["radio_name"] = s.RadioName - tags["wlanconf_id"] = s.WlanconfID tags["essid"] = s.Essid tags["site_id"] = s.SiteID tags["usage"] = s.Usage tags["state"] = s.State tags["is_guest"] = s.IsGuest.Txt - tags["is_wep"] = s.IsWep.Txt fields["ccq"] = s.Ccq fields["extchannel"] = s.Extchannel @@ -171,13 +155,11 @@ func processVAPs(vt unifi.VapTable, rt unifi.RadioTable, rts unifi.RadioTableSta if p.Name != s.RadioName { continue } - tags["wlangroup_id"] = p.WlangroupID tags["channel"] = p.Channel.Txt tags["radio"] = p.Radio fields["current_antenna_gain"] = p.CurrentAntennaGain.Val fields["ht"] = p.Ht.Txt fields["max_txpower"] = p.MaxTxpower.Val - fields["min_rssi_enabled"] = p.MinRssiEnabled.Val fields["min_txpower"] = p.MinTxpower.Val fields["nss"] = p.Nss.Val fields["radio_caps"] = p.RadioCaps.Val diff --git a/pkg/influxunifi/udm.go b/pkg/influxunifi/udm.go index fa968115..54f9494f 100644 --- a/pkg/influxunifi/udm.go +++ b/pkg/influxunifi/udm.go @@ -17,29 +17,20 @@ func UDMPoints(u *unifi.UDM, now time.Time) ([]*influx.Point, error) { u.Stat.Gw = &unifi.Gw{} } tags := map[string]string{ - "id": u.ID, - "mac": u.Mac, - "device_oid": u.Stat.Gw.Oid, - "site_id": u.SiteID, - "site_name": u.SiteName, - "adopted": u.Adopted.Txt, - "name": u.Name, - "cfgversion": u.Cfgversion, - "config_network_ip": u.ConfigNetwork.IP, - "config_network_type": u.ConfigNetwork.Type, - "connect_request_ip": u.ConnectRequestIP, - "connect_request_port": u.ConnectRequestPort, - "device_id": u.DeviceID, - "guest_token": u.GuestToken, - "inform_ip": u.InformIP, - "known_cfgversion": u.KnownCfgversion, - "model": u.Model, - "serial": u.Serial, - "type": u.Type, - "usg_caps": u.UsgCaps.Txt, - "speedtest-status-saved": u.SpeedtestStatusSaved.Txt, - "wan1_up": u.Wan1.Up.Txt, - "wan2_up": u.Wan2.Up.Txt, + "id": u.ID, + "mac": u.Mac, + "site_id": u.SiteID, + "site_name": u.SiteName, + "name": u.Name, + "cfgversion": u.Cfgversion, + "device_id": u.DeviceID, + "known_cfgversion": u.KnownCfgversion, + "model": u.Model, + "serial": u.Serial, + "type": u.Type, + "usg_caps": u.UsgCaps.Txt, + "wan1_up": u.Wan1.Up.Txt, + "wan2_up": u.Wan2.Up.Txt, } fields := map[string]interface{}{ "ip": u.IP, @@ -147,29 +138,16 @@ func UDMPoints(u *unifi.UDM, now time.Time) ([]*influx.Point, error) { } points := []*influx.Point{pt} tags = map[string]string{ - "id": u.ID, - "mac": u.Mac, - "device_oid": u.Stat.Sw.Oid, - "site_id": u.SiteID, - "site_name": u.SiteName, - "name": u.Name, - "adopted": u.Adopted.Txt, - "cfgversion": u.Cfgversion, - "config_network_ip": u.ConfigNetwork.IP, - "config_network_type": u.ConfigNetwork.Type, - "device_id": u.DeviceID, - "inform_ip": u.InformIP, - "known_cfgversion": u.KnownCfgversion, - "locating": u.Locating.Txt, - "model": u.Model, - "serial": u.Serial, - "type": u.Type, - "dot1x_portctrl_enabled": u.Dot1XPortctrlEnabled.Txt, - "flowctrl_enabled": u.FlowctrlEnabled.Txt, - "has_fan": u.HasFan.Txt, - "has_temperature": u.HasTemperature.Txt, - "jumboframe_enabled": u.JumboframeEnabled.Txt, - "stp_version": u.StpVersion, + "id": u.ID, + "mac": u.Mac, + "site_id": u.SiteID, + "site_name": u.SiteName, + "name": u.Name, + "model": u.Model, + "serial": u.Serial, + "type": u.Type, + "has_fan": u.HasFan.Txt, + "has_temperature": u.HasTemperature.Txt, } fields = map[string]interface{}{ "fw_caps": u.FwCaps.Val, @@ -219,23 +197,19 @@ func UDMPoints(u *unifi.UDM, now time.Time) ([]*influx.Point, error) { for _, p := range u.NetworkTable { tags := map[string]string{ - "device_name": u.Name, - "device_id": u.ID, - "device_mac": u.Mac, - "site_name": u.SiteName, - "up": p.Up.Txt, - "dhcpd_dns_enabled": p.DhcpdDNSEnabled.Txt, - "dhcpd_enabled": p.DhcpdEnabled.Txt, - "dhcpd_time_offset_enabled": p.DhcpdTimeOffsetEnabled.Txt, - "dhcp_relay_enabledy": p.DhcpRelayEnabled.Txt, - "dhcpd_gateway_enabled": p.DhcpdGatewayEnabled.Txt, - "enabled": p.Enabled.Txt, - "vlan_enabled": p.VlanEnabled.Txt, - "attr_no_delete": p.AttrNoDelete.Txt, - "is_guest": p.IsGuest.Txt, - "is_nat": p.IsNat.Txt, - "networkgroup": p.Networkgroup, - "site_id": p.SiteID, + "device_name": u.Name, + "device_id": u.ID, + "device_mac": u.Mac, + "site_name": u.SiteName, + "up": p.Up.Txt, + "enabled": p.Enabled.Txt, + "site_id": p.SiteID, + "ip": p.IP, + "ip_subnet": p.IPSubnet, + "mac": p.Mac, + "name": p.Name, + "domain_name": p.DomainName, + "purpose": p.Purpose, } fields := map[string]interface{}{ "domain_name": p.DomainName, @@ -263,35 +237,21 @@ func UDMPoints(u *unifi.UDM, now time.Time) ([]*influx.Point, error) { for _, p := range u.PortTable { tags := map[string]string{ - "site_id": u.SiteID, - "site_name": u.SiteName, - "device_name": u.Name, - "name": p.Name, - "enable": p.Enable.Txt, - "is_uplink": p.IsUplink.Txt, - "up": p.Up.Txt, - "portconf_id": p.PortconfID, - "dot1x_mode": p.Dot1XMode, - "dot1x_status": p.Dot1XStatus, - "stp_state": p.StpState, - "sfp_found": p.SfpFound.Txt, - "op_mode": p.OpMode, - "poe_mode": p.PoeMode, - "port_poe": p.PortPoe.Txt, - "port_idx": p.PortIdx.Txt, - "port_id": u.Name + " Port " + p.PortIdx.Txt, - "poe_enable": p.PoeEnable.Txt, - "flowctrl_rx": p.FlowctrlRx.Txt, - "flowctrl_tx": p.FlowctrlTx.Txt, - "autoneg": p.Autoneg.Txt, - "full_duplex": p.FullDuplex.Txt, - "jumbo": p.Jumbo.Txt, - "masked": p.Masked.Txt, - "poe_good": p.PoeGood.Txt, - "media": p.Media, - "poe_class": p.PoeClass, - "poe_caps": p.PoeCaps.Txt, - "aggregated_by": p.AggregatedBy.Txt, + "site_id": u.SiteID, + "site_name": u.SiteName, + "device_name": u.Name, + "name": p.Name, + "enable": p.Enable.Txt, + "up": p.Up.Txt, + "poe_mode": p.PoeMode, + "port_poe": p.PortPoe.Txt, + "port_idx": p.PortIdx.Txt, + "port_id": u.Name + " Port " + p.PortIdx.Txt, + "poe_enable": p.PoeEnable.Txt, + "flowctrl_rx": p.FlowctrlRx.Txt, + "flowctrl_tx": p.FlowctrlTx.Txt, + "media": p.Media, + "poe_class": p.PoeClass, } fields := map[string]interface{}{ "dbytes_r": p.BytesR.Val, @@ -314,7 +274,6 @@ func UDMPoints(u *unifi.UDM, now time.Time) ([]*influx.Point, error) { "poe_current": p.PoeCurrent.Val, "poe_power": p.PoePower.Val, "poe_voltage": p.PoeVoltage.Val, - "full_duplex": p.FullDuplex.Val, } pt, err = influx.NewPoint("usw_ports", tags, fields, now) if err != nil { @@ -327,27 +286,15 @@ func UDMPoints(u *unifi.UDM, now time.Time) ([]*influx.Point, error) { // we're done now. the following code process UDM (non-pro) UAP data. } tags = map[string]string{ - "id": u.ID, - "ip": u.IP, - "mac": u.Mac, - "device_type": u.Stat.Ap.O, - "device_oid": u.Stat.Ap.Oid, - "device_ap": u.Stat.Ap.Ap, - "site_id": u.SiteID, - "site_name": u.SiteName, - "name": u.Name, - "adopted": u.Adopted.Txt, - "cfgversion": u.Cfgversion, - "config_network_ip": u.ConfigNetwork.IP, - "config_network_type": u.ConfigNetwork.Type, - "connect_request_ip": u.ConnectRequestIP, - "device_id": u.DeviceID, - "has_eth1": u.HasEth1.Txt, - "inform_ip": u.InformIP, - "known_cfgversion": u.KnownCfgversion, - "model": u.Model, - "serial": u.Serial, - "type": u.Type, + "ip": u.IP, + "mac": u.Mac, + "site_id": u.SiteID, + "site_name": u.SiteName, + "name": u.Name, + "cfgversion": u.Cfgversion, + "model": u.Model, + "serial": u.Serial, + "type": u.Type, } fields = map[string]interface{}{ "ip": u.IP, @@ -360,7 +307,6 @@ func UDMPoints(u *unifi.UDM, now time.Time) ([]*influx.Point, error) { "user-num_sta": int(u.UserWlanNumSta.Val), "guest-num_sta": int(u.GuestWlanNumSta.Val), "num_sta": u.WlanNumSta.Val, - "version": u.Version, "loadavg_1": u.SysStats.Loadavg1.Val, "loadavg_5": u.SysStats.Loadavg5.Val, "loadavg_15": u.SysStats.Loadavg15.Val, @@ -408,7 +354,7 @@ func UDMPoints(u *unifi.UDM, now time.Time) ([]*influx.Point, error) { if err != nil { return nil, err } - uapPoints, err := processVAPs(*u.VapTable, *u.RadioTable, *u.RadioTableStats, u.Name, u.ID, u.Mac, u.SiteName, now) + uapPoints, err := processVAPs(*u.VapTable, *u.RadioTable, *u.RadioTableStats, u.Name, u.Mac, u.SiteName, now) if err != nil { return nil, err } diff --git a/pkg/influxunifi/usg.go b/pkg/influxunifi/usg.go index 606011c0..a86f28b4 100644 --- a/pkg/influxunifi/usg.go +++ b/pkg/influxunifi/usg.go @@ -15,33 +15,21 @@ func USGPoints(u *unifi.USG, now time.Time) ([]*influx.Point, error) { u.Stat.Gw = &unifi.Gw{} } tags := map[string]string{ - "id": u.ID, - "mac": u.Mac, - "device_type": u.Stat.O, - "device_oid": u.Stat.Oid, - "site_id": u.SiteID, - "site_name": u.SiteName, - "adopted": u.Adopted.Txt, - "name": u.Name, - "cfgversion": u.Cfgversion, - "config_network_ip": u.ConfigNetwork.IP, - "config_network_type": u.ConfigNetwork.Type, - "connect_request_ip": u.ConnectRequestIP, - "connect_request_port": u.ConnectRequestPort, - "device_id": u.DeviceID, - "guest_token": u.GuestToken, - "inform_ip": u.InformIP, - "known_cfgversion": u.KnownCfgversion, - "led_override": u.LedOverride, - "locating": u.Locating.Txt, - "model": u.Model, - "outdoor_mode_override": u.OutdoorModeOverride, - "serial": u.Serial, - "type": u.Type, - "usg_caps": u.UsgCaps.Txt, - "speedtest-status-saved": u.SpeedtestStatusSaved.Txt, - "wan1_up": u.Wan1.Up.Txt, - "wan2_up": u.Wan2.Up.Txt, + "id": u.ID, + "mac": u.Mac, + "device_type": u.Stat.O, + "site_id": u.SiteID, + "site_name": u.SiteName, + "name": u.Name, + "cfgversion": u.Cfgversion, + "device_id": u.DeviceID, + "known_cfgversion": u.KnownCfgversion, + "model": u.Model, + "serial": u.Serial, + "type": u.Type, + "usg_caps": u.UsgCaps.Txt, + "wan1_up": u.Wan1.Up.Txt, + "wan2_up": u.Wan2.Up.Txt, } fields := map[string]interface{}{ "ip": u.IP, @@ -153,33 +141,19 @@ func USGPoints(u *unifi.USG, now time.Time) ([]*influx.Point, error) { points := []*influx.Point{pt} for _, p := range u.NetworkTable { tags := map[string]string{ - "device_name": u.Name, - "device_id": u.ID, - "device_mac": u.Mac, - "site_name": u.SiteName, - "up": p.Up.Txt, - "dhcpd_dns_enabled": p.DhcpdDNSEnabled.Txt, - "dhcpd_enabled": p.DhcpdEnabled.Txt, - "dhcpd_time_offset_enabled": p.DhcpdTimeOffsetEnabled.Txt, - "dhcp_relay_enabledy": p.DhcpRelayEnabled.Txt, - "dhcpd_gateway_enabled": p.DhcpdGatewayEnabled.Txt, - "enabled": p.Enabled.Txt, - "vlan_enabled": p.VlanEnabled.Txt, - "attr_no_delete": p.AttrNoDelete.Txt, - "is_guest": p.IsGuest.Txt, - "is_nat": p.IsNat.Txt, - "networkgroup": p.Networkgroup, - "site_id": p.SiteID, - "ip": p.IP, - "ip_subnet": p.IPSubnet, - "mac": p.Mac, - "name": p.Name, - "domain_name": p.DomainName, - "dhcpd_start": p.DhcpdStart, - "dhcpd_stop": p.DhcpdStop, - "ipv6_interface_type": p.Ipv6InterfaceType, - "attr_hidden_id": p.AttrHiddenID, - "purpose": p.Purpose, + "device_name": u.Name, + "device_id": u.ID, + "device_mac": u.Mac, + "site_name": u.SiteName, + "up": p.Up.Txt, + "enabled": p.Enabled.Txt, + "site_id": p.SiteID, + "ip": p.IP, + "ip_subnet": p.IPSubnet, + "mac": p.Mac, + "name": p.Name, + "domain_name": p.DomainName, + "purpose": p.Purpose, } fields := map[string]interface{}{ "num_sta": p.NumSta.Val, diff --git a/pkg/influxunifi/usw.go b/pkg/influxunifi/usw.go index 225a4340..a627363a 100644 --- a/pkg/influxunifi/usw.go +++ b/pkg/influxunifi/usw.go @@ -14,29 +14,16 @@ func USWPoints(u *unifi.USW, now time.Time) ([]*influx.Point, error) { u.Stat.Sw = &unifi.Sw{} } tags := map[string]string{ - "id": u.ID, - "mac": u.Mac, - "device_oid": u.Stat.Oid, - "site_id": u.SiteID, - "site_name": u.SiteName, - "name": u.Name, - "adopted": u.Adopted.Txt, - "cfgversion": u.Cfgversion, - "config_network_ip": u.ConfigNetwork.IP, - "config_network_type": u.ConfigNetwork.Type, - "device_id": u.DeviceID, - "inform_ip": u.InformIP, - "known_cfgversion": u.KnownCfgversion, - "locating": u.Locating.Txt, - "model": u.Model, - "serial": u.Serial, - "type": u.Type, - "dot1x_portctrl_enabled": u.Dot1XPortctrlEnabled.Txt, - "flowctrl_enabled": u.FlowctrlEnabled.Txt, - "has_fan": u.HasFan.Txt, - "has_temperature": u.HasTemperature.Txt, - "jumboframe_enabled": u.JumboframeEnabled.Txt, - "stp_version": u.StpVersion, + "id": u.ID, + "mac": u.Mac, + "site_id": u.SiteID, + "site_name": u.SiteName, + "name": u.Name, + "model": u.Model, + "serial": u.Serial, + "type": u.Type, + "has_fan": u.HasFan.Txt, + "has_temperature": u.HasTemperature.Txt, } fields := map[string]interface{}{ "fw_caps": u.FwCaps.Val, @@ -85,35 +72,21 @@ func USWPoints(u *unifi.USW, now time.Time) ([]*influx.Point, error) { points := []*influx.Point{pt} for _, p := range u.PortTable { tags := map[string]string{ - "site_id": u.SiteID, - "site_name": u.SiteName, - "device_name": u.Name, - "name": p.Name, - "enable": p.Enable.Txt, - "is_uplink": p.IsUplink.Txt, - "up": p.Up.Txt, - "portconf_id": p.PortconfID, - "dot1x_mode": p.Dot1XMode, - "dot1x_status": p.Dot1XStatus, - "stp_state": p.StpState, - "sfp_found": p.SfpFound.Txt, - "op_mode": p.OpMode, - "poe_mode": p.PoeMode, - "port_poe": p.PortPoe.Txt, - "port_idx": p.PortIdx.Txt, - "port_id": u.Name + " Port " + p.PortIdx.Txt, - "poe_enable": p.PoeEnable.Txt, - "flowctrl_rx": p.FlowctrlRx.Txt, - "flowctrl_tx": p.FlowctrlTx.Txt, - "autoneg": p.Autoneg.Txt, - "full_duplex": p.FullDuplex.Txt, - "jumbo": p.Jumbo.Txt, - "masked": p.Masked.Txt, - "poe_good": p.PoeGood.Txt, - "media": p.Media, - "poe_class": p.PoeClass, - "poe_caps": p.PoeCaps.Txt, - "aggregated_by": p.AggregatedBy.Txt, + "site_id": u.SiteID, + "site_name": u.SiteName, + "device_name": u.Name, + "name": p.Name, + "enable": p.Enable.Txt, + "up": p.Up.Txt, + "poe_mode": p.PoeMode, + "port_poe": p.PortPoe.Txt, + "port_idx": p.PortIdx.Txt, + "port_id": u.Name + " Port " + p.PortIdx.Txt, + "poe_enable": p.PoeEnable.Txt, + "flowctrl_rx": p.FlowctrlRx.Txt, + "flowctrl_tx": p.FlowctrlTx.Txt, + "media": p.Media, + "poe_class": p.PoeClass, } fields := map[string]interface{}{ "dbytes_r": p.BytesR.Val, @@ -136,7 +109,6 @@ func USWPoints(u *unifi.USW, now time.Time) ([]*influx.Point, error) { "poe_current": p.PoeCurrent.Val, "poe_power": p.PoePower.Val, "poe_voltage": p.PoeVoltage.Val, - "full_duplex": p.FullDuplex.Val, } pt, err = influx.NewPoint("usw_ports", tags, fields, now) if err != nil { From cef7815e2d939dc437dc8ebfca845d03b15b9838 Mon Sep 17 00:00:00 2001 From: davidnewhall2 Date: Sat, 30 Nov 2019 03:42:17 -0800 Subject: [PATCH 03/10] allow more data reduction --- examples/up.conf.example | 12 ++++--- examples/up.json.example | 3 +- examples/up.xml.example | 78 ++++------------------------------------ examples/up.yaml.example | 53 +++------------------------ pkg/influxunifi/site.go | 27 ++++++-------- pkg/influxunifi/udm.go | 42 ++++++++++------------ pkg/influxunifi/usg.go | 24 +++++-------- pkg/influxunifi/usw.go | 19 +++++----- pkg/poller/config.go | 3 +- pkg/poller/influx.go | 2 +- pkg/poller/prometheus.go | 10 ++---- pkg/poller/start.go | 1 + pkg/poller/unifi.go | 5 ++- 13 files changed, 76 insertions(+), 203 deletions(-) diff --git a/examples/up.conf.example b/examples/up.conf.example index eb4fb0f2..c2e8cbbe 100644 --- a/examples/up.conf.example +++ b/examples/up.conf.example @@ -56,10 +56,6 @@ unifi_user = "influx" unifi_pass = "4BB9345C-2341-48D7-99F5-E01B583FF77F" unifi_url = "https://127.0.0.1:8443" -# Enable collection of Intrusion Detection System Data (InfluxDB only). -# Only useful if IDS or IPS are enabled on one of the sites. -collect_ids = false - # Some controllers or reverse proxy configurations do not allow cookies to be # re-user on every request (every interval). This setting provides a workaround # That causes the poller to re-auth (login) to the controller on every interval. @@ -67,6 +63,14 @@ collect_ids = false # a few more requests to your controller every interval. reauthenticate = false +# Enable collection of Intrusion Detection System Data (InfluxDB only). +# Only useful if IDS or IPS are enabled on one of the sites. +save_ids = false + +# Enable collection of site data. This data powers the Network Sites dashboard. +# It's not valuable to everyone and setting this to false will save resources. +save_sites = true + # If your UniFi controller has a valid SSL certificate (like lets encrypt), # you can enable this option to validate it. Otherwise, any SSL certificate is # valid. If you don't know if you have a valid SSL cert, then you don't have one. diff --git a/examples/up.json.example b/examples/up.json.example index e9961505..7842987f 100644 --- a/examples/up.json.example +++ b/examples/up.json.example @@ -13,7 +13,8 @@ "unifi_user": "influx", "unifi_pass": "", "unifi_url": "https://127.0.0.1:8443", - "collect_ids": false, + "save_ids": false, + "save_sites": true, "reauthenticate": false, "verify_ssl": false } diff --git a/examples/up.xml.example b/examples/up.xml.example index 325f12d4..e4523e3a 100644 --- a/examples/up.xml.example +++ b/examples/up.xml.example @@ -2,99 +2,33 @@ - + all + 60s - - 30s - - false - - false - influx - - 0.0.0.0:9130 - unifi unifi http://127.0.0.1:8086 unifi - false - influx https://127.0.0.1:8443 - - false - false - false + false + true + diff --git a/examples/up.yaml.example b/examples/up.yaml.example index 00e75fba..0eac5a24 100644 --- a/examples/up.yaml.example +++ b/examples/up.yaml.example @@ -1,73 +1,28 @@ +######################################################## # UniFi Poller primary configuration file. YAML FORMAT # -# provided values are defaults # +# provided values are defaults. See up.conf.example! # ######################################################## --- -# If the controller has more than one site, specify which sites to poll here. -# Set this to "default" to poll only the first site on the controller. -# A setting of "all" will poll all sites; this works if you only have 1 site too. sites: - all - -# The UniFi Controller only updates traffic stats about every 30 seconds. -# Setting this to something lower may lead to "zeros" in your data. -# If you're getting zeros now, set this to "1m" -# Only has effect if "mode" (below) is "influx" - other modes do not use interval. interval: "30s" -# Turns on line numbers, microsecond logging, and a per-device log. -# The default is false, but I personally leave this on at home (four devices). -# This may be noisy if you have a lot of devices. It adds one line per device. debug: false - -# Turns off per-interval logs. Only startup and error logs will be emitted. -# Recommend enabling debug with this setting for better error logging. quiet: false -# Which mode to run this application in. The default mode is "influx". Providing -# an invalid mode will also result in "influx". In this default mode the application -# runs as a daemon and polls the controller at the configured interval. -# -# There are two other options at this time: "influxlambda" and "prometheus" -# -# Mode "influxlambda" makes the application exit after collecting and reporting metrics -# to InfluxDB one time. This mode requires an external process like an AWS Lambda -# or a simple crontab to keep the timings accurate on UniFi Poller run intervals. -# -# Mode "prometheus" opens an HTTP server on port 9130 and exports the metrics at -# /metrics for polling collection by a prometheus server. This disables influxdb. -# IMPORTANT: The prometheus mode is still beta. -# Please help us test and provide your feedback on the github repo! mode: "influx" - -# This controls on which ip and port /metrics is exported when mode is "prometheus". -# This has no effect in other modes. Must contain a colon and port. http_listen: "0.0.0.0:9130" -# InfluxDB does not require auth by default, so the user/password are probably unimportant. influx_url: "http://127.0.0.1:8086" influx_user: "unifi" influx_pass: "unifi" -# Be sure to create this database. influx_db: "unifi" -# If your InfluxDB uses an invalid SSL cert, set this to true. influx_insecure_ssl: false -# Make a read-only user in the UniFi Admin Settings. unifi_user: "influx" unifi_pass: "" unifi_url: "https://127.0.0.1:8443" - -# Enable collection of Intrusion Detection System Data (InfluxDB only). -# Only useful if IDS or IPS are enabled on one of the sites. -collect_ids: false - -# Some controllers or reverse proxy configurations do not allow cookies to be -# re-user on every request (every interval). This setting provides a workaround -# That causes the poller to re-auth (login) to the controller on every interval. -# Only enable this if you get login errors after 30 seconds. This will generate -# a few more requests to your controller every interval. reauthenticate: false - -# If your UniFi controller has a valid SSL certificate, you can enable -# this option to validate it. Otherwise, any SSL certificate is valid. verify_ssl: false +save_ids: false +save_sites: true diff --git a/pkg/influxunifi/site.go b/pkg/influxunifi/site.go index 466a43ac..dbfdac38 100644 --- a/pkg/influxunifi/site.go +++ b/pkg/influxunifi/site.go @@ -1,7 +1,6 @@ package influxunifi import ( - "strings" "time" influx "github.com/influxdata/influxdb1-client/v2" @@ -14,20 +13,16 @@ func SitePoints(u *unifi.Site, now time.Time) ([]*influx.Point, error) { points := []*influx.Point{} for _, s := range u.Health { tags := map[string]string{ - "name": u.Name, - "site_name": u.SiteName, - "desc": u.Desc, - "status": s.Status, - "subsystem": s.Subsystem, - "wan_ip": s.WanIP, - "netmask": s.Netmask, - "gw_name": s.GwName, - "gw_mac": s.GwMac, - "gw_version": s.GwVersion, - "lan_ip": s.LanIP, - "nameservers": strings.Join(s.Nameservers, ","), - "gateways": strings.Join(s.Gateways, ","), - "num_new_alarms": u.NumNewAlarms.Txt, + "name": u.Name, + "site_name": u.SiteName, + "desc": u.Desc, + "status": s.Status, + "subsystem": s.Subsystem, + "wan_ip": s.WanIP, + "netmask": s.Netmask, + "gw_name": s.GwName, + "gw_mac": s.GwMac, + "lan_ip": s.LanIP, } fields := map[string]interface{}{ "num_user": s.NumUser.Val, @@ -61,8 +56,6 @@ func SitePoints(u *unifi.Site, now time.Time) ([]*influx.Point, error) { "remote_user_rx_packets": s.RemoteUserRxPackets.Val, "remote_user_tx_packets": s.RemoteUserTxPackets.Val, "num_new_alarms": u.NumNewAlarms.Val, - "nameservers": len(s.Nameservers), - "gateways": len(s.Gateways), } pt, err := influx.NewPoint("subsystems", tags, fields, time.Now()) if err != nil { diff --git a/pkg/influxunifi/udm.go b/pkg/influxunifi/udm.go index 54f9494f..f679c922 100644 --- a/pkg/influxunifi/udm.go +++ b/pkg/influxunifi/udm.go @@ -17,20 +17,15 @@ func UDMPoints(u *unifi.UDM, now time.Time) ([]*influx.Point, error) { u.Stat.Gw = &unifi.Gw{} } tags := map[string]string{ - "id": u.ID, - "mac": u.Mac, - "site_id": u.SiteID, - "site_name": u.SiteName, - "name": u.Name, - "cfgversion": u.Cfgversion, - "device_id": u.DeviceID, - "known_cfgversion": u.KnownCfgversion, - "model": u.Model, - "serial": u.Serial, - "type": u.Type, - "usg_caps": u.UsgCaps.Txt, - "wan1_up": u.Wan1.Up.Txt, - "wan2_up": u.Wan2.Up.Txt, + "ip": u.IP, + "mac": u.Mac, + "site_id": u.SiteID, + "site_name": u.SiteName, + "name": u.Name, + "cfgversion": u.Cfgversion, + "model": u.Model, + "serial": u.Serial, + "type": u.Type, } fields := map[string]interface{}{ "ip": u.IP, @@ -138,16 +133,15 @@ func UDMPoints(u *unifi.UDM, now time.Time) ([]*influx.Point, error) { } points := []*influx.Point{pt} tags = map[string]string{ - "id": u.ID, - "mac": u.Mac, - "site_id": u.SiteID, - "site_name": u.SiteName, - "name": u.Name, - "model": u.Model, - "serial": u.Serial, - "type": u.Type, - "has_fan": u.HasFan.Txt, - "has_temperature": u.HasTemperature.Txt, + "ip": u.IP, + "mac": u.Mac, + "site_id": u.SiteID, + "site_name": u.SiteName, + "name": u.Name, + "cfgversion": u.Cfgversion, + "model": u.Model, + "serial": u.Serial, + "type": u.Type, } fields = map[string]interface{}{ "fw_caps": u.FwCaps.Val, diff --git a/pkg/influxunifi/usg.go b/pkg/influxunifi/usg.go index a86f28b4..81ae87dc 100644 --- a/pkg/influxunifi/usg.go +++ b/pkg/influxunifi/usg.go @@ -15,21 +15,15 @@ func USGPoints(u *unifi.USG, now time.Time) ([]*influx.Point, error) { u.Stat.Gw = &unifi.Gw{} } tags := map[string]string{ - "id": u.ID, - "mac": u.Mac, - "device_type": u.Stat.O, - "site_id": u.SiteID, - "site_name": u.SiteName, - "name": u.Name, - "cfgversion": u.Cfgversion, - "device_id": u.DeviceID, - "known_cfgversion": u.KnownCfgversion, - "model": u.Model, - "serial": u.Serial, - "type": u.Type, - "usg_caps": u.UsgCaps.Txt, - "wan1_up": u.Wan1.Up.Txt, - "wan2_up": u.Wan2.Up.Txt, + "ip": u.IP, + "mac": u.Mac, + "site_id": u.SiteID, + "site_name": u.SiteName, + "name": u.Name, + "cfgversion": u.Cfgversion, + "model": u.Model, + "serial": u.Serial, + "type": u.Type, } fields := map[string]interface{}{ "ip": u.IP, diff --git a/pkg/influxunifi/usw.go b/pkg/influxunifi/usw.go index a627363a..7f392962 100644 --- a/pkg/influxunifi/usw.go +++ b/pkg/influxunifi/usw.go @@ -14,16 +14,15 @@ func USWPoints(u *unifi.USW, now time.Time) ([]*influx.Point, error) { u.Stat.Sw = &unifi.Sw{} } tags := map[string]string{ - "id": u.ID, - "mac": u.Mac, - "site_id": u.SiteID, - "site_name": u.SiteName, - "name": u.Name, - "model": u.Model, - "serial": u.Serial, - "type": u.Type, - "has_fan": u.HasFan.Txt, - "has_temperature": u.HasTemperature.Txt, + "ip": u.IP, + "mac": u.Mac, + "site_id": u.SiteID, + "site_name": u.SiteName, + "name": u.Name, + "cfgversion": u.Cfgversion, + "model": u.Model, + "serial": u.Serial, + "type": u.Type, } fields := map[string]interface{}{ "fw_caps": u.FwCaps.Val, diff --git a/pkg/poller/config.go b/pkg/poller/config.go index 743d3996..37ca9a90 100644 --- a/pkg/poller/config.go +++ b/pkg/poller/config.go @@ -65,9 +65,10 @@ type Config struct { Debug bool `json:"debug" toml:"debug" xml:"debug" yaml:"debug"` Quiet bool `json:"quiet,omitempty" toml:"quiet,omitempty" xml:"quiet" yaml:"quiet"` VerifySSL bool `json:"verify_ssl" toml:"verify_ssl" xml:"verify_ssl" yaml:"verify_ssl"` - CollectIDS bool `json:"collect_ids" toml:"collect_ids" xml:"collect_ids" yaml:"collect_ids"` + SaveIDS bool `json:"save_ids" toml:"save_ids" xml:"save_ids" yaml:"save_ids"` ReAuth bool `json:"reauthenticate" toml:"reauthenticate" xml:"reauthenticate" yaml:"reauthenticate"` InfxBadSSL bool `json:"influx_insecure_ssl" toml:"influx_insecure_ssl" xml:"influx_insecure_ssl" yaml:"influx_insecure_ssl"` + SaveSites bool `json:"save_sites,omitempty" toml:"save_sites,omitempty" xml:"save_sites" yaml:"save_sites"` Mode string `json:"mode" toml:"mode" xml:"mode" yaml:"mode"` HTTPListen string `json:"http_listen" toml:"http_listen" xml:"http_listen" yaml:"http_listen"` Namespace string `json:"namespace" toml:"namespace" xml:"namespace" yaml:"namespace"` diff --git a/pkg/poller/influx.go b/pkg/poller/influx.go index 1eb2bb83..9b2872d2 100644 --- a/pkg/poller/influx.go +++ b/pkg/poller/influx.go @@ -70,7 +70,7 @@ func (u *UnifiPoller) LogInfluxReport(m *influxunifi.Metrics) { fields += len(i) } idsMsg := "" - if u.Config.CollectIDS { + if u.Config.SaveIDS { idsMsg = fmt.Sprintf("IDS Events: %d, ", len(m.IDSList)) } u.Logf("UniFi Measurements Recorded. Sites: %d, Clients: %d, "+ diff --git a/pkg/poller/prometheus.go b/pkg/poller/prometheus.go index 88502dc9..45dd1176 100644 --- a/pkg/poller/prometheus.go +++ b/pkg/poller/prometheus.go @@ -1,7 +1,6 @@ package poller import ( - "fmt" "net/http" "strings" "time" @@ -54,16 +53,11 @@ func (u *UnifiPoller) ExportMetrics() (*metrics.Metrics, error) { // This is run by Prometheus as LoggingFn func (u *UnifiPoller) LogExportReport(report *promunifi.Report) { m := report.Metrics - idsMsg := "" - if u.Config.CollectIDS { - idsMsg = fmt.Sprintf(", IDS Events: %d, ", len(m.IDSList)) - } - u.Logf("UniFi Measurements Exported. Site: %d, Client: %d, "+ - "UAP: %d, USG/UDM: %d, USW: %d%s, Descs: %d, "+ + "UAP: %d, USG/UDM: %d, USW: %d, Descs: %d, "+ "Metrics: %d, Errs: %d, 0s: %d, Reqs/Total: %v / %v", len(m.Sites), len(m.Clients), len(m.UAPs), len(m.UDMs)+len(m.USGs), len(m.USWs), - idsMsg, report.Descs, report.Total, report.Errors, report.Zeros, + report.Descs, report.Total, report.Errors, report.Zeros, report.Fetch.Round(time.Millisecond/oneDecimalPoint), report.Elapsed.Round(time.Millisecond/oneDecimalPoint)) } diff --git a/pkg/poller/start.go b/pkg/poller/start.go index 11d70228..342d4d58 100644 --- a/pkg/poller/start.go +++ b/pkg/poller/start.go @@ -25,6 +25,7 @@ func New() *UnifiPoller { UnifiBase: defaultUnifiURL, Interval: Duration{defaultInterval}, Sites: []string{"all"}, + SaveSites: true, HTTPListen: defaultHTTPListen, Namespace: appName, }, Flag: &Flag{}, diff --git a/pkg/poller/unifi.go b/pkg/poller/unifi.go index c431f252..73708243 100644 --- a/pkg/poller/unifi.go +++ b/pkg/poller/unifi.go @@ -68,7 +68,7 @@ func (u *UnifiPoller) CollectMetrics() (*metrics.Metrics, error) { // Get the sites we care about. m.Sites, err = u.GetFilteredSites() u.LogError(err, "unifi.GetSites()") - if u.Config.CollectIDS { + if u.Config.SaveIDS { m.IDSList, err = u.Unifi.GetIDS(m.Sites, time.Now().Add(u.Config.Interval.Duration), time.Now()) u.LogError(err, "unifi.GetIDS()") } @@ -111,6 +111,9 @@ func (u *UnifiPoller) AugmentMetrics(metrics *metrics.Metrics) { metrics.Clients[i].GwName = devices[c.GwMac] metrics.Clients[i].RadioDescription = bssdIDs[metrics.Clients[i].Bssid] + metrics.Clients[i].RadioProto } + if !u.Config.SaveSites { + metrics.Sites = nil + } } // GetFilteredSites returns a list of sites to fetch data for. From 50c1a635c6eb116f7d53a9f5d3722ac852a8a10b Mon Sep 17 00:00:00 2001 From: davidnewhall2 Date: Sat, 30 Nov 2019 16:45:22 -0800 Subject: [PATCH 04/10] Improve influx library --- pkg/influxunifi/clients.go | 146 +++++------- pkg/influxunifi/ids.go | 11 +- pkg/influxunifi/metrics.go | 180 +++++++++----- pkg/influxunifi/report.go | 69 ++++++ pkg/influxunifi/site.go | 97 ++++---- pkg/influxunifi/uap.go | 157 ++++++------ pkg/influxunifi/udm.go | 474 ++++++++++++++++--------------------- pkg/influxunifi/usg.go | 251 +++++++++----------- pkg/influxunifi/usw.go | 132 +++++------ pkg/poller/config.go | 4 +- pkg/poller/influx.go | 59 ++--- pkg/poller/start.go | 4 +- 12 files changed, 773 insertions(+), 811 deletions(-) create mode 100644 pkg/influxunifi/report.go diff --git a/pkg/influxunifi/clients.go b/pkg/influxunifi/clients.go index 0ff5fcd8..f954da17 100644 --- a/pkg/influxunifi/clients.go +++ b/pkg/influxunifi/clients.go @@ -1,93 +1,77 @@ package influxunifi import ( - "time" - - influx "github.com/influxdata/influxdb1-client/v2" "golift.io/unifi" ) -// ClientPoints generates Unifi Client datapoints for InfluxDB. +// batchClient generates Unifi Client datapoints for InfluxDB. // These points can be passed directly to influx. -func ClientPoints(c *unifi.Client, now time.Time) ([]*influx.Point, error) { +func (u *InfluxUnifi) batchClient(r report, s *unifi.Client) { tags := map[string]string{ - "id": c.ID, - "mac": c.Mac, - "user_id": c.UserID, - "site_id": c.SiteID, - "site_name": c.SiteName, - "ap_mac": c.ApMac, - "gw_mac": c.GwMac, - "sw_mac": c.SwMac, - "ap_name": c.ApName, - "gw_name": c.GwName, - "sw_name": c.SwName, - "oui": c.Oui, - "radio_name": c.RadioName, - "radio": c.Radio, - "radio_proto": c.RadioProto, - "name": c.Name, - "fixed_ip": c.FixedIP, - "sw_port": c.SwPort.Txt, - "os_class": c.OsClass.Txt, - "os_name": c.OsName.Txt, - "dev_cat": c.DevCat.Txt, - "dev_id": c.DevID.Txt, - "dev_vendor": c.DevVendor.Txt, - "dev_family": c.DevFamily.Txt, - "is_wired": c.IsWired.Txt, - "is_guest": c.IsGuest.Txt, - "use_fixedip": c.UseFixedIP.Txt, - "channel": c.Channel.Txt, - "vlan": c.Vlan.Txt, + "mac": s.Mac, + "site_name": s.SiteName, + "ap_name": s.ApName, + "gw_name": s.GwName, + "sw_name": s.SwName, + "oui": s.Oui, + "radio_name": s.RadioName, + "radio": s.Radio, + "radio_proto": s.RadioProto, + "name": s.Name, + "fixed_ip": s.FixedIP, + "sw_port": s.SwPort.Txt, + "os_class": s.OsClass.Txt, + "os_name": s.OsName.Txt, + "dev_cat": s.DevCat.Txt, + "dev_id": s.DevID.Txt, + "dev_vendor": s.DevVendor.Txt, + "dev_family": s.DevFamily.Txt, + "is_wired": s.IsWired.Txt, + "is_guest": s.IsGuest.Txt, + "use_fixedip": s.UseFixedIP.Txt, + "channel": s.Channel.Txt, + "vlan": s.Vlan.Txt, } fields := map[string]interface{}{ - "anomalies": c.Anomalies, - "ip": c.IP, - "essid": c.Essid, - "bssid": c.Bssid, - "radio_desc": c.RadioDescription, - "satisfaction": c.Satisfaction.Val, - "hostname": c.Hostname, - "bytes_r": c.BytesR, - "ccq": c.Ccq, - "first_seen": c.FirstSeen, - "idle_time": c.IdleTime, - "last_seen": c.LastSeen, - "network": c.Network, - "noise": c.Noise, - "note": c.Note, - "roam_count": c.RoamCount, - "rssi": c.Rssi, - "rx_bytes": c.RxBytes, - "rx_bytes_r": c.RxBytesR, - "rx_packets": c.RxPackets, - "rx_rate": c.RxRate, - "signal": c.Signal, - "tx_bytes": c.TxBytes, - "tx_bytes_r": c.TxBytesR, - "tx_packets": c.TxPackets, - "tx_retries": c.TxRetries, - "tx_power": c.TxPower, - "tx_rate": c.TxRate, - "uptime": c.Uptime, - "wifi_tx_attempts": c.WifiTxAttempts, - "wired-rx_bytes": c.WiredRxBytes, - "wired-rx_bytes-r": c.WiredRxBytesR, - "wired-rx_packets": c.WiredRxPackets, - "wired-tx_bytes": c.WiredTxBytes, - "wired-tx_bytes-r": c.WiredTxBytesR, - "wired-tx_packets": c.WiredTxPackets, - "dpi_app": c.DpiStats.App.Val, - "dpi_cat": c.DpiStats.Cat.Val, - "dpi_rx_bytes": c.DpiStats.RxBytes.Val, - "dpi_rx_packets": c.DpiStats.RxPackets.Val, - "dpi_tx_bytes": c.DpiStats.TxBytes.Val, - "dpi_tx_packets": c.DpiStats.TxPackets.Val, + "anomalies": s.Anomalies, + "ip": s.IP, + "essid": s.Essid, + "bssid": s.Bssid, + "radio_desc": s.RadioDescription, + "satisfaction": s.Satisfaction.Val, + "bytes_r": s.BytesR, + "ccq": s.Ccq, + "noise": s.Noise, + "note": s.Note, + "roam_count": s.RoamCount, + "rssi": s.Rssi, + "rx_bytes": s.RxBytes, + "rx_bytes_r": s.RxBytesR, + "rx_packets": s.RxPackets, + "rx_rate": s.RxRate, + "signal": s.Signal, + "tx_bytes": s.TxBytes, + "tx_bytes_r": s.TxBytesR, + "tx_packets": s.TxPackets, + "tx_retries": s.TxRetries, + "tx_power": s.TxPower, + "tx_rate": s.TxRate, + "uptime": s.Uptime, + "wifi_tx_attempts": s.WifiTxAttempts, + "wired-rx_bytes": s.WiredRxBytes, + "wired-rx_bytes-r": s.WiredRxBytesR, + "wired-rx_packets": s.WiredRxPackets, + "wired-tx_bytes": s.WiredTxBytes, + "wired-tx_bytes-r": s.WiredTxBytesR, + "wired-tx_packets": s.WiredTxPackets, + /* + "dpi_app": c.DpiStats.App.Val, + "dpi_cat": c.DpiStats.Cat.Val, + "dpi_rx_bytes": c.DpiStats.RxBytes.Val, + "dpi_rx_packets": c.DpiStats.RxPackets.Val, + "dpi_tx_bytes": c.DpiStats.TxBytes.Val, + "dpi_tx_packets": c.DpiStats.TxPackets.Val, + */ } - pt, err := influx.NewPoint("clients", tags, fields, now) - if err != nil { - return nil, err - } - return []*influx.Point{pt}, nil + r.send(&metric{Table: "clients", Tags: tags, Fields: fields}) } diff --git a/pkg/influxunifi/ids.go b/pkg/influxunifi/ids.go index bf444f5f..c7b8edba 100644 --- a/pkg/influxunifi/ids.go +++ b/pkg/influxunifi/ids.go @@ -1,13 +1,12 @@ package influxunifi import ( - influx "github.com/influxdata/influxdb1-client/v2" "golift.io/unifi" ) -// IDSPoints generates intrusion detection datapoints for InfluxDB. +// batchIDS generates intrusion detection datapoints for InfluxDB. // These points can be passed directly to influx. -func IDSPoints(i *unifi.IDS) ([]*influx.Point, error) { +func (u *InfluxUnifi) batchIDS(r report, i *unifi.IDS) { tags := map[string]string{ "in_iface": i.InIface, "event_type": i.EventType, @@ -36,9 +35,5 @@ func IDSPoints(i *unifi.IDS) ([]*influx.Point, error) { "srcipASN": i.SrcipASN, "usgipASN": i.UsgipASN, } - pt, err := influx.NewPoint("intrusion_detect", tags, fields, i.Datetime) - if err != nil { - return nil, err - } - return []*influx.Point{pt}, nil + r.send(&metric{Table: "intrusion_detect", Tags: tags, Fields: fields}) } diff --git a/pkg/influxunifi/metrics.go b/pkg/influxunifi/metrics.go index f4a8c86b..af8bd274 100644 --- a/pkg/influxunifi/metrics.go +++ b/pkg/influxunifi/metrics.go @@ -3,67 +3,141 @@ package influxunifi import ( + "crypto/tls" + "fmt" + "time" + "github.com/davidnewhall/unifi-poller/pkg/metrics" - client "github.com/influxdata/influxdb1-client/v2" + _ "github.com/influxdata/influxdb1-client" + influx "github.com/influxdata/influxdb1-client/v2" ) -// Metrics contains all the data from the controller and an influx endpoint to send it to. -type Metrics struct { - *metrics.Metrics - client.BatchPoints +// Config defines the data needed to store metrics in InfluxDB +type Config struct { + Database string + URL string + User string + Pass string + BadSSL bool } -// ProcessPoints batches all device and client data into influxdb data points. +// InfluxUnifi is returned by New() after you provide a Config. +type InfluxUnifi struct { + cf *Config + influx influx.Client +} + +type metric struct { + Table string + Tags map[string]string + Fields map[string]interface{} +} + +// New returns an InfluxDB interface. +func New(c *Config) (*InfluxUnifi, error) { + i, err := influx.NewHTTPClient(influx.HTTPConfig{ + Addr: c.URL, + Username: c.User, + Password: c.Pass, + TLSConfig: &tls.Config{InsecureSkipVerify: c.BadSSL}, + }) + return &InfluxUnifi{cf: c, influx: i}, err +} + +// ReportMetrics batches all device and client data into influxdb data points. // Call this after you've collected all the data you care about. -// This function is sorta weird and returns a slice of errors. The reasoning is -// that some points may process while others fail, so we attempt to process them -// all. This is (usually) run in a loop, so we can't really exit on error, -// we just log the errors and tally them on a counter. In reality, this never -// returns any errors because we control the data going in; cool right? But we -// still check&log it in case the data going is skewed up and causes errors! -func (m *Metrics) ProcessPoints() []error { - errs := []error{} - processPoints := func(m *Metrics, p []*client.Point, err error) { - switch { - case err != nil: - errs = append(errs, err) - case p == nil: - default: - m.AddPoints(p) - } +// Returns an error if influxdb calls fail, otherwise returns a report. +func (u *InfluxUnifi) ReportMetrics(m *metrics.Metrics) (*Report, error) { + r := &Report{Metrics: m, ch: make(chan *metric), Start: time.Now()} + defer close(r.ch) + // Make a new Influx Points Batcher. + var err error + r.bp, err = influx.NewBatchPoints(influx.BatchPointsConfig{Database: u.cf.Database}) + if err != nil { + return nil, fmt.Errorf("influx.NewBatchPoints: %v", err) } - for _, asset := range m.Sites { - pts, err := SitePoints(asset, m.TS) - processPoints(m, pts, err) - } - for _, asset := range m.Clients { - pts, err := ClientPoints(asset, m.TS) - processPoints(m, pts, err) - } - for _, asset := range m.IDSList { - pts, err := IDSPoints(asset) // no m.TS. - processPoints(m, pts, err) - } + go u.collect(r, r.ch) + // Batch all the points. + u.loopPoints(r) - if m.Devices == nil { - return errs + // Send all the points. + if err = u.influx.Write(r.bp); err != nil { + return nil, fmt.Errorf("influxdb.Write(points): %v", err) } - for _, asset := range m.Devices.UAPs { - pts, err := UAPPoints(asset, m.TS) - processPoints(m, pts, err) - } - for _, asset := range m.Devices.USGs { - pts, err := USGPoints(asset, m.TS) - processPoints(m, pts, err) - } - for _, asset := range m.Devices.USWs { - pts, err := USWPoints(asset, m.TS) - processPoints(m, pts, err) - } - for _, asset := range m.Devices.UDMs { - pts, err := UDMPoints(asset, m.TS) - processPoints(m, pts, err) - } - return errs + r.Elapsed = time.Since(r.Start) + return r, nil +} + +// collect runs in a go routine and batches all the points. +func (u *InfluxUnifi) collect(r report, ch chan *metric) { + for m := range ch { + pt, err := influx.NewPoint(m.Table, m.Tags, m.Fields, r.metrics().TS) + if err != nil { + r.error(err) + } else { + r.batch(m, pt) + } + r.done() + } +} + +// loopPoints kicks off 3 or 7 go routines to process metrics and send them +// to the collect routine through the metric channel. +func (u *InfluxUnifi) loopPoints(r report) { + m := r.metrics() + r.add() + go func() { + defer r.done() + for _, s := range m.Sites { + u.batchSite(r, s) + } + }() + r.add() + go func() { + defer r.done() + for _, s := range m.Clients { + u.batchClient(r, s) + } + }() + r.add() + go func() { + defer r.done() + for _, s := range m.IDSList { + u.batchIDS(r, s) + } + }() + if m.Devices == nil { + return + } + + r.add() + go func() { + defer r.done() + for _, s := range m.UAPs { + u.batchUAP(r, s) + } + }() + r.add() + go func() { + defer r.done() + for _, s := range m.USGs { + u.batchUSG(r, s) + } + }() + r.add() + go func() { + defer r.done() + for _, s := range m.USWs { + u.batchUSW(r, s) + } + }() + r.add() + go func() { + defer r.done() + for _, s := range m.UDMs { + u.batchUDM(r, s) + } + }() + r.wait() } diff --git a/pkg/influxunifi/report.go b/pkg/influxunifi/report.go new file mode 100644 index 00000000..42211c26 --- /dev/null +++ b/pkg/influxunifi/report.go @@ -0,0 +1,69 @@ +package influxunifi + +import ( + "sync" + "time" + + "github.com/davidnewhall/unifi-poller/pkg/metrics" + influx "github.com/influxdata/influxdb1-client/v2" +) + +// Report is returned to the calling procedure after everything is processed. +type Report struct { + Metrics *metrics.Metrics + Errors []error + Total int + Fields int + Start time.Time + Elapsed time.Duration + ch chan *metric + wg sync.WaitGroup + bp influx.BatchPoints +} + +// satisfy gomnd +const one = 1 + +// report is an internal interface that can be mocked and overrridden for tests. +type report interface { + add() + done() + wait() + send(m *metric) + error(err error) + batch(m *metric, pt *influx.Point) + metrics() *metrics.Metrics +} + +func (r *Report) metrics() *metrics.Metrics { + return r.Metrics +} + +func (r *Report) add() { + r.wg.Add(one) +} + +func (r *Report) done() { + r.wg.Add(-one) +} + +func (r *Report) send(m *metric) { + r.wg.Add(one) + r.ch <- m +} + +func (r *Report) wait() { + r.wg.Wait() +} + +/* The following methods are not thread safe. */ + +func (r *Report) error(err error) { + r.Errors = append(r.Errors, err) +} + +func (r *Report) batch(m *metric, p *influx.Point) { + r.Total++ + r.Fields += len(m.Fields) + r.bp.AddPoint(p) +} diff --git a/pkg/influxunifi/site.go b/pkg/influxunifi/site.go index dbfdac38..243d2acc 100644 --- a/pkg/influxunifi/site.go +++ b/pkg/influxunifi/site.go @@ -1,67 +1,56 @@ package influxunifi import ( - "time" - - influx "github.com/influxdata/influxdb1-client/v2" "golift.io/unifi" ) -// SitePoints generates Unifi Sites' datapoints for InfluxDB. +// batchSite generates Unifi Sites' datapoints for InfluxDB. // These points can be passed directly to influx. -func SitePoints(u *unifi.Site, now time.Time) ([]*influx.Point, error) { - points := []*influx.Point{} - for _, s := range u.Health { +func (u *InfluxUnifi) batchSite(r report, s *unifi.Site) { + for _, h := range s.Health { tags := map[string]string{ - "name": u.Name, - "site_name": u.SiteName, - "desc": u.Desc, - "status": s.Status, - "subsystem": s.Subsystem, - "wan_ip": s.WanIP, - "netmask": s.Netmask, - "gw_name": s.GwName, - "gw_mac": s.GwMac, - "lan_ip": s.LanIP, + "name": s.Name, + "site_name": s.SiteName, + "desc": s.Desc, + "status": h.Status, + "subsystem": h.Subsystem, + "wan_ip": h.WanIP, + "gw_name": h.GwName, + "lan_ip": h.LanIP, } fields := map[string]interface{}{ - "num_user": s.NumUser.Val, - "num_guest": s.NumGuest.Val, - "num_iot": s.NumIot.Val, - "tx_bytes-r": s.TxBytesR.Val, - "rx_bytes-r": s.RxBytesR.Val, - "num_ap": s.NumAp.Val, - "num_adopted": s.NumAdopted.Val, - "num_disabled": s.NumDisabled.Val, - "num_disconnected": s.NumDisconnected.Val, - "num_pending": s.NumPending.Val, - "num_gw": s.NumGw.Val, - "wan_ip": s.WanIP, - "num_sta": s.NumSta.Val, - "gw_cpu": s.GwSystemStats.CPU.Val, - "gw_mem": s.GwSystemStats.Mem.Val, - "gw_uptime": s.GwSystemStats.Uptime.Val, - "latency": s.Latency.Val, - "uptime": s.Uptime.Val, - "drops": s.Drops.Val, - "xput_up": s.XputUp.Val, - "xput_down": s.XputDown.Val, - "speedtest_ping": s.SpeedtestPing.Val, - "speedtest_lastrun": s.SpeedtestLastrun.Val, - "num_sw": s.NumSw.Val, - "remote_user_num_active": s.RemoteUserNumActive.Val, - "remote_user_num_inactive": s.RemoteUserNumInactive.Val, - "remote_user_rx_bytes": s.RemoteUserRxBytes.Val, - "remote_user_tx_bytes": s.RemoteUserTxBytes.Val, - "remote_user_rx_packets": s.RemoteUserRxPackets.Val, - "remote_user_tx_packets": s.RemoteUserTxPackets.Val, - "num_new_alarms": u.NumNewAlarms.Val, + "num_user": h.NumUser.Val, + "num_guest": h.NumGuest.Val, + "num_iot": h.NumIot.Val, + "tx_bytes-r": h.TxBytesR.Val, + "rx_bytes-r": h.RxBytesR.Val, + "num_ap": h.NumAp.Val, + "num_adopted": h.NumAdopted.Val, + "num_disabled": h.NumDisabled.Val, + "num_disconnected": h.NumDisconnected.Val, + "num_pending": h.NumPending.Val, + "num_gw": h.NumGw.Val, + "wan_ip": h.WanIP, + "num_sta": h.NumSta.Val, + "gw_cpu": h.GwSystemStats.CPU.Val, + "gw_mem": h.GwSystemStats.Mem.Val, + "gw_uptime": h.GwSystemStats.Uptime.Val, + "latency": h.Latency.Val, + "uptime": h.Uptime.Val, + "drops": h.Drops.Val, + "xput_up": h.XputUp.Val, + "xput_down": h.XputDown.Val, + "speedtest_ping": h.SpeedtestPing.Val, + "speedtest_lastrun": h.SpeedtestLastrun.Val, + "num_sw": h.NumSw.Val, + "remote_user_num_active": h.RemoteUserNumActive.Val, + "remote_user_num_inactive": h.RemoteUserNumInactive.Val, + "remote_user_rx_bytes": h.RemoteUserRxBytes.Val, + "remote_user_tx_bytes": h.RemoteUserTxBytes.Val, + "remote_user_rx_packets": h.RemoteUserRxPackets.Val, + "remote_user_tx_packets": h.RemoteUserTxPackets.Val, + "num_new_alarms": s.NumNewAlarms.Val, } - pt, err := influx.NewPoint("subsystems", tags, fields, time.Now()) - if err != nil { - return points, err - } - points = append(points, pt) + r.send(&metric{Table: "subsystems", Tags: tags, Fields: fields}) } - return points, nil } diff --git a/pkg/influxunifi/uap.go b/pkg/influxunifi/uap.go index 423c00cb..fd1a1f96 100644 --- a/pkg/influxunifi/uap.go +++ b/pkg/influxunifi/uap.go @@ -1,103 +1,89 @@ package influxunifi import ( - "time" - - influx "github.com/influxdata/influxdb1-client/v2" "golift.io/unifi" ) -// UAPPoints generates Wireless-Access-Point datapoints for InfluxDB. +// batchUAP generates Wireless-Access-Point datapoints for InfluxDB. // These points can be passed directly to influx. -func UAPPoints(u *unifi.UAP, now time.Time) ([]*influx.Point, error) { - if u.Stat.Ap == nil { - u.Stat.Ap = &unifi.Ap{} +func (u *InfluxUnifi) batchUAP(r report, s *unifi.UAP) { + if s.Stat.Ap == nil { + s.Stat.Ap = &unifi.Ap{} } tags := map[string]string{ - "ip": u.IP, - "mac": u.Mac, - "site_id": u.SiteID, - "site_name": u.SiteName, - "name": u.Name, - "cfgversion": u.Cfgversion, - "model": u.Model, - "serial": u.Serial, - "type": u.Type, + "mac": s.Mac, + "site_name": s.SiteName, + "name": s.Name, + "version": s.Version, + "model": s.Model, + "serial": s.Serial, + "type": s.Type, } fields := map[string]interface{}{ - "ip": u.IP, - "bytes": u.Bytes.Val, - "last_seen": u.LastSeen.Val, - "rx_bytes": u.RxBytes.Val, - "tx_bytes": u.TxBytes.Val, - "uptime": u.Uptime.Val, - "state": u.State, - "user-num_sta": int(u.UserNumSta.Val), - "guest-num_sta": int(u.GuestNumSta.Val), - "num_sta": u.NumSta.Val, - "loadavg_1": u.SysStats.Loadavg1.Val, - "loadavg_5": u.SysStats.Loadavg5.Val, - "loadavg_15": u.SysStats.Loadavg15.Val, - "mem_buffer": u.SysStats.MemBuffer.Val, - "mem_total": u.SysStats.MemTotal.Val, - "mem_used": u.SysStats.MemUsed.Val, - "cpu": u.SystemStats.CPU.Val, - "mem": u.SystemStats.Mem.Val, - "system_uptime": u.SystemStats.Uptime.Val, + "ip": s.IP, + "bytes": s.Bytes.Val, + "last_seen": s.LastSeen.Val, + "rx_bytes": s.RxBytes.Val, + "tx_bytes": s.TxBytes.Val, + "uptime": s.Uptime.Val, + "state": s.State, + "user-num_sta": int(s.UserNumSta.Val), + "guest-num_sta": int(s.GuestNumSta.Val), + "num_sta": s.NumSta.Val, + "loadavg_1": s.SysStats.Loadavg1.Val, + "loadavg_5": s.SysStats.Loadavg5.Val, + "loadavg_15": s.SysStats.Loadavg15.Val, + "mem_buffer": s.SysStats.MemBuffer.Val, + "mem_total": s.SysStats.MemTotal.Val, + "mem_used": s.SysStats.MemUsed.Val, + "cpu": s.SystemStats.CPU.Val, + "mem": s.SystemStats.Mem.Val, + "system_uptime": s.SystemStats.Uptime.Val, // Accumulative Statistics. - "stat_user-rx_packets": u.Stat.Ap.UserRxPackets.Val, - "stat_guest-rx_packets": u.Stat.Ap.GuestRxPackets.Val, - "stat_rx_packets": u.Stat.Ap.RxPackets.Val, - "stat_user-rx_bytes": u.Stat.Ap.UserRxBytes.Val, - "stat_guest-rx_bytes": u.Stat.Ap.GuestRxBytes.Val, - "stat_rx_bytes": u.Stat.Ap.RxBytes.Val, - "stat_user-rx_errors": u.Stat.Ap.UserRxErrors.Val, - "stat_guest-rx_errors": u.Stat.Ap.GuestRxErrors.Val, - "stat_rx_errors": u.Stat.Ap.RxErrors.Val, - "stat_user-rx_dropped": u.Stat.Ap.UserRxDropped.Val, - "stat_guest-rx_dropped": u.Stat.Ap.GuestRxDropped.Val, - "stat_rx_dropped": u.Stat.Ap.RxDropped.Val, - "stat_user-rx_crypts": u.Stat.Ap.UserRxCrypts.Val, - "stat_guest-rx_crypts": u.Stat.Ap.GuestRxCrypts.Val, - "stat_rx_crypts": u.Stat.Ap.RxCrypts.Val, - "stat_user-rx_frags": u.Stat.Ap.UserRxFrags.Val, - "stat_guest-rx_frags": u.Stat.Ap.GuestRxFrags.Val, - "stat_rx_frags": u.Stat.Ap.RxFrags.Val, - "stat_user-tx_packets": u.Stat.Ap.UserTxPackets.Val, - "stat_guest-tx_packets": u.Stat.Ap.GuestTxPackets.Val, - "stat_tx_packets": u.Stat.Ap.TxPackets.Val, - "stat_user-tx_bytes": u.Stat.Ap.UserTxBytes.Val, - "stat_guest-tx_bytes": u.Stat.Ap.GuestTxBytes.Val, - "stat_tx_bytes": u.Stat.Ap.TxBytes.Val, - "stat_user-tx_errors": u.Stat.Ap.UserTxErrors.Val, - "stat_guest-tx_errors": u.Stat.Ap.GuestTxErrors.Val, - "stat_tx_errors": u.Stat.Ap.TxErrors.Val, - "stat_user-tx_dropped": u.Stat.Ap.UserTxDropped.Val, - "stat_guest-tx_dropped": u.Stat.Ap.GuestTxDropped.Val, - "stat_tx_dropped": u.Stat.Ap.TxDropped.Val, - "stat_user-tx_retries": u.Stat.Ap.UserTxRetries.Val, - "stat_guest-tx_retries": u.Stat.Ap.GuestTxRetries.Val, + "stat_user-rx_packets": s.Stat.Ap.UserRxPackets.Val, + "stat_guest-rx_packets": s.Stat.Ap.GuestRxPackets.Val, + "stat_rx_packets": s.Stat.Ap.RxPackets.Val, + "stat_user-rx_bytes": s.Stat.Ap.UserRxBytes.Val, + "stat_guest-rx_bytes": s.Stat.Ap.GuestRxBytes.Val, + "stat_rx_bytes": s.Stat.Ap.RxBytes.Val, + "stat_user-rx_errors": s.Stat.Ap.UserRxErrors.Val, + "stat_guest-rx_errors": s.Stat.Ap.GuestRxErrors.Val, + "stat_rx_errors": s.Stat.Ap.RxErrors.Val, + "stat_user-rx_dropped": s.Stat.Ap.UserRxDropped.Val, + "stat_guest-rx_dropped": s.Stat.Ap.GuestRxDropped.Val, + "stat_rx_dropped": s.Stat.Ap.RxDropped.Val, + "stat_user-rx_crypts": s.Stat.Ap.UserRxCrypts.Val, + "stat_guest-rx_crypts": s.Stat.Ap.GuestRxCrypts.Val, + "stat_rx_crypts": s.Stat.Ap.RxCrypts.Val, + "stat_user-rx_frags": s.Stat.Ap.UserRxFrags.Val, + "stat_guest-rx_frags": s.Stat.Ap.GuestRxFrags.Val, + "stat_rx_frags": s.Stat.Ap.RxFrags.Val, + "stat_user-tx_packets": s.Stat.Ap.UserTxPackets.Val, + "stat_guest-tx_packets": s.Stat.Ap.GuestTxPackets.Val, + "stat_tx_packets": s.Stat.Ap.TxPackets.Val, + "stat_user-tx_bytes": s.Stat.Ap.UserTxBytes.Val, + "stat_guest-tx_bytes": s.Stat.Ap.GuestTxBytes.Val, + "stat_tx_bytes": s.Stat.Ap.TxBytes.Val, + "stat_user-tx_errors": s.Stat.Ap.UserTxErrors.Val, + "stat_guest-tx_errors": s.Stat.Ap.GuestTxErrors.Val, + "stat_tx_errors": s.Stat.Ap.TxErrors.Val, + "stat_user-tx_dropped": s.Stat.Ap.UserTxDropped.Val, + "stat_guest-tx_dropped": s.Stat.Ap.GuestTxDropped.Val, + "stat_tx_dropped": s.Stat.Ap.TxDropped.Val, + "stat_user-tx_retries": s.Stat.Ap.UserTxRetries.Val, + "stat_guest-tx_retries": s.Stat.Ap.GuestTxRetries.Val, } - pt, err := influx.NewPoint("uap", tags, fields, now) - if err != nil { - return nil, err - } - morePoints, err := processVAPs(u.VapTable, u.RadioTable, u.RadioTableStats, u.Name, u.Mac, u.SiteName, now) - if err != nil { - return nil, err - } - return append(morePoints, pt), nil + r.send(&metric{Table: "uap", Tags: tags, Fields: fields}) + u.processVAPs(r, s.VapTable, s.RadioTable, s.RadioTableStats, s.Name, s.Mac, s.SiteName) } // processVAPs creates points for Wifi Radios. This works with several types of UAP-capable devices. -func processVAPs(vt unifi.VapTable, rt unifi.RadioTable, rts unifi.RadioTableStats, name, mac, sitename string, ts time.Time) ([]*influx.Point, error) { - tags := make(map[string]string) - fields := make(map[string]interface{}) - points := []*influx.Point{} - +func (u *InfluxUnifi) processVAPs(r report, vt unifi.VapTable, rt unifi.RadioTable, rts unifi.RadioTableStats, name, mac, sitename string) { // Loop each virtual AP (ESSID) and extract data for it // from radio_tables and radio_table_stats. for _, s := range vt { + tags := make(map[string]string) + fields := make(map[string]interface{}) tags["device_name"] = name tags["device_mac"] = mac tags["site_name"] = sitename @@ -113,7 +99,6 @@ func processVAPs(vt unifi.VapTable, rt unifi.RadioTable, rts unifi.RadioTableSta tags["is_guest"] = s.IsGuest.Txt fields["ccq"] = s.Ccq - fields["extchannel"] = s.Extchannel fields["mac_filter_rejections"] = s.MacFilterRejections fields["num_satisfaction_sta"] = s.NumSatisfactionSta.Val fields["avg_client_signal"] = s.AvgClientSignal.Val @@ -185,12 +170,6 @@ func processVAPs(vt unifi.VapTable, rt unifi.RadioTable, rts unifi.RadioTableSta fields["tx_retries"] = p.TxRetries.Val fields["user-num_sta"] = p.UserNumSta.Val } - - pt, err := influx.NewPoint("uap_vaps", tags, fields, ts) - if err != nil { - return points, err - } - points = append(points, pt) + r.send(&metric{Table: "uap_vaps", Tags: tags, Fields: fields}) } - return points, nil } diff --git a/pkg/influxunifi/udm.go b/pkg/influxunifi/udm.go index f679c922..4b01deb0 100644 --- a/pkg/influxunifi/udm.go +++ b/pkg/influxunifi/udm.go @@ -1,200 +1,163 @@ package influxunifi import ( - "time" - - influx "github.com/influxdata/influxdb1-client/v2" "golift.io/unifi" ) -// UDMPoints generates Unifi Gateway datapoints for InfluxDB. +// batchUDM generates Unifi Gateway datapoints for InfluxDB. // These points can be passed directly to influx. -func UDMPoints(u *unifi.UDM, now time.Time) ([]*influx.Point, error) { - if u.Stat.Sw == nil { - u.Stat.Sw = &unifi.Sw{} +func (u *InfluxUnifi) batchUDM(r report, s *unifi.UDM) { + if s.Stat.Sw == nil { + s.Stat.Sw = &unifi.Sw{} } - if u.Stat.Gw == nil { - u.Stat.Gw = &unifi.Gw{} + if s.Stat.Gw == nil { + s.Stat.Gw = &unifi.Gw{} } tags := map[string]string{ - "ip": u.IP, - "mac": u.Mac, - "site_id": u.SiteID, - "site_name": u.SiteName, - "name": u.Name, - "cfgversion": u.Cfgversion, - "model": u.Model, - "serial": u.Serial, - "type": u.Type, + "mac": s.Mac, + "site_name": s.SiteName, + "name": s.Name, + "version": s.Version, + "model": s.Model, + "serial": s.Serial, + "type": s.Type, } fields := map[string]interface{}{ - "ip": u.IP, - "bytes": u.Bytes.Val, - "last_seen": u.LastSeen.Val, - "license_state": u.LicenseState, - "fw_caps": u.FwCaps.Val, - "guest-num_sta": u.GuestNumSta.Val, - "rx_bytes": u.RxBytes.Val, - "tx_bytes": u.TxBytes.Val, - "uptime": u.Uptime.Val, - "state": u.State.Val, - "user-num_sta": u.UserNumSta.Val, - "num_sta": u.NumSta.Val, - "version": u.Version, - "num_desktop": u.NumDesktop.Val, - "num_handheld": u.NumHandheld.Val, - "num_mobile": u.NumMobile.Val, - "speedtest-status_latency": u.SpeedtestStatus.Latency.Val, - "speedtest-status_rundate": u.SpeedtestStatus.Rundate.Val, - "speedtest-status_runtime": u.SpeedtestStatus.Runtime.Val, - "speedtest-status_download": u.SpeedtestStatus.StatusDownload.Val, - "speedtest-status_ping": u.SpeedtestStatus.StatusPing.Val, - "speedtest-status_summary": u.SpeedtestStatus.StatusSummary.Val, - "speedtest-status_upload": u.SpeedtestStatus.StatusUpload.Val, - "speedtest-status_xput_download": u.SpeedtestStatus.XputDownload.Val, - "speedtest-status_xput_upload": u.SpeedtestStatus.XputUpload.Val, - "config_network_wan_type": u.ConfigNetwork.Type, - "wan1_bytes-r": u.Wan1.BytesR.Val, - "wan1_enable": u.Wan1.Enable.Val, - "wan1_full_duplex": u.Wan1.FullDuplex.Val, - "wan1_gateway": u.Wan1.Gateway, - "wan1_ifname": u.Wan1.Ifname, - "wan1_ip": u.Wan1.IP, - "wan1_mac": u.Wan1.Mac, - "wan1_max_speed": u.Wan1.MaxSpeed.Val, - "wan1_name": u.Wan1.Name, - "wan1_netmask": u.Wan1.Netmask, - "wan1_rx_bytes": u.Wan1.RxBytes.Val, - "wan1_rx_bytes-r": u.Wan1.RxBytesR.Val, - "wan1_rx_dropped": u.Wan1.RxDropped.Val, - "wan1_rx_errors": u.Wan1.RxErrors.Val, - "wan1_rx_multicast": u.Wan1.RxMulticast.Val, - "wan1_rx_packets": u.Wan1.RxPackets.Val, - "wan1_type": u.Wan1.Type, - "wan1_speed": u.Wan1.Speed.Val, - "wan1_up": u.Wan1.Up.Val, - "wan1_tx_bytes": u.Wan1.TxBytes.Val, - "wan1_tx_bytes-r": u.Wan1.TxBytesR.Val, - "wan1_tx_dropped": u.Wan1.TxDropped.Val, - "wan1_tx_errors": u.Wan1.TxErrors.Val, - "wan1_tx_packets": u.Wan1.TxPackets.Val, - "wan2_bytes-r": u.Wan2.BytesR.Val, - "wan2_enable": u.Wan2.Enable.Val, - "wan2_full_duplex": u.Wan2.FullDuplex.Val, - "wan2_gateway": u.Wan2.Gateway, - "wan2_ifname": u.Wan2.Ifname, - "wan2_ip": u.Wan2.IP, - "wan2_mac": u.Wan2.Mac, - "wan2_max_speed": u.Wan2.MaxSpeed.Val, - "wan2_name": u.Wan2.Name, - "wan2_netmask": u.Wan2.Netmask, - "wan2_rx_bytes": u.Wan2.RxBytes.Val, - "wan2_rx_bytes-r": u.Wan2.RxBytesR.Val, - "wan2_rx_dropped": u.Wan2.RxDropped.Val, - "wan2_rx_errors": u.Wan2.RxErrors.Val, - "wan2_rx_multicast": u.Wan2.RxMulticast.Val, - "wan2_rx_packets": u.Wan2.RxPackets.Val, - "wan2_type": u.Wan2.Type, - "wan2_speed": u.Wan2.Speed.Val, - "wan2_up": u.Wan2.Up.Val, - "wan2_tx_bytes": u.Wan2.TxBytes.Val, - "wan2_tx_bytes-r": u.Wan2.TxBytesR.Val, - "wan2_tx_dropped": u.Wan2.TxDropped.Val, - "wan2_tx_errors": u.Wan2.TxErrors.Val, - "wan2_tx_packets": u.Wan2.TxPackets.Val, - "loadavg_1": u.SysStats.Loadavg1.Val, - "loadavg_5": u.SysStats.Loadavg5.Val, - "loadavg_15": u.SysStats.Loadavg15.Val, - "mem_used": u.SysStats.MemUsed.Val, - "mem_buffer": u.SysStats.MemBuffer.Val, - "mem_total": u.SysStats.MemTotal.Val, - "cpu": u.SystemStats.CPU.Val, - "mem": u.SystemStats.Mem.Val, - "system_uptime": u.SystemStats.Uptime.Val, - "gw": u.Stat.Gw, - "lan-rx_bytes": u.Stat.LanRxBytes.Val, - "lan-rx_packets": u.Stat.LanRxPackets.Val, - "lan-tx_bytes": u.Stat.LanTxBytes.Val, - "lan-tx_packets": u.Stat.LanTxPackets.Val, - "wan-rx_bytes": u.Stat.WanRxBytes.Val, - "wan-rx_dropped": u.Stat.WanRxDropped.Val, - "wan-rx_packets": u.Stat.WanRxPackets.Val, - "wan-tx_bytes": u.Stat.WanTxBytes.Val, - "wan-tx_packets": u.Stat.WanTxPackets.Val, - "uplink_name": u.Uplink.Name, - "uplink_latency": u.Uplink.Latency.Val, - "uplink_speed": u.Uplink.Speed.Val, - "uplink_num_ports": u.Uplink.NumPort.Val, - "uplink_max_speed": u.Uplink.MaxSpeed.Val, + "ip": s.IP, + "bytes": s.Bytes.Val, + "last_seen": s.LastSeen.Val, + "license_state": s.LicenseState, + "guest-num_sta": s.GuestNumSta.Val, + "rx_bytes": s.RxBytes.Val, + "tx_bytes": s.TxBytes.Val, + "uptime": s.Uptime.Val, + "state": s.State.Val, + "user-num_sta": s.UserNumSta.Val, + "version": s.Version, + "num_desktop": s.NumDesktop.Val, + "num_handheld": s.NumHandheld.Val, + "num_mobile": s.NumMobile.Val, + "speedtest-status_latency": s.SpeedtestStatus.Latency.Val, + "speedtest-status_runtime": s.SpeedtestStatus.Runtime.Val, + "speedtest-status_ping": s.SpeedtestStatus.StatusPing.Val, + "speedtest-status_xput_download": s.SpeedtestStatus.XputDownload.Val, + "speedtest-status_xput_upload": s.SpeedtestStatus.XputUpload.Val, + "wan1_bytes-r": s.Wan1.BytesR.Val, + "wan1_enable": s.Wan1.Enable.Val, + "wan1_full_duplex": s.Wan1.FullDuplex.Val, + "wan1_gateway": s.Wan1.Gateway, + "wan1_ifname": s.Wan1.Ifname, + "wan1_ip": s.Wan1.IP, + "wan1_mac": s.Wan1.Mac, + "wan1_max_speed": s.Wan1.MaxSpeed.Val, + "wan1_name": s.Wan1.Name, + "wan1_rx_bytes": s.Wan1.RxBytes.Val, + "wan1_rx_bytes-r": s.Wan1.RxBytesR.Val, + "wan1_rx_dropped": s.Wan1.RxDropped.Val, + "wan1_rx_errors": s.Wan1.RxErrors.Val, + "wan1_rx_multicast": s.Wan1.RxMulticast.Val, + "wan1_rx_packets": s.Wan1.RxPackets.Val, + "wan1_type": s.Wan1.Type, + "wan1_speed": s.Wan1.Speed.Val, + "wan1_up": s.Wan1.Up.Val, + "wan1_tx_bytes": s.Wan1.TxBytes.Val, + "wan1_tx_bytes-r": s.Wan1.TxBytesR.Val, + "wan1_tx_dropped": s.Wan1.TxDropped.Val, + "wan1_tx_errors": s.Wan1.TxErrors.Val, + "wan1_tx_packets": s.Wan1.TxPackets.Val, + "wan2_bytes-r": s.Wan2.BytesR.Val, + "wan2_enable": s.Wan2.Enable.Val, + "wan2_full_duplex": s.Wan2.FullDuplex.Val, + "wan2_gateway": s.Wan2.Gateway, + "wan2_ifname": s.Wan2.Ifname, + "wan2_ip": s.Wan2.IP, + "wan2_mac": s.Wan2.Mac, + "wan2_max_speed": s.Wan2.MaxSpeed.Val, + "wan2_name": s.Wan2.Name, + "wan2_rx_bytes": s.Wan2.RxBytes.Val, + "wan2_rx_bytes-r": s.Wan2.RxBytesR.Val, + "wan2_rx_dropped": s.Wan2.RxDropped.Val, + "wan2_rx_errors": s.Wan2.RxErrors.Val, + "wan2_rx_multicast": s.Wan2.RxMulticast.Val, + "wan2_rx_packets": s.Wan2.RxPackets.Val, + "wan2_type": s.Wan2.Type, + "wan2_speed": s.Wan2.Speed.Val, + "wan2_up": s.Wan2.Up.Val, + "wan2_tx_bytes": s.Wan2.TxBytes.Val, + "wan2_tx_bytes-r": s.Wan2.TxBytesR.Val, + "wan2_tx_dropped": s.Wan2.TxDropped.Val, + "wan2_tx_errors": s.Wan2.TxErrors.Val, + "wan2_tx_packets": s.Wan2.TxPackets.Val, + "loadavg_1": s.SysStats.Loadavg1.Val, + "loadavg_5": s.SysStats.Loadavg5.Val, + "loadavg_15": s.SysStats.Loadavg15.Val, + "mem_used": s.SysStats.MemUsed.Val, + "mem_buffer": s.SysStats.MemBuffer.Val, + "mem_total": s.SysStats.MemTotal.Val, + "cpu": s.SystemStats.CPU.Val, + "mem": s.SystemStats.Mem.Val, + "system_uptime": s.SystemStats.Uptime.Val, + "lan-rx_bytes": s.Stat.LanRxBytes.Val, + "lan-rx_packets": s.Stat.LanRxPackets.Val, + "lan-tx_bytes": s.Stat.LanTxBytes.Val, + "lan-tx_packets": s.Stat.LanTxPackets.Val, + "wan-rx_bytes": s.Stat.WanRxBytes.Val, + "wan-rx_dropped": s.Stat.WanRxDropped.Val, + "wan-rx_packets": s.Stat.WanRxPackets.Val, + "wan-tx_bytes": s.Stat.WanTxBytes.Val, + "wan-tx_packets": s.Stat.WanTxPackets.Val, } - pt, err := influx.NewPoint("usg", tags, fields, now) - if err != nil { - return nil, err - } - points := []*influx.Point{pt} + r.send(&metric{Table: "usg", Tags: tags, Fields: fields}) + tags = map[string]string{ - "ip": u.IP, - "mac": u.Mac, - "site_id": u.SiteID, - "site_name": u.SiteName, - "name": u.Name, - "cfgversion": u.Cfgversion, - "model": u.Model, - "serial": u.Serial, - "type": u.Type, + "mac": s.Mac, + "site_name": s.SiteName, + "name": s.Name, + "version": s.Version, + "model": s.Model, + "serial": s.Serial, + "type": s.Type, } fields = map[string]interface{}{ - "fw_caps": u.FwCaps.Val, - "guest-num_sta": u.GuestLanNumSta.Val, - "ip": u.IP, - "bytes": u.Bytes.Val, - "fan_level": float64(0), - "general_temperature": float64(0), - "last_seen": u.LastSeen.Val, - "license_state": u.LicenseState, - "overheating": u.Overheating.Val, - "rx_bytes": u.RxBytes.Val, - "tx_bytes": u.TxBytes.Val, - "uptime": u.Uptime.Val, - "state": u.State.Val, - "user-num_sta": u.UserLanNumSta.Val, - "num_sta": u.LanNumSta.Val, - "version": u.Version, - "loadavg_1": u.SysStats.Loadavg1.Val, - "loadavg_5": u.SysStats.Loadavg5.Val, - "loadavg_15": u.SysStats.Loadavg15.Val, - "mem_buffer": u.SysStats.MemBuffer.Val, - "mem_used": u.SysStats.MemUsed.Val, - "mem_total": u.SysStats.MemTotal.Val, - "cpu": u.SystemStats.CPU.Val, - "mem": u.SystemStats.Mem.Val, - "system_uptime": u.SystemStats.Uptime.Val, - "stp_priority": u.StpPriority.Val, - "stat_bytes": u.Stat.Sw.Bytes.Val, - "stat_rx_bytes": u.Stat.Sw.RxBytes.Val, - "stat_rx_crypts": u.Stat.Sw.RxCrypts.Val, - "stat_rx_dropped": u.Stat.Sw.RxDropped.Val, - "stat_rx_errors": u.Stat.Sw.RxErrors.Val, - "stat_rx_frags": u.Stat.Sw.RxFrags.Val, - "stat_rx_packets": u.Stat.Sw.TxPackets.Val, - "stat_tx_bytes": u.Stat.Sw.TxBytes.Val, - "stat_tx_dropped": u.Stat.Sw.TxDropped.Val, - "stat_tx_errors": u.Stat.Sw.TxErrors.Val, - "stat_tx_packets": u.Stat.Sw.TxPackets.Val, - "stat_tx_retries": u.Stat.Sw.TxRetries.Val, + "guest-num_sta": s.GuestNumSta.Val, + "ip": s.IP, + "bytes": s.Bytes.Val, + "last_seen": s.LastSeen.Val, + "rx_bytes": s.RxBytes.Val, + "tx_bytes": s.TxBytes.Val, + "uptime": s.Uptime.Val, + "state": s.State.Val, + "user-num_sta": s.UserNumSta.Val, + "loadavg_1": s.SysStats.Loadavg1.Val, + "loadavg_5": s.SysStats.Loadavg5.Val, + "loadavg_15": s.SysStats.Loadavg15.Val, + "mem_buffer": s.SysStats.MemBuffer.Val, + "mem_used": s.SysStats.MemUsed.Val, + "mem_total": s.SysStats.MemTotal.Val, + "cpu": s.SystemStats.CPU.Val, + "mem": s.SystemStats.Mem.Val, + "system_uptime": s.SystemStats.Uptime.Val, + "stat_bytes": s.Stat.Sw.Bytes.Val, + "stat_rx_bytes": s.Stat.Sw.RxBytes.Val, + "stat_rx_crypts": s.Stat.Sw.RxCrypts.Val, + "stat_rx_dropped": s.Stat.Sw.RxDropped.Val, + "stat_rx_errors": s.Stat.Sw.RxErrors.Val, + "stat_rx_frags": s.Stat.Sw.RxFrags.Val, + "stat_rx_packets": s.Stat.Sw.TxPackets.Val, + "stat_tx_bytes": s.Stat.Sw.TxBytes.Val, + "stat_tx_dropped": s.Stat.Sw.TxDropped.Val, + "stat_tx_errors": s.Stat.Sw.TxErrors.Val, + "stat_tx_packets": s.Stat.Sw.TxPackets.Val, + "stat_tx_retries": s.Stat.Sw.TxRetries.Val, } - pt, err = influx.NewPoint("usw", tags, fields, now) - if err != nil { - return nil, err - } - points = append(points, pt) + r.send(&metric{Table: "usw", Tags: tags, Fields: fields}) - for _, p := range u.NetworkTable { + for _, p := range s.NetworkTable { tags := map[string]string{ - "device_name": u.Name, - "device_id": u.ID, - "device_mac": u.Mac, - "site_name": u.SiteName, + "device_name": s.Name, + "device_id": s.ID, + "device_mac": s.Mac, + "site_name": s.SiteName, "up": p.Up.Txt, "enabled": p.Enabled.Txt, "site_id": p.SiteID, @@ -222,25 +185,21 @@ func UDMPoints(u *unifi.UDM, now time.Time) ([]*influx.Point, error) { "ipv6_interface_type": p.Ipv6InterfaceType, "attr_hidden_id": p.AttrHiddenID, } - pt, err = influx.NewPoint("usg_networks", tags, fields, now) - if err != nil { - return points, err - } - points = append(points, pt) + r.send(&metric{Table: "usg_networks", Tags: tags, Fields: fields}) } - for _, p := range u.PortTable { + for _, p := range s.PortTable { tags := map[string]string{ - "site_id": u.SiteID, - "site_name": u.SiteName, - "device_name": u.Name, + "site_id": s.SiteID, + "site_name": s.SiteName, + "device_name": s.Name, "name": p.Name, "enable": p.Enable.Txt, "up": p.Up.Txt, "poe_mode": p.PoeMode, "port_poe": p.PortPoe.Txt, "port_idx": p.PortIdx.Txt, - "port_id": u.Name + " Port " + p.PortIdx.Txt, + "port_id": s.Name + " Port " + p.PortIdx.Txt, "poe_enable": p.PoeEnable.Txt, "flowctrl_rx": p.FlowctrlRx.Txt, "flowctrl_tx": p.FlowctrlTx.Txt, @@ -269,88 +228,75 @@ func UDMPoints(u *unifi.UDM, now time.Time) ([]*influx.Point, error) { "poe_power": p.PoePower.Val, "poe_voltage": p.PoeVoltage.Val, } - pt, err = influx.NewPoint("usw_ports", tags, fields, now) - if err != nil { - return points, err - } - points = append(points, pt) + r.send(&metric{Table: "usw_ports", Tags: tags, Fields: fields}) } - if u.Stat.Ap == nil { - return points, nil + if s.Stat.Ap == nil { + return // we're done now. the following code process UDM (non-pro) UAP data. } tags = map[string]string{ - "ip": u.IP, - "mac": u.Mac, - "site_id": u.SiteID, - "site_name": u.SiteName, - "name": u.Name, - "cfgversion": u.Cfgversion, - "model": u.Model, - "serial": u.Serial, - "type": u.Type, + "mac": s.Mac, + "site_name": s.SiteName, + "name": s.Name, + "version": s.Version, + "model": s.Model, + "serial": s.Serial, + "type": s.Type, } fields = map[string]interface{}{ - "ip": u.IP, - "bytes": u.Bytes.Val, - "last_seen": u.LastSeen.Val, - "rx_bytes": u.RxBytes.Val, - "tx_bytes": u.TxBytes.Val, - "uptime": u.Uptime.Val, - "state": int(u.State.Val), - "user-num_sta": int(u.UserWlanNumSta.Val), - "guest-num_sta": int(u.GuestWlanNumSta.Val), - "num_sta": u.WlanNumSta.Val, - "loadavg_1": u.SysStats.Loadavg1.Val, - "loadavg_5": u.SysStats.Loadavg5.Val, - "loadavg_15": u.SysStats.Loadavg15.Val, - "mem_buffer": u.SysStats.MemBuffer.Val, - "mem_total": u.SysStats.MemTotal.Val, - "mem_used": u.SysStats.MemUsed.Val, - "cpu": u.SystemStats.CPU.Val, - "mem": u.SystemStats.Mem.Val, - "system_uptime": u.SystemStats.Uptime.Val, + "ip": s.IP, + "bytes": s.Bytes.Val, + "last_seen": s.LastSeen.Val, + "rx_bytes": s.RxBytes.Val, + "tx_bytes": s.TxBytes.Val, + "uptime": s.Uptime.Val, + "state": int(s.State.Val), + "user-num_sta": int(s.UserWlanNumSta.Val), + "guest-num_sta": int(s.GuestWlanNumSta.Val), + "num_sta": s.WlanNumSta.Val, + "loadavg_1": s.SysStats.Loadavg1.Val, + "loadavg_5": s.SysStats.Loadavg5.Val, + "loadavg_15": s.SysStats.Loadavg15.Val, + "mem_buffer": s.SysStats.MemBuffer.Val, + "mem_total": s.SysStats.MemTotal.Val, + "mem_used": s.SysStats.MemUsed.Val, + "cpu": s.SystemStats.CPU.Val, + "mem": s.SystemStats.Mem.Val, + "system_uptime": s.SystemStats.Uptime.Val, // Accumulative Statistics. - "stat_user-rx_packets": u.Stat.Ap.UserRxPackets.Val, - "stat_guest-rx_packets": u.Stat.Ap.GuestRxPackets.Val, - "stat_rx_packets": u.Stat.Ap.RxPackets.Val, - "stat_user-rx_bytes": u.Stat.Ap.UserRxBytes.Val, - "stat_guest-rx_bytes": u.Stat.Ap.GuestRxBytes.Val, - "stat_rx_bytes": u.Stat.Ap.RxBytes.Val, - "stat_user-rx_errors": u.Stat.Ap.UserRxErrors.Val, - "stat_guest-rx_errors": u.Stat.Ap.GuestRxErrors.Val, - "stat_rx_errors": u.Stat.Ap.RxErrors.Val, - "stat_user-rx_dropped": u.Stat.Ap.UserRxDropped.Val, - "stat_guest-rx_dropped": u.Stat.Ap.GuestRxDropped.Val, - "stat_rx_dropped": u.Stat.Ap.RxDropped.Val, - "stat_user-rx_crypts": u.Stat.Ap.UserRxCrypts.Val, - "stat_guest-rx_crypts": u.Stat.Ap.GuestRxCrypts.Val, - "stat_rx_crypts": u.Stat.Ap.RxCrypts.Val, - "stat_user-rx_frags": u.Stat.Ap.UserRxFrags.Val, - "stat_guest-rx_frags": u.Stat.Ap.GuestRxFrags.Val, - "stat_rx_frags": u.Stat.Ap.RxFrags.Val, - "stat_user-tx_packets": u.Stat.Ap.UserTxPackets.Val, - "stat_guest-tx_packets": u.Stat.Ap.GuestTxPackets.Val, - "stat_tx_packets": u.Stat.Ap.TxPackets.Val, - "stat_user-tx_bytes": u.Stat.Ap.UserTxBytes.Val, - "stat_guest-tx_bytes": u.Stat.Ap.GuestTxBytes.Val, - "stat_tx_bytes": u.Stat.Ap.TxBytes.Val, - "stat_user-tx_errors": u.Stat.Ap.UserTxErrors.Val, - "stat_guest-tx_errors": u.Stat.Ap.GuestTxErrors.Val, - "stat_tx_errors": u.Stat.Ap.TxErrors.Val, - "stat_user-tx_dropped": u.Stat.Ap.UserTxDropped.Val, - "stat_guest-tx_dropped": u.Stat.Ap.GuestTxDropped.Val, - "stat_tx_dropped": u.Stat.Ap.TxDropped.Val, - "stat_user-tx_retries": u.Stat.Ap.UserTxRetries.Val, - "stat_guest-tx_retries": u.Stat.Ap.GuestTxRetries.Val, + "stat_user-rx_packets": s.Stat.Ap.UserRxPackets.Val, + "stat_guest-rx_packets": s.Stat.Ap.GuestRxPackets.Val, + "stat_rx_packets": s.Stat.Ap.RxPackets.Val, + "stat_user-rx_bytes": s.Stat.Ap.UserRxBytes.Val, + "stat_guest-rx_bytes": s.Stat.Ap.GuestRxBytes.Val, + "stat_rx_bytes": s.Stat.Ap.RxBytes.Val, + "stat_user-rx_errors": s.Stat.Ap.UserRxErrors.Val, + "stat_guest-rx_errors": s.Stat.Ap.GuestRxErrors.Val, + "stat_rx_errors": s.Stat.Ap.RxErrors.Val, + "stat_user-rx_dropped": s.Stat.Ap.UserRxDropped.Val, + "stat_guest-rx_dropped": s.Stat.Ap.GuestRxDropped.Val, + "stat_rx_dropped": s.Stat.Ap.RxDropped.Val, + "stat_user-rx_crypts": s.Stat.Ap.UserRxCrypts.Val, + "stat_guest-rx_crypts": s.Stat.Ap.GuestRxCrypts.Val, + "stat_rx_crypts": s.Stat.Ap.RxCrypts.Val, + "stat_user-rx_frags": s.Stat.Ap.UserRxFrags.Val, + "stat_guest-rx_frags": s.Stat.Ap.GuestRxFrags.Val, + "stat_rx_frags": s.Stat.Ap.RxFrags.Val, + "stat_user-tx_packets": s.Stat.Ap.UserTxPackets.Val, + "stat_guest-tx_packets": s.Stat.Ap.GuestTxPackets.Val, + "stat_tx_packets": s.Stat.Ap.TxPackets.Val, + "stat_user-tx_bytes": s.Stat.Ap.UserTxBytes.Val, + "stat_guest-tx_bytes": s.Stat.Ap.GuestTxBytes.Val, + "stat_tx_bytes": s.Stat.Ap.TxBytes.Val, + "stat_user-tx_errors": s.Stat.Ap.UserTxErrors.Val, + "stat_guest-tx_errors": s.Stat.Ap.GuestTxErrors.Val, + "stat_tx_errors": s.Stat.Ap.TxErrors.Val, + "stat_user-tx_dropped": s.Stat.Ap.UserTxDropped.Val, + "stat_guest-tx_dropped": s.Stat.Ap.GuestTxDropped.Val, + "stat_tx_dropped": s.Stat.Ap.TxDropped.Val, + "stat_user-tx_retries": s.Stat.Ap.UserTxRetries.Val, + "stat_guest-tx_retries": s.Stat.Ap.GuestTxRetries.Val, } - pt, err = influx.NewPoint("uap", tags, fields, now) - if err != nil { - return nil, err - } - uapPoints, err := processVAPs(*u.VapTable, *u.RadioTable, *u.RadioTableStats, u.Name, u.Mac, u.SiteName, now) - if err != nil { - return nil, err - } - return append(append(points, pt), uapPoints...), nil + r.send(&metric{Table: "uap", Tags: tags, Fields: fields}) + u.processVAPs(r, *s.VapTable, *s.RadioTable, *s.RadioTableStats, s.Name, s.Mac, s.SiteName) } diff --git a/pkg/influxunifi/usg.go b/pkg/influxunifi/usg.go index 81ae87dc..07a479d4 100644 --- a/pkg/influxunifi/usg.go +++ b/pkg/influxunifi/usg.go @@ -2,143 +2,118 @@ package influxunifi import ( "strings" - "time" - influx "github.com/influxdata/influxdb1-client/v2" "golift.io/unifi" ) -// USGPoints generates Unifi Gateway datapoints for InfluxDB. +// batchUSG generates Unifi Gateway datapoints for InfluxDB. // These points can be passed directly to influx. -func USGPoints(u *unifi.USG, now time.Time) ([]*influx.Point, error) { - if u.Stat.Gw == nil { - u.Stat.Gw = &unifi.Gw{} +func (u *InfluxUnifi) batchUSG(r report, s *unifi.USG) { + if s.Stat.Gw == nil { + s.Stat.Gw = &unifi.Gw{} } tags := map[string]string{ - "ip": u.IP, - "mac": u.Mac, - "site_id": u.SiteID, - "site_name": u.SiteName, - "name": u.Name, - "cfgversion": u.Cfgversion, - "model": u.Model, - "serial": u.Serial, - "type": u.Type, + "mac": s.Mac, + "site_name": s.SiteName, + "name": s.Name, + "version": s.Version, + "model": s.Model, + "serial": s.Serial, + "type": s.Type, } fields := map[string]interface{}{ - "ip": u.IP, - "bytes": u.Bytes.Val, - "last_seen": u.LastSeen.Val, - "license_state": u.LicenseState, - "fw_caps": u.FwCaps.Val, - "guest-num_sta": u.GuestNumSta.Val, - "rx_bytes": u.RxBytes.Val, - "tx_bytes": u.TxBytes.Val, - "uptime": u.Uptime.Val, - "roll_upgrade": u.Rollupgrade.Val, - "state": u.State.Val, - "upgradable": u.Upgradable.Val, - "user-num_sta": u.UserNumSta.Val, - "version": u.Version, - "num_desktop": u.NumDesktop.Val, - "num_handheld": u.NumHandheld.Val, - "num_mobile": u.NumMobile.Val, - "speedtest-status_latency": u.SpeedtestStatus.Latency.Val, - "speedtest-status_rundate": u.SpeedtestStatus.Rundate.Val, - "speedtest-status_runtime": u.SpeedtestStatus.Runtime.Val, - "speedtest-status_download": u.SpeedtestStatus.StatusDownload.Val, - "speedtest-status_ping": u.SpeedtestStatus.StatusPing.Val, - "speedtest-status_summary": u.SpeedtestStatus.StatusSummary.Val, - "speedtest-status_upload": u.SpeedtestStatus.StatusUpload.Val, - "speedtest-status_xput_download": u.SpeedtestStatus.XputDownload.Val, - "speedtest-status_xput_upload": u.SpeedtestStatus.XputUpload.Val, - "config_network_wan_type": u.ConfigNetwork.Type, - "wan1_bytes-r": u.Wan1.BytesR.Val, - "wan1_enable": u.Wan1.Enable.Val, - "wan1_full_duplex": u.Wan1.FullDuplex.Val, - "wan1_gateway": u.Wan1.Gateway, - "wan1_ifname": u.Wan1.Ifname, - "wan1_ip": u.Wan1.IP, - "wan1_mac": u.Wan1.Mac, - "wan1_max_speed": u.Wan1.MaxSpeed.Val, - "wan1_name": u.Wan1.Name, - "wan1_netmask": u.Wan1.Netmask, - "wan1_rx_bytes": u.Wan1.RxBytes.Val, - "wan1_rx_bytes-r": u.Wan1.RxBytesR.Val, - "wan1_rx_dropped": u.Wan1.RxDropped.Val, - "wan1_rx_errors": u.Wan1.RxErrors.Val, - "wan1_rx_multicast": u.Wan1.RxMulticast.Val, - "wan1_rx_packets": u.Wan1.RxPackets.Val, - "wan1_type": u.Wan1.Type, - "wan1_speed": u.Wan1.Speed.Val, - "wan1_up": u.Wan1.Up.Val, - "wan1_tx_bytes": u.Wan1.TxBytes.Val, - "wan1_tx_bytes-r": u.Wan1.TxBytesR.Val, - "wan1_tx_dropped": u.Wan1.TxDropped.Val, - "wan1_tx_errors": u.Wan1.TxErrors.Val, - "wan1_tx_packets": u.Wan1.TxPackets.Val, - "wan2_bytes-r": u.Wan2.BytesR.Val, - "wan2_enable": u.Wan2.Enable.Val, - "wan2_full_duplex": u.Wan2.FullDuplex.Val, - "wan2_gateway": u.Wan2.Gateway, - "wan2_ifname": u.Wan2.Ifname, - "wan2_ip": u.Wan2.IP, - "wan2_mac": u.Wan2.Mac, - "wan2_max_speed": u.Wan2.MaxSpeed.Val, - "wan2_name": u.Wan2.Name, - "wan2_netmask": u.Wan2.Netmask, - "wan2_rx_bytes": u.Wan2.RxBytes.Val, - "wan2_rx_bytes-r": u.Wan2.RxBytesR.Val, - "wan2_rx_dropped": u.Wan2.RxDropped.Val, - "wan2_rx_errors": u.Wan2.RxErrors.Val, - "wan2_rx_multicast": u.Wan2.RxMulticast.Val, - "wan2_rx_packets": u.Wan2.RxPackets.Val, - "wan2_type": u.Wan2.Type, - "wan2_speed": u.Wan2.Speed.Val, - "wan2_up": u.Wan2.Up.Val, - "wan2_tx_bytes": u.Wan2.TxBytes.Val, - "wan2_tx_bytes-r": u.Wan2.TxBytesR.Val, - "wan2_tx_dropped": u.Wan2.TxDropped.Val, - "wan2_tx_errors": u.Wan2.TxErrors.Val, - "wan2_tx_packets": u.Wan2.TxPackets.Val, - "loadavg_1": u.SysStats.Loadavg1.Val, - "loadavg_5": u.SysStats.Loadavg5.Val, - "loadavg_15": u.SysStats.Loadavg15.Val, - "mem_used": u.SysStats.MemUsed.Val, - "mem_buffer": u.SysStats.MemBuffer.Val, - "mem_total": u.SysStats.MemTotal.Val, - "cpu": u.SystemStats.CPU.Val, - "mem": u.SystemStats.Mem.Val, - "system_uptime": u.SystemStats.Uptime.Val, - "stat_duration": u.Stat.Duration.Val, - "stat_datetime": u.Stat.Datetime, - "gw": u.Stat.Gw, - "lan-rx_bytes": u.Stat.LanRxBytes.Val, - "lan-rx_packets": u.Stat.LanRxPackets.Val, - "lan-tx_bytes": u.Stat.LanTxBytes.Val, - "lan-tx_packets": u.Stat.LanTxPackets.Val, - "wan-rx_bytes": u.Stat.WanRxBytes.Val, - "wan-rx_dropped": u.Stat.WanRxDropped.Val, - "wan-rx_packets": u.Stat.WanRxPackets.Val, - "wan-tx_bytes": u.Stat.WanTxBytes.Val, - "wan-tx_packets": u.Stat.WanTxPackets.Val, - "uplink_name": u.Uplink.Name, - "uplink_latency": u.Uplink.Latency.Val, - "uplink_speed": u.Uplink.Speed.Val, - "uplink_num_ports": u.Uplink.NumPort.Val, - "uplink_max_speed": u.Uplink.MaxSpeed.Val, + "ip": s.IP, + "bytes": s.Bytes.Val, + "last_seen": s.LastSeen.Val, + "license_state": s.LicenseState, + "guest-num_sta": s.GuestNumSta.Val, + "rx_bytes": s.RxBytes.Val, + "tx_bytes": s.TxBytes.Val, + "uptime": s.Uptime.Val, + "state": s.State.Val, + "user-num_sta": s.UserNumSta.Val, + "version": s.Version, + "num_desktop": s.NumDesktop.Val, + "num_handheld": s.NumHandheld.Val, + "num_mobile": s.NumMobile.Val, + "speedtest-status_latency": s.SpeedtestStatus.Latency.Val, + "speedtest-status_runtime": s.SpeedtestStatus.Runtime.Val, + "speedtest-status_ping": s.SpeedtestStatus.StatusPing.Val, + "speedtest-status_xput_download": s.SpeedtestStatus.XputDownload.Val, + "speedtest-status_xput_upload": s.SpeedtestStatus.XputUpload.Val, + "wan1_bytes-r": s.Wan1.BytesR.Val, + "wan1_enable": s.Wan1.Enable.Val, + "wan1_full_duplex": s.Wan1.FullDuplex.Val, + "wan1_gateway": s.Wan1.Gateway, + "wan1_ifname": s.Wan1.Ifname, + "wan1_ip": s.Wan1.IP, + "wan1_mac": s.Wan1.Mac, + "wan1_max_speed": s.Wan1.MaxSpeed.Val, + "wan1_name": s.Wan1.Name, + "wan1_rx_bytes": s.Wan1.RxBytes.Val, + "wan1_rx_bytes-r": s.Wan1.RxBytesR.Val, + "wan1_rx_dropped": s.Wan1.RxDropped.Val, + "wan1_rx_errors": s.Wan1.RxErrors.Val, + "wan1_rx_multicast": s.Wan1.RxMulticast.Val, + "wan1_rx_packets": s.Wan1.RxPackets.Val, + "wan1_type": s.Wan1.Type, + "wan1_speed": s.Wan1.Speed.Val, + "wan1_up": s.Wan1.Up.Val, + "wan1_tx_bytes": s.Wan1.TxBytes.Val, + "wan1_tx_bytes-r": s.Wan1.TxBytesR.Val, + "wan1_tx_dropped": s.Wan1.TxDropped.Val, + "wan1_tx_errors": s.Wan1.TxErrors.Val, + "wan1_tx_packets": s.Wan1.TxPackets.Val, + "wan2_bytes-r": s.Wan2.BytesR.Val, + "wan2_enable": s.Wan2.Enable.Val, + "wan2_full_duplex": s.Wan2.FullDuplex.Val, + "wan2_gateway": s.Wan2.Gateway, + "wan2_ifname": s.Wan2.Ifname, + "wan2_ip": s.Wan2.IP, + "wan2_mac": s.Wan2.Mac, + "wan2_max_speed": s.Wan2.MaxSpeed.Val, + "wan2_name": s.Wan2.Name, + "wan2_rx_bytes": s.Wan2.RxBytes.Val, + "wan2_rx_bytes-r": s.Wan2.RxBytesR.Val, + "wan2_rx_dropped": s.Wan2.RxDropped.Val, + "wan2_rx_errors": s.Wan2.RxErrors.Val, + "wan2_rx_multicast": s.Wan2.RxMulticast.Val, + "wan2_rx_packets": s.Wan2.RxPackets.Val, + "wan2_type": s.Wan2.Type, + "wan2_speed": s.Wan2.Speed.Val, + "wan2_up": s.Wan2.Up.Val, + "wan2_tx_bytes": s.Wan2.TxBytes.Val, + "wan2_tx_bytes-r": s.Wan2.TxBytesR.Val, + "wan2_tx_dropped": s.Wan2.TxDropped.Val, + "wan2_tx_errors": s.Wan2.TxErrors.Val, + "wan2_tx_packets": s.Wan2.TxPackets.Val, + "loadavg_1": s.SysStats.Loadavg1.Val, + "loadavg_5": s.SysStats.Loadavg5.Val, + "loadavg_15": s.SysStats.Loadavg15.Val, + "mem_used": s.SysStats.MemUsed.Val, + "mem_buffer": s.SysStats.MemBuffer.Val, + "mem_total": s.SysStats.MemTotal.Val, + "cpu": s.SystemStats.CPU.Val, + "mem": s.SystemStats.Mem.Val, + "system_uptime": s.SystemStats.Uptime.Val, + "lan-rx_bytes": s.Stat.LanRxBytes.Val, + "lan-rx_packets": s.Stat.LanRxPackets.Val, + "lan-tx_bytes": s.Stat.LanTxBytes.Val, + "lan-tx_packets": s.Stat.LanTxPackets.Val, + "wan-rx_bytes": s.Stat.WanRxBytes.Val, + "wan-rx_dropped": s.Stat.WanRxDropped.Val, + "wan-rx_packets": s.Stat.WanRxPackets.Val, + "wan-tx_bytes": s.Stat.WanTxBytes.Val, + "wan-tx_packets": s.Stat.WanTxPackets.Val, } - pt, err := influx.NewPoint("usg", tags, fields, now) - if err != nil { - return nil, err - } - points := []*influx.Point{pt} - for _, p := range u.NetworkTable { + r.send(&metric{Table: "usg", Tags: tags, Fields: fields}) + + for _, p := range s.NetworkTable { tags := map[string]string{ - "device_name": u.Name, - "device_id": u.ID, - "device_mac": u.Mac, - "site_name": u.SiteName, + "device_name": s.Name, + "device_id": s.ID, + "device_mac": s.Mac, + "site_name": s.SiteName, "up": p.Up.Txt, "enabled": p.Enabled.Txt, "site_id": p.SiteID, @@ -156,18 +131,14 @@ func USGPoints(u *unifi.USG, now time.Time) ([]*influx.Point, error) { "tx_bytes": p.TxBytes.Val, "tx_packets": p.TxPackets.Val, } - pt, err = influx.NewPoint("usg_networks", tags, fields, now) - if err != nil { - return points, err - } - points = append(points, pt) + r.send(&metric{Table: "usg_networks", Tags: tags, Fields: fields}) } - for _, p := range u.PortTable { + for _, p := range s.PortTable { tags := map[string]string{ - "device_name": u.Name, - "device_id": u.ID, - "device_mac": u.Mac, - "site_name": u.SiteName, + "device_name": s.Name, + "device_id": s.ID, + "device_mac": s.Mac, + "site_name": s.SiteName, "name": p.Name, "ifname": p.Ifname, "ip": p.IP, @@ -189,11 +160,7 @@ func USGPoints(u *unifi.USG, now time.Time) ([]*influx.Point, error) { "rx_multicast": p.RxMulticast.Val, "dns_servers": strings.Join(p.DNS, ","), } - pt, err = influx.NewPoint("usg_ports", tags, fields, now) - if err != nil { - return points, err - } - points = append(points, pt) + r.send(&metric{Table: "usg_ports", Tags: tags, Fields: fields}) + } - return points, nil } diff --git a/pkg/influxunifi/usw.go b/pkg/influxunifi/usw.go index 7f392962..60a88853 100644 --- a/pkg/influxunifi/usw.go +++ b/pkg/influxunifi/usw.go @@ -1,91 +1,76 @@ package influxunifi import ( - "time" - - influx "github.com/influxdata/influxdb1-client/v2" "golift.io/unifi" ) -// USWPoints generates Unifi Switch datapoints for InfluxDB. +// batchUSW generates Unifi Switch datapoints for InfluxDB. // These points can be passed directly to influx. -func USWPoints(u *unifi.USW, now time.Time) ([]*influx.Point, error) { - if u.Stat.Sw == nil { - u.Stat.Sw = &unifi.Sw{} +func (u *InfluxUnifi) batchUSW(r report, s *unifi.USW) { + if s.Stat.Sw == nil { + s.Stat.Sw = &unifi.Sw{} } tags := map[string]string{ - "ip": u.IP, - "mac": u.Mac, - "site_id": u.SiteID, - "site_name": u.SiteName, - "name": u.Name, - "cfgversion": u.Cfgversion, - "model": u.Model, - "serial": u.Serial, - "type": u.Type, + "mac": s.Mac, + "site_name": s.SiteName, + "name": s.Name, + "version": s.Version, + "model": s.Model, + "serial": s.Serial, + "type": s.Type, } fields := map[string]interface{}{ - "fw_caps": u.FwCaps.Val, - "guest-num_sta": u.GuestNumSta.Val, - "ip": u.IP, - "bytes": u.Bytes.Val, - "fan_level": u.FanLevel.Val, - "general_temperature": u.GeneralTemperature.Val, - "last_seen": u.LastSeen.Val, - "license_state": u.LicenseState, - "overheating": u.Overheating.Val, - "rx_bytes": u.RxBytes.Val, - "tx_bytes": u.TxBytes.Val, - "uptime": u.Uptime.Val, - "state": u.State.Val, - "user-num_sta": u.UserNumSta.Val, - "version": u.Version, - "loadavg_1": u.SysStats.Loadavg1.Val, - "loadavg_5": u.SysStats.Loadavg5.Val, - "loadavg_15": u.SysStats.Loadavg15.Val, - "mem_buffer": u.SysStats.MemBuffer.Val, - "mem_used": u.SysStats.MemUsed.Val, - "mem_total": u.SysStats.MemTotal.Val, - "cpu": u.SystemStats.CPU.Val, - "mem": u.SystemStats.Mem.Val, - "stp_priority": u.StpPriority.Val, - "system_uptime": u.SystemStats.Uptime.Val, - "stat_bytes": u.Stat.Bytes.Val, - "stat_rx_bytes": u.Stat.RxBytes.Val, - "stat_rx_crypts": u.Stat.RxCrypts.Val, - "stat_rx_dropped": u.Stat.RxDropped.Val, - "stat_rx_errors": u.Stat.RxErrors.Val, - "stat_rx_frags": u.Stat.RxFrags.Val, - "stat_rx_packets": u.Stat.TxPackets.Val, - "stat_tx_bytes": u.Stat.TxBytes.Val, - "stat_tx_dropped": u.Stat.TxDropped.Val, - "stat_tx_errors": u.Stat.TxErrors.Val, - "stat_tx_packets": u.Stat.TxPackets.Val, - "stat_tx_retries": u.Stat.TxRetries.Val, - "uplink_depth": u.UplinkDepth.Txt, + "guest-num_sta": s.GuestNumSta.Val, + "ip": s.IP, + "bytes": s.Bytes.Val, + "fan_level": s.FanLevel.Val, + "general_temperature": s.GeneralTemperature.Val, + "last_seen": s.LastSeen.Val, + "rx_bytes": s.RxBytes.Val, + "tx_bytes": s.TxBytes.Val, + "uptime": s.Uptime.Val, + "state": s.State.Val, + "user-num_sta": s.UserNumSta.Val, + "loadavg_1": s.SysStats.Loadavg1.Val, + "loadavg_5": s.SysStats.Loadavg5.Val, + "loadavg_15": s.SysStats.Loadavg15.Val, + "mem_buffer": s.SysStats.MemBuffer.Val, + "mem_used": s.SysStats.MemUsed.Val, + "mem_total": s.SysStats.MemTotal.Val, + "cpu": s.SystemStats.CPU.Val, + "mem": s.SystemStats.Mem.Val, + "system_uptime": s.SystemStats.Uptime.Val, + "stat_bytes": s.Stat.Sw.Bytes.Val, + "stat_rx_bytes": s.Stat.Sw.RxBytes.Val, + "stat_rx_crypts": s.Stat.Sw.RxCrypts.Val, + "stat_rx_dropped": s.Stat.Sw.RxDropped.Val, + "stat_rx_errors": s.Stat.Sw.RxErrors.Val, + "stat_rx_frags": s.Stat.Sw.RxFrags.Val, + "stat_rx_packets": s.Stat.Sw.TxPackets.Val, + "stat_tx_bytes": s.Stat.Sw.TxBytes.Val, + "stat_tx_dropped": s.Stat.Sw.TxDropped.Val, + "stat_tx_errors": s.Stat.Sw.TxErrors.Val, + "stat_tx_packets": s.Stat.Sw.TxPackets.Val, + "stat_tx_retries": s.Stat.Sw.TxRetries.Val, } - pt, err := influx.NewPoint("usw", tags, fields, now) - if err != nil { - return nil, err - } - points := []*influx.Point{pt} - for _, p := range u.PortTable { + r.send(&metric{Table: "usw", Tags: tags, Fields: fields}) + + for _, p := range s.PortTable { + if !p.Up.Val || !p.Enable.Val { + continue // only record UP ports. + } tags := map[string]string{ - "site_id": u.SiteID, - "site_name": u.SiteName, - "device_name": u.Name, + "site_name": s.SiteName, + "device_name": s.Name, "name": p.Name, - "enable": p.Enable.Txt, - "up": p.Up.Txt, "poe_mode": p.PoeMode, "port_poe": p.PortPoe.Txt, "port_idx": p.PortIdx.Txt, - "port_id": u.Name + " Port " + p.PortIdx.Txt, + "port_id": s.Name + " Port " + p.PortIdx.Txt, "poe_enable": p.PoeEnable.Txt, "flowctrl_rx": p.FlowctrlRx.Txt, "flowctrl_tx": p.FlowctrlTx.Txt, "media": p.Media, - "poe_class": p.PoeClass, } fields := map[string]interface{}{ "dbytes_r": p.BytesR.Val, @@ -105,15 +90,12 @@ func USWPoints(u *unifi.USW, now time.Time) ([]*influx.Point, error) { "tx_errors": p.TxErrors.Val, "tx_multicast": p.TxMulticast.Val, "tx_packets": p.TxPackets.Val, - "poe_current": p.PoeCurrent.Val, - "poe_power": p.PoePower.Val, - "poe_voltage": p.PoeVoltage.Val, } - pt, err = influx.NewPoint("usw_ports", tags, fields, now) - if err != nil { - return points, err + if p.PoeEnable.Val && p.PortPoe.Val { + fields["poe_current"] = p.PoeCurrent.Val + fields["poe_power"] = p.PoePower.Val + fields["poe_voltage"] = p.PoeVoltage.Val } - points = append(points, pt) + r.send(&metric{Table: "usw_ports", Tags: tags, Fields: fields}) } - return points, nil } diff --git a/pkg/poller/config.go b/pkg/poller/config.go index 37ca9a90..2ded5926 100644 --- a/pkg/poller/config.go +++ b/pkg/poller/config.go @@ -13,7 +13,7 @@ import ( "time" "github.com/BurntSushi/toml" - influx "github.com/influxdata/influxdb1-client/v2" + "github.com/davidnewhall/unifi-poller/pkg/influxunifi" "github.com/spf13/pflag" "golift.io/unifi" yaml "gopkg.in/yaml.v2" @@ -41,7 +41,7 @@ const ENVConfigPrefix = "UP_" // UnifiPoller contains the application startup data, and auth info for UniFi & Influx. type UnifiPoller struct { - Influx influx.Client + Influx *influxunifi.InfluxUnifi Unifi *unifi.Unifi Flag *Flag Config *Config diff --git a/pkg/poller/influx.go b/pkg/poller/influx.go index 9b2872d2..6dbc15c3 100644 --- a/pkg/poller/influx.go +++ b/pkg/poller/influx.go @@ -1,21 +1,20 @@ package poller import ( - "crypto/tls" "fmt" + "time" "github.com/davidnewhall/unifi-poller/pkg/influxunifi" - "github.com/davidnewhall/unifi-poller/pkg/metrics" - influx "github.com/influxdata/influxdb1-client/v2" ) // GetInfluxDB returns an InfluxDB interface. func (u *UnifiPoller) GetInfluxDB() (err error) { - u.Influx, err = influx.NewHTTPClient(influx.HTTPConfig{ - Addr: u.Config.InfluxURL, - Username: u.Config.InfluxUser, - Password: u.Config.InfluxPass, - TLSConfig: &tls.Config{InsecureSkipVerify: u.Config.InfxBadSSL}, + u.Influx, err = influxunifi.New(&influxunifi.Config{ + Database: u.Config.InfluxDB, + User: u.Config.InfluxUser, + Pass: u.Config.InfluxPass, + BadSSL: u.Config.InfxBadSSL, + URL: u.Config.InfluxURL, }) if err != nil { return fmt.Errorf("influxdb: %v", err) @@ -35,46 +34,24 @@ func (u *UnifiPoller) CollectAndProcess() error { return err } u.AugmentMetrics(metrics) - err = u.ReportMetrics(metrics) - u.LogError(err, "processing metrics") - return err -} - -// ReportMetrics batches all the metrics and writes them to InfluxDB. -// This creates an InfluxDB writer, and returns an error if the write fails. -func (u *UnifiPoller) ReportMetrics(metrics *metrics.Metrics) error { - // Batch (and send) all the points. - m := &influxunifi.Metrics{Metrics: metrics} - // Make a new Influx Points Batcher. - var err error - m.BatchPoints, err = influx.NewBatchPoints(influx.BatchPointsConfig{Database: u.Config.InfluxDB}) + report, err := u.Influx.ReportMetrics(metrics) if err != nil { - return fmt.Errorf("influx.NewBatchPoints: %v", err) + u.LogError(err, "processing metrics") + return err } - for _, err := range m.ProcessPoints() { - u.LogError(err, "influx.ProcessPoints") - } - if err = u.Influx.Write(m.BatchPoints); err != nil { - return fmt.Errorf("influxdb.Write(points): %v", err) - } - u.LogInfluxReport(m) + u.LogInfluxReport(report) return nil } // LogInfluxReport writes a log message after exporting to influxdb. -func (u *UnifiPoller) LogInfluxReport(m *influxunifi.Metrics) { - var fields, points int - for _, p := range m.Points() { - points++ - i, _ := p.Fields() - fields += len(i) - } +func (u *UnifiPoller) LogInfluxReport(r *influxunifi.Report) { idsMsg := "" if u.Config.SaveIDS { - idsMsg = fmt.Sprintf("IDS Events: %d, ", len(m.IDSList)) + idsMsg = fmt.Sprintf("IDS Events: %d, ", len(r.Metrics.IDSList)) } - u.Logf("UniFi Measurements Recorded. Sites: %d, Clients: %d, "+ - "Wireless APs: %d, Gateways: %d, Switches: %d, %sPoints: %d, Fields: %d", - len(m.Sites), len(m.Clients), len(m.UAPs), - len(m.UDMs)+len(m.USGs), len(m.USWs), idsMsg, points, fields) + u.Logf("UniFi Metrics Recorded. Sites: %d, Clients: %d, "+ + "UAP: %d, USG/UDM: %d, USW: %d, %sPoints: %d, Fields: %d, Errs: %d, Elapsed: %v", + len(r.Metrics.Sites), len(r.Metrics.Clients), len(r.Metrics.UAPs), + len(r.Metrics.UDMs)+len(r.Metrics.USGs), len(r.Metrics.USWs), idsMsg, r.Total, + r.Fields, len(r.Errors), r.Elapsed.Round(time.Millisecond)) } diff --git a/pkg/poller/start.go b/pkg/poller/start.go index 342d4d58..ea68ba0b 100644 --- a/pkg/poller/start.go +++ b/pkg/poller/start.go @@ -21,14 +21,14 @@ func New() *UnifiPoller { InfluxPass: defaultInfluxPass, InfluxDB: defaultInfluxDB, UnifiUser: defaultUnifiUser, - UnifiPass: defaultUnifiUser, + UnifiPass: "", UnifiBase: defaultUnifiURL, Interval: Duration{defaultInterval}, Sites: []string{"all"}, SaveSites: true, HTTPListen: defaultHTTPListen, Namespace: appName, - }, Flag: &Flag{}, + }, Flag: &Flag{ConfigFile: DefaultConfFile}, } } From 36e88dcaf47f4a6e0622c941b032ebb7b8522a78 Mon Sep 17 00:00:00 2001 From: davidnewhall2 Date: Sat, 30 Nov 2019 18:18:49 -0800 Subject: [PATCH 05/10] more reusable code --- pkg/influxunifi/uap.go | 259 ++++++++++++++++++++--------------------- pkg/influxunifi/udm.go | 256 ++++++++-------------------------------- pkg/influxunifi/usg.go | 183 +++++++++++++---------------- pkg/influxunifi/usw.go | 24 ++-- 4 files changed, 263 insertions(+), 459 deletions(-) diff --git a/pkg/influxunifi/uap.go b/pkg/influxunifi/uap.go index fd1a1f96..005ef640 100644 --- a/pkg/influxunifi/uap.go +++ b/pkg/influxunifi/uap.go @@ -19,157 +19,152 @@ func (u *InfluxUnifi) batchUAP(r report, s *unifi.UAP) { "serial": s.Serial, "type": s.Type, } - fields := map[string]interface{}{ - "ip": s.IP, - "bytes": s.Bytes.Val, - "last_seen": s.LastSeen.Val, - "rx_bytes": s.RxBytes.Val, - "tx_bytes": s.TxBytes.Val, - "uptime": s.Uptime.Val, - "state": s.State, - "user-num_sta": int(s.UserNumSta.Val), - "guest-num_sta": int(s.GuestNumSta.Val), - "num_sta": s.NumSta.Val, - "loadavg_1": s.SysStats.Loadavg1.Val, - "loadavg_5": s.SysStats.Loadavg5.Val, - "loadavg_15": s.SysStats.Loadavg15.Val, - "mem_buffer": s.SysStats.MemBuffer.Val, - "mem_total": s.SysStats.MemTotal.Val, - "mem_used": s.SysStats.MemUsed.Val, - "cpu": s.SystemStats.CPU.Val, - "mem": s.SystemStats.Mem.Val, - "system_uptime": s.SystemStats.Uptime.Val, - // Accumulative Statistics. - "stat_user-rx_packets": s.Stat.Ap.UserRxPackets.Val, - "stat_guest-rx_packets": s.Stat.Ap.GuestRxPackets.Val, - "stat_rx_packets": s.Stat.Ap.RxPackets.Val, - "stat_user-rx_bytes": s.Stat.Ap.UserRxBytes.Val, - "stat_guest-rx_bytes": s.Stat.Ap.GuestRxBytes.Val, - "stat_rx_bytes": s.Stat.Ap.RxBytes.Val, - "stat_user-rx_errors": s.Stat.Ap.UserRxErrors.Val, - "stat_guest-rx_errors": s.Stat.Ap.GuestRxErrors.Val, - "stat_rx_errors": s.Stat.Ap.RxErrors.Val, - "stat_user-rx_dropped": s.Stat.Ap.UserRxDropped.Val, - "stat_guest-rx_dropped": s.Stat.Ap.GuestRxDropped.Val, - "stat_rx_dropped": s.Stat.Ap.RxDropped.Val, - "stat_user-rx_crypts": s.Stat.Ap.UserRxCrypts.Val, - "stat_guest-rx_crypts": s.Stat.Ap.GuestRxCrypts.Val, - "stat_rx_crypts": s.Stat.Ap.RxCrypts.Val, - "stat_user-rx_frags": s.Stat.Ap.UserRxFrags.Val, - "stat_guest-rx_frags": s.Stat.Ap.GuestRxFrags.Val, - "stat_rx_frags": s.Stat.Ap.RxFrags.Val, - "stat_user-tx_packets": s.Stat.Ap.UserTxPackets.Val, - "stat_guest-tx_packets": s.Stat.Ap.GuestTxPackets.Val, - "stat_tx_packets": s.Stat.Ap.TxPackets.Val, - "stat_user-tx_bytes": s.Stat.Ap.UserTxBytes.Val, - "stat_guest-tx_bytes": s.Stat.Ap.GuestTxBytes.Val, - "stat_tx_bytes": s.Stat.Ap.TxBytes.Val, - "stat_user-tx_errors": s.Stat.Ap.UserTxErrors.Val, - "stat_guest-tx_errors": s.Stat.Ap.GuestTxErrors.Val, - "stat_tx_errors": s.Stat.Ap.TxErrors.Val, - "stat_user-tx_dropped": s.Stat.Ap.UserTxDropped.Val, - "stat_guest-tx_dropped": s.Stat.Ap.GuestTxDropped.Val, - "stat_tx_dropped": s.Stat.Ap.TxDropped.Val, - "stat_user-tx_retries": s.Stat.Ap.UserTxRetries.Val, - "stat_guest-tx_retries": s.Stat.Ap.GuestTxRetries.Val, - } + fields := Combine(u.processUAPstats(r, s.Stat.Ap), u.batchSysStats(r, s.SysStats, s.SystemStats)) + fields["ip"] = s.IP + fields["bytes"] = s.Bytes.Val + fields["last_seen"] = s.LastSeen.Val + fields["rx_bytes"] = s.RxBytes.Val + fields["tx_bytes"] = s.TxBytes.Val + fields["uptime"] = s.Uptime.Val + fields["state"] = s.State + fields["user-num_sta"] = int(s.UserNumSta.Val) + fields["guest-num_sta"] = int(s.GuestNumSta.Val) + fields["num_sta"] = s.NumSta.Val r.send(&metric{Table: "uap", Tags: tags, Fields: fields}) - u.processVAPs(r, s.VapTable, s.RadioTable, s.RadioTableStats, s.Name, s.Mac, s.SiteName) + u.processVAPs(r, tags, s.VapTable, s.RadioTable, s.RadioTableStats) +} + +func (u *InfluxUnifi) processUAPstats(r report, ap *unifi.Ap) map[string]interface{} { + // Accumulative Statistics. + return map[string]interface{}{ + "stat_user-rx_packets": ap.UserRxPackets.Val, + "stat_guest-rx_packets": ap.GuestRxPackets.Val, + "stat_rx_packets": ap.RxPackets.Val, + "stat_user-rx_bytes": ap.UserRxBytes.Val, + "stat_guest-rx_bytes": ap.GuestRxBytes.Val, + "stat_rx_bytes": ap.RxBytes.Val, + "stat_user-rx_errors": ap.UserRxErrors.Val, + "stat_guest-rx_errors": ap.GuestRxErrors.Val, + "stat_rx_errors": ap.RxErrors.Val, + "stat_user-rx_dropped": ap.UserRxDropped.Val, + "stat_guest-rx_dropped": ap.GuestRxDropped.Val, + "stat_rx_dropped": ap.RxDropped.Val, + "stat_user-rx_crypts": ap.UserRxCrypts.Val, + "stat_guest-rx_crypts": ap.GuestRxCrypts.Val, + "stat_rx_crypts": ap.RxCrypts.Val, + "stat_user-rx_frags": ap.UserRxFrags.Val, + "stat_guest-rx_frags": ap.GuestRxFrags.Val, + "stat_rx_frags": ap.RxFrags.Val, + "stat_user-tx_packets": ap.UserTxPackets.Val, + "stat_guest-tx_packets": ap.GuestTxPackets.Val, + "stat_tx_packets": ap.TxPackets.Val, + "stat_user-tx_bytes": ap.UserTxBytes.Val, + "stat_guest-tx_bytes": ap.GuestTxBytes.Val, + "stat_tx_bytes": ap.TxBytes.Val, + "stat_user-tx_errors": ap.UserTxErrors.Val, + "stat_guest-tx_errors": ap.GuestTxErrors.Val, + "stat_tx_errors": ap.TxErrors.Val, + "stat_user-tx_dropped": ap.UserTxDropped.Val, + "stat_guest-tx_dropped": ap.GuestTxDropped.Val, + "stat_tx_dropped": ap.TxDropped.Val, + "stat_user-tx_retries": ap.UserTxRetries.Val, + "stat_guest-tx_retries": ap.GuestTxRetries.Val, + } } // processVAPs creates points for Wifi Radios. This works with several types of UAP-capable devices. -func (u *InfluxUnifi) processVAPs(r report, vt unifi.VapTable, rt unifi.RadioTable, rts unifi.RadioTableStats, name, mac, sitename string) { +func (u *InfluxUnifi) processVAPs(r report, tags map[string]string, vt unifi.VapTable, rt unifi.RadioTable, rts unifi.RadioTableStats) { // Loop each virtual AP (ESSID) and extract data for it // from radio_tables and radio_table_stats. for _, s := range vt { - tags := make(map[string]string) - fields := make(map[string]interface{}) - tags["device_name"] = name - tags["device_mac"] = mac - tags["site_name"] = sitename - tags["ap_mac"] = s.ApMac - tags["bssid"] = s.Bssid - tags["id"] = s.ID - tags["name"] = s.Name - tags["radio_name"] = s.RadioName - tags["essid"] = s.Essid - tags["site_id"] = s.SiteID - tags["usage"] = s.Usage - tags["state"] = s.State - tags["is_guest"] = s.IsGuest.Txt + t := make(map[string]string) // tags + f := make(map[string]interface{}) // fields + t["device_name"] = tags["name"] + t["site_name"] = tags["site_name"] + t["ap_mac"] = s.ApMac + t["bssid"] = s.Bssid + t["id"] = s.ID + t["name"] = s.Name + t["radio_name"] = s.RadioName + t["essid"] = s.Essid + t["site_id"] = s.SiteID + t["usage"] = s.Usage + t["state"] = s.State + t["is_guest"] = s.IsGuest.Txt - fields["ccq"] = s.Ccq - fields["mac_filter_rejections"] = s.MacFilterRejections - fields["num_satisfaction_sta"] = s.NumSatisfactionSta.Val - fields["avg_client_signal"] = s.AvgClientSignal.Val - fields["satisfaction"] = s.Satisfaction.Val - fields["satisfaction_now"] = s.SatisfactionNow.Val - fields["rx_bytes"] = s.RxBytes.Val - fields["rx_crypts"] = s.RxCrypts.Val - fields["rx_dropped"] = s.RxDropped.Val - fields["rx_errors"] = s.RxErrors.Val - fields["rx_frags"] = s.RxFrags.Val - fields["rx_nwids"] = s.RxNwids.Val - fields["rx_packets"] = s.RxPackets.Val - fields["tx_bytes"] = s.TxBytes.Val - fields["tx_dropped"] = s.TxDropped.Val - fields["tx_errors"] = s.TxErrors.Val - fields["tx_packets"] = s.TxPackets.Val - fields["tx_power"] = s.TxPower.Val - fields["tx_retries"] = s.TxRetries.Val - fields["tx_combined_retries"] = s.TxCombinedRetries.Val - fields["tx_data_mpdu_bytes"] = s.TxDataMpduBytes.Val - fields["tx_rts_retries"] = s.TxRtsRetries.Val - fields["tx_success"] = s.TxSuccess.Val - fields["tx_total"] = s.TxTotal.Val - fields["tx_tcp_goodbytes"] = s.TxTCPStats.Goodbytes.Val - fields["tx_tcp_lat_avg"] = s.TxTCPStats.LatAvg.Val - fields["tx_tcp_lat_max"] = s.TxTCPStats.LatMax.Val - fields["tx_tcp_lat_min"] = s.TxTCPStats.LatMin.Val - fields["rx_tcp_goodbytes"] = s.RxTCPStats.Goodbytes.Val - fields["rx_tcp_lat_avg"] = s.RxTCPStats.LatAvg.Val - fields["rx_tcp_lat_max"] = s.RxTCPStats.LatMax.Val - fields["rx_tcp_lat_min"] = s.RxTCPStats.LatMin.Val - fields["wifi_tx_latency_mov_avg"] = s.WifiTxLatencyMov.Avg.Val - fields["wifi_tx_latency_mov_max"] = s.WifiTxLatencyMov.Max.Val - fields["wifi_tx_latency_mov_min"] = s.WifiTxLatencyMov.Min.Val - fields["wifi_tx_latency_mov_total"] = s.WifiTxLatencyMov.Total.Val - fields["wifi_tx_latency_mov_cuont"] = s.WifiTxLatencyMov.TotalCount.Val + f["ccq"] = s.Ccq + f["mac_filter_rejections"] = s.MacFilterRejections + f["num_satisfaction_sta"] = s.NumSatisfactionSta.Val + f["avg_client_signal"] = s.AvgClientSignal.Val + f["satisfaction"] = s.Satisfaction.Val + f["satisfaction_now"] = s.SatisfactionNow.Val + f["rx_bytes"] = s.RxBytes.Val + f["rx_crypts"] = s.RxCrypts.Val + f["rx_dropped"] = s.RxDropped.Val + f["rx_errors"] = s.RxErrors.Val + f["rx_frags"] = s.RxFrags.Val + f["rx_nwids"] = s.RxNwids.Val + f["rx_packets"] = s.RxPackets.Val + f["tx_bytes"] = s.TxBytes.Val + f["tx_dropped"] = s.TxDropped.Val + f["tx_errors"] = s.TxErrors.Val + f["tx_packets"] = s.TxPackets.Val + f["tx_power"] = s.TxPower.Val + f["tx_retries"] = s.TxRetries.Val + f["tx_combined_retries"] = s.TxCombinedRetries.Val + f["tx_data_mpdu_bytes"] = s.TxDataMpduBytes.Val + f["tx_rts_retries"] = s.TxRtsRetries.Val + f["tx_success"] = s.TxSuccess.Val + f["tx_total"] = s.TxTotal.Val + f["tx_tcp_goodbytes"] = s.TxTCPStats.Goodbytes.Val + f["tx_tcp_lat_avg"] = s.TxTCPStats.LatAvg.Val + f["tx_tcp_lat_max"] = s.TxTCPStats.LatMax.Val + f["tx_tcp_lat_min"] = s.TxTCPStats.LatMin.Val + f["rx_tcp_goodbytes"] = s.RxTCPStats.Goodbytes.Val + f["rx_tcp_lat_avg"] = s.RxTCPStats.LatAvg.Val + f["rx_tcp_lat_max"] = s.RxTCPStats.LatMax.Val + f["rx_tcp_lat_min"] = s.RxTCPStats.LatMin.Val + f["wifi_tx_latency_mov_avg"] = s.WifiTxLatencyMov.Avg.Val + f["wifi_tx_latency_mov_max"] = s.WifiTxLatencyMov.Max.Val + f["wifi_tx_latency_mov_min"] = s.WifiTxLatencyMov.Min.Val + f["wifi_tx_latency_mov_total"] = s.WifiTxLatencyMov.Total.Val + f["wifi_tx_latency_mov_cuont"] = s.WifiTxLatencyMov.TotalCount.Val + // XXX: This is busted. It needs its own table.... for _, p := range rt { if p.Name != s.RadioName { continue } - tags["channel"] = p.Channel.Txt - tags["radio"] = p.Radio - fields["current_antenna_gain"] = p.CurrentAntennaGain.Val - fields["ht"] = p.Ht.Txt - fields["max_txpower"] = p.MaxTxpower.Val - fields["min_txpower"] = p.MinTxpower.Val - fields["nss"] = p.Nss.Val - fields["radio_caps"] = p.RadioCaps.Val - fields["tx_power"] = p.TxPower.Val + t["channel"] = p.Channel.Txt + t["radio"] = p.Radio + f["current_antenna_gain"] = p.CurrentAntennaGain.Val + f["ht"] = p.Ht.Txt + f["max_txpower"] = p.MaxTxpower.Val + f["min_txpower"] = p.MinTxpower.Val + f["nss"] = p.Nss.Val + f["radio_caps"] = p.RadioCaps.Val + f["tx_power"] = p.TxPower.Val } for _, p := range rts { if p.Name != s.RadioName { continue } - fields["ast_be_xmit"] = p.AstBeXmit.Val - fields["channel"] = p.Channel.Val - fields["cu_self_rx"] = p.CuSelfRx.Val - fields["cu_self_tx"] = p.CuSelfTx.Val - fields["cu_total"] = p.CuTotal.Val - fields["extchannel"] = p.Extchannel.Val - fields["gain"] = p.Gain.Val - fields["guest-num_sta"] = p.GuestNumSta.Val - fields["num_sta"] = p.NumSta.Val - fields["radio"] = p.Radio - fields["tx_packets"] = p.TxPackets.Val - fields["tx_power"] = p.TxPower.Val - fields["tx_retries"] = p.TxRetries.Val - fields["user-num_sta"] = p.UserNumSta.Val + f["ast_be_xmit"] = p.AstBeXmit.Val + f["channel"] = p.Channel.Val + f["cu_self_rx"] = p.CuSelfRx.Val + f["cu_self_tx"] = p.CuSelfTx.Val + f["cu_total"] = p.CuTotal.Val + f["extchannel"] = p.Extchannel.Val + f["gain"] = p.Gain.Val + f["guest-num_sta"] = p.GuestNumSta.Val + f["num_sta"] = p.NumSta.Val + f["radio"] = p.Radio + f["tx_packets"] = p.TxPackets.Val + f["tx_power"] = p.TxPower.Val + f["tx_retries"] = p.TxRetries.Val + f["user-num_sta"] = p.UserNumSta.Val } - r.send(&metric{Table: "uap_vaps", Tags: tags, Fields: fields}) + r.send(&metric{Table: "uap_vaps", Tags: t, Fields: f}) } } diff --git a/pkg/influxunifi/udm.go b/pkg/influxunifi/udm.go index 4b01deb0..66cf78d9 100644 --- a/pkg/influxunifi/udm.go +++ b/pkg/influxunifi/udm.go @@ -4,6 +4,32 @@ import ( "golift.io/unifi" ) +// Combines concatenates N maps. This will delete things if not used with caution. +func Combine(in ...map[string]interface{}) map[string]interface{} { + out := make(map[string]interface{}) + for i := range in { + for k := range in[i] { + out[k] = in[i][k] + } + } + return out +} + +// batchSysStats is used by all device types. +func (u *InfluxUnifi) batchSysStats(r report, s unifi.SysStats, ss unifi.SystemStats) map[string]interface{} { + return map[string]interface{}{ + "loadavg_1": s.Loadavg1.Val, + "loadavg_5": s.Loadavg5.Val, + "loadavg_15": s.Loadavg15.Val, + "mem_used": s.MemUsed.Val, + "mem_buffer": s.MemBuffer.Val, + "mem_total": s.MemTotal.Val, + "cpu": ss.CPU.Val, + "mem": ss.Mem.Val, + "system_uptime": ss.Uptime.Val, + } +} + // batchUDM generates Unifi Gateway datapoints for InfluxDB. // These points can be passed directly to influx. func (u *InfluxUnifi) batchUDM(r report, s *unifi.UDM) { @@ -22,7 +48,7 @@ func (u *InfluxUnifi) batchUDM(r report, s *unifi.UDM) { "serial": s.Serial, "type": s.Type, } - fields := map[string]interface{}{ + fields := Combine(map[string]interface{}{ "ip": s.IP, "bytes": s.Bytes.Val, "last_seen": s.LastSeen.Val, @@ -42,72 +68,14 @@ func (u *InfluxUnifi) batchUDM(r report, s *unifi.UDM) { "speedtest-status_ping": s.SpeedtestStatus.StatusPing.Val, "speedtest-status_xput_download": s.SpeedtestStatus.XputDownload.Val, "speedtest-status_xput_upload": s.SpeedtestStatus.XputUpload.Val, - "wan1_bytes-r": s.Wan1.BytesR.Val, - "wan1_enable": s.Wan1.Enable.Val, - "wan1_full_duplex": s.Wan1.FullDuplex.Val, - "wan1_gateway": s.Wan1.Gateway, - "wan1_ifname": s.Wan1.Ifname, - "wan1_ip": s.Wan1.IP, - "wan1_mac": s.Wan1.Mac, - "wan1_max_speed": s.Wan1.MaxSpeed.Val, - "wan1_name": s.Wan1.Name, - "wan1_rx_bytes": s.Wan1.RxBytes.Val, - "wan1_rx_bytes-r": s.Wan1.RxBytesR.Val, - "wan1_rx_dropped": s.Wan1.RxDropped.Val, - "wan1_rx_errors": s.Wan1.RxErrors.Val, - "wan1_rx_multicast": s.Wan1.RxMulticast.Val, - "wan1_rx_packets": s.Wan1.RxPackets.Val, - "wan1_type": s.Wan1.Type, - "wan1_speed": s.Wan1.Speed.Val, - "wan1_up": s.Wan1.Up.Val, - "wan1_tx_bytes": s.Wan1.TxBytes.Val, - "wan1_tx_bytes-r": s.Wan1.TxBytesR.Val, - "wan1_tx_dropped": s.Wan1.TxDropped.Val, - "wan1_tx_errors": s.Wan1.TxErrors.Val, - "wan1_tx_packets": s.Wan1.TxPackets.Val, - "wan2_bytes-r": s.Wan2.BytesR.Val, - "wan2_enable": s.Wan2.Enable.Val, - "wan2_full_duplex": s.Wan2.FullDuplex.Val, - "wan2_gateway": s.Wan2.Gateway, - "wan2_ifname": s.Wan2.Ifname, - "wan2_ip": s.Wan2.IP, - "wan2_mac": s.Wan2.Mac, - "wan2_max_speed": s.Wan2.MaxSpeed.Val, - "wan2_name": s.Wan2.Name, - "wan2_rx_bytes": s.Wan2.RxBytes.Val, - "wan2_rx_bytes-r": s.Wan2.RxBytesR.Val, - "wan2_rx_dropped": s.Wan2.RxDropped.Val, - "wan2_rx_errors": s.Wan2.RxErrors.Val, - "wan2_rx_multicast": s.Wan2.RxMulticast.Val, - "wan2_rx_packets": s.Wan2.RxPackets.Val, - "wan2_type": s.Wan2.Type, - "wan2_speed": s.Wan2.Speed.Val, - "wan2_up": s.Wan2.Up.Val, - "wan2_tx_bytes": s.Wan2.TxBytes.Val, - "wan2_tx_bytes-r": s.Wan2.TxBytesR.Val, - "wan2_tx_dropped": s.Wan2.TxDropped.Val, - "wan2_tx_errors": s.Wan2.TxErrors.Val, - "wan2_tx_packets": s.Wan2.TxPackets.Val, - "loadavg_1": s.SysStats.Loadavg1.Val, - "loadavg_5": s.SysStats.Loadavg5.Val, - "loadavg_15": s.SysStats.Loadavg15.Val, - "mem_used": s.SysStats.MemUsed.Val, - "mem_buffer": s.SysStats.MemBuffer.Val, - "mem_total": s.SysStats.MemTotal.Val, - "cpu": s.SystemStats.CPU.Val, - "mem": s.SystemStats.Mem.Val, - "system_uptime": s.SystemStats.Uptime.Val, - "lan-rx_bytes": s.Stat.LanRxBytes.Val, - "lan-rx_packets": s.Stat.LanRxPackets.Val, - "lan-tx_bytes": s.Stat.LanTxBytes.Val, - "lan-tx_packets": s.Stat.LanTxPackets.Val, - "wan-rx_bytes": s.Stat.WanRxBytes.Val, - "wan-rx_dropped": s.Stat.WanRxDropped.Val, - "wan-rx_packets": s.Stat.WanRxPackets.Val, - "wan-tx_bytes": s.Stat.WanTxBytes.Val, - "wan-tx_packets": s.Stat.WanTxPackets.Val, - } + "lan-rx_bytes": s.Stat.Gw.LanRxBytes.Val, + "lan-rx_packets": s.Stat.Gw.LanRxPackets.Val, + "lan-tx_bytes": s.Stat.Gw.LanTxBytes.Val, + "lan-tx_packets": s.Stat.Gw.LanTxPackets.Val, + }, u.batchSysStats(r, s.SysStats, s.SystemStats)) r.send(&metric{Table: "usg", Tags: tags, Fields: fields}) + u.batchNetworkTable(r, tags, s.NetworkTable) + u.batchUSGwans(r, tags, s.Wan1, s.Wan2) tags = map[string]string{ "mac": s.Mac, @@ -127,16 +95,6 @@ func (u *InfluxUnifi) batchUDM(r report, s *unifi.UDM) { "tx_bytes": s.TxBytes.Val, "uptime": s.Uptime.Val, "state": s.State.Val, - "user-num_sta": s.UserNumSta.Val, - "loadavg_1": s.SysStats.Loadavg1.Val, - "loadavg_5": s.SysStats.Loadavg5.Val, - "loadavg_15": s.SysStats.Loadavg15.Val, - "mem_buffer": s.SysStats.MemBuffer.Val, - "mem_used": s.SysStats.MemUsed.Val, - "mem_total": s.SysStats.MemTotal.Val, - "cpu": s.SystemStats.CPU.Val, - "mem": s.SystemStats.Mem.Val, - "system_uptime": s.SystemStats.Uptime.Val, "stat_bytes": s.Stat.Sw.Bytes.Val, "stat_rx_bytes": s.Stat.Sw.RxBytes.Val, "stat_rx_crypts": s.Stat.Sw.RxCrypts.Val, @@ -151,85 +109,8 @@ func (u *InfluxUnifi) batchUDM(r report, s *unifi.UDM) { "stat_tx_retries": s.Stat.Sw.TxRetries.Val, } r.send(&metric{Table: "usw", Tags: tags, Fields: fields}) + u.batchPortTable(r, tags, s.PortTable) - for _, p := range s.NetworkTable { - tags := map[string]string{ - "device_name": s.Name, - "device_id": s.ID, - "device_mac": s.Mac, - "site_name": s.SiteName, - "up": p.Up.Txt, - "enabled": p.Enabled.Txt, - "site_id": p.SiteID, - "ip": p.IP, - "ip_subnet": p.IPSubnet, - "mac": p.Mac, - "name": p.Name, - "domain_name": p.DomainName, - "purpose": p.Purpose, - } - fields := map[string]interface{}{ - "domain_name": p.DomainName, - "dhcpd_start": p.DhcpdStart, - "dhcpd_stop": p.DhcpdStop, - "ip": p.IP, - "ip_subnet": p.IPSubnet, - "mac": p.Mac, - "name": p.Name, - "num_sta": p.NumSta.Val, - "purpose": p.Purpose, - "rx_bytes": p.RxBytes.Val, - "rx_packets": p.RxPackets.Val, - "tx_bytes": p.TxBytes.Val, - "tx_packets": p.TxPackets.Val, - "ipv6_interface_type": p.Ipv6InterfaceType, - "attr_hidden_id": p.AttrHiddenID, - } - r.send(&metric{Table: "usg_networks", Tags: tags, Fields: fields}) - } - - for _, p := range s.PortTable { - tags := map[string]string{ - "site_id": s.SiteID, - "site_name": s.SiteName, - "device_name": s.Name, - "name": p.Name, - "enable": p.Enable.Txt, - "up": p.Up.Txt, - "poe_mode": p.PoeMode, - "port_poe": p.PortPoe.Txt, - "port_idx": p.PortIdx.Txt, - "port_id": s.Name + " Port " + p.PortIdx.Txt, - "poe_enable": p.PoeEnable.Txt, - "flowctrl_rx": p.FlowctrlRx.Txt, - "flowctrl_tx": p.FlowctrlTx.Txt, - "media": p.Media, - "poe_class": p.PoeClass, - } - fields := map[string]interface{}{ - "dbytes_r": p.BytesR.Val, - "rx_broadcast": p.RxBroadcast.Val, - "rx_bytes": p.RxBytes.Val, - "rx_bytes-r": p.RxBytesR.Val, - "rx_dropped": p.RxDropped.Val, - "rx_errors": p.RxErrors.Val, - "rx_multicast": p.RxMulticast.Val, - "rx_packets": p.RxPackets.Val, - "speed": p.Speed.Val, - "stp_pathcost": p.StpPathcost.Val, - "tx_broadcast": p.TxBroadcast.Val, - "tx_bytes": p.TxBytes.Val, - "tx_bytes-r": p.TxBytesR.Val, - "tx_dropped": p.TxDropped.Val, - "tx_errors": p.TxErrors.Val, - "tx_multicast": p.TxMulticast.Val, - "tx_packets": p.TxPackets.Val, - "poe_current": p.PoeCurrent.Val, - "poe_power": p.PoePower.Val, - "poe_voltage": p.PoeVoltage.Val, - } - r.send(&metric{Table: "usw_ports", Tags: tags, Fields: fields}) - } if s.Stat.Ap == nil { return // we're done now. the following code process UDM (non-pro) UAP data. @@ -243,60 +124,17 @@ func (u *InfluxUnifi) batchUDM(r report, s *unifi.UDM) { "serial": s.Serial, "type": s.Type, } - fields = map[string]interface{}{ - "ip": s.IP, - "bytes": s.Bytes.Val, - "last_seen": s.LastSeen.Val, - "rx_bytes": s.RxBytes.Val, - "tx_bytes": s.TxBytes.Val, - "uptime": s.Uptime.Val, - "state": int(s.State.Val), - "user-num_sta": int(s.UserWlanNumSta.Val), - "guest-num_sta": int(s.GuestWlanNumSta.Val), - "num_sta": s.WlanNumSta.Val, - "loadavg_1": s.SysStats.Loadavg1.Val, - "loadavg_5": s.SysStats.Loadavg5.Val, - "loadavg_15": s.SysStats.Loadavg15.Val, - "mem_buffer": s.SysStats.MemBuffer.Val, - "mem_total": s.SysStats.MemTotal.Val, - "mem_used": s.SysStats.MemUsed.Val, - "cpu": s.SystemStats.CPU.Val, - "mem": s.SystemStats.Mem.Val, - "system_uptime": s.SystemStats.Uptime.Val, - // Accumulative Statistics. - "stat_user-rx_packets": s.Stat.Ap.UserRxPackets.Val, - "stat_guest-rx_packets": s.Stat.Ap.GuestRxPackets.Val, - "stat_rx_packets": s.Stat.Ap.RxPackets.Val, - "stat_user-rx_bytes": s.Stat.Ap.UserRxBytes.Val, - "stat_guest-rx_bytes": s.Stat.Ap.GuestRxBytes.Val, - "stat_rx_bytes": s.Stat.Ap.RxBytes.Val, - "stat_user-rx_errors": s.Stat.Ap.UserRxErrors.Val, - "stat_guest-rx_errors": s.Stat.Ap.GuestRxErrors.Val, - "stat_rx_errors": s.Stat.Ap.RxErrors.Val, - "stat_user-rx_dropped": s.Stat.Ap.UserRxDropped.Val, - "stat_guest-rx_dropped": s.Stat.Ap.GuestRxDropped.Val, - "stat_rx_dropped": s.Stat.Ap.RxDropped.Val, - "stat_user-rx_crypts": s.Stat.Ap.UserRxCrypts.Val, - "stat_guest-rx_crypts": s.Stat.Ap.GuestRxCrypts.Val, - "stat_rx_crypts": s.Stat.Ap.RxCrypts.Val, - "stat_user-rx_frags": s.Stat.Ap.UserRxFrags.Val, - "stat_guest-rx_frags": s.Stat.Ap.GuestRxFrags.Val, - "stat_rx_frags": s.Stat.Ap.RxFrags.Val, - "stat_user-tx_packets": s.Stat.Ap.UserTxPackets.Val, - "stat_guest-tx_packets": s.Stat.Ap.GuestTxPackets.Val, - "stat_tx_packets": s.Stat.Ap.TxPackets.Val, - "stat_user-tx_bytes": s.Stat.Ap.UserTxBytes.Val, - "stat_guest-tx_bytes": s.Stat.Ap.GuestTxBytes.Val, - "stat_tx_bytes": s.Stat.Ap.TxBytes.Val, - "stat_user-tx_errors": s.Stat.Ap.UserTxErrors.Val, - "stat_guest-tx_errors": s.Stat.Ap.GuestTxErrors.Val, - "stat_tx_errors": s.Stat.Ap.TxErrors.Val, - "stat_user-tx_dropped": s.Stat.Ap.UserTxDropped.Val, - "stat_guest-tx_dropped": s.Stat.Ap.GuestTxDropped.Val, - "stat_tx_dropped": s.Stat.Ap.TxDropped.Val, - "stat_user-tx_retries": s.Stat.Ap.UserTxRetries.Val, - "stat_guest-tx_retries": s.Stat.Ap.GuestTxRetries.Val, - } + fields = u.processUAPstats(r, s.Stat.Ap) + fields["ip"] = s.IP + fields["bytes"] = s.Bytes.Val + fields["last_seen"] = s.LastSeen.Val + fields["rx_bytes"] = s.RxBytes.Val + fields["tx_bytes"] = s.TxBytes.Val + fields["uptime"] = s.Uptime.Val + fields["state"] = s.State + fields["user-num_sta"] = int(s.UserNumSta.Val) + fields["guest-num_sta"] = int(s.GuestNumSta.Val) + fields["num_sta"] = s.NumSta.Val r.send(&metric{Table: "uap", Tags: tags, Fields: fields}) - u.processVAPs(r, *s.VapTable, *s.RadioTable, *s.RadioTableStats, s.Name, s.Mac, s.SiteName) + u.processVAPs(r, tags, *s.VapTable, *s.RadioTable, *s.RadioTableStats) } diff --git a/pkg/influxunifi/usg.go b/pkg/influxunifi/usg.go index 07a479d4..54f0142c 100644 --- a/pkg/influxunifi/usg.go +++ b/pkg/influxunifi/usg.go @@ -1,8 +1,6 @@ package influxunifi import ( - "strings" - "golift.io/unifi" ) @@ -41,84 +39,93 @@ func (u *InfluxUnifi) batchUSG(r report, s *unifi.USG) { "speedtest-status_ping": s.SpeedtestStatus.StatusPing.Val, "speedtest-status_xput_download": s.SpeedtestStatus.XputDownload.Val, "speedtest-status_xput_upload": s.SpeedtestStatus.XputUpload.Val, - "wan1_bytes-r": s.Wan1.BytesR.Val, - "wan1_enable": s.Wan1.Enable.Val, - "wan1_full_duplex": s.Wan1.FullDuplex.Val, - "wan1_gateway": s.Wan1.Gateway, - "wan1_ifname": s.Wan1.Ifname, - "wan1_ip": s.Wan1.IP, - "wan1_mac": s.Wan1.Mac, - "wan1_max_speed": s.Wan1.MaxSpeed.Val, - "wan1_name": s.Wan1.Name, - "wan1_rx_bytes": s.Wan1.RxBytes.Val, - "wan1_rx_bytes-r": s.Wan1.RxBytesR.Val, - "wan1_rx_dropped": s.Wan1.RxDropped.Val, - "wan1_rx_errors": s.Wan1.RxErrors.Val, - "wan1_rx_multicast": s.Wan1.RxMulticast.Val, - "wan1_rx_packets": s.Wan1.RxPackets.Val, - "wan1_type": s.Wan1.Type, - "wan1_speed": s.Wan1.Speed.Val, - "wan1_up": s.Wan1.Up.Val, - "wan1_tx_bytes": s.Wan1.TxBytes.Val, - "wan1_tx_bytes-r": s.Wan1.TxBytesR.Val, - "wan1_tx_dropped": s.Wan1.TxDropped.Val, - "wan1_tx_errors": s.Wan1.TxErrors.Val, - "wan1_tx_packets": s.Wan1.TxPackets.Val, - "wan2_bytes-r": s.Wan2.BytesR.Val, - "wan2_enable": s.Wan2.Enable.Val, - "wan2_full_duplex": s.Wan2.FullDuplex.Val, - "wan2_gateway": s.Wan2.Gateway, - "wan2_ifname": s.Wan2.Ifname, - "wan2_ip": s.Wan2.IP, - "wan2_mac": s.Wan2.Mac, - "wan2_max_speed": s.Wan2.MaxSpeed.Val, - "wan2_name": s.Wan2.Name, - "wan2_rx_bytes": s.Wan2.RxBytes.Val, - "wan2_rx_bytes-r": s.Wan2.RxBytesR.Val, - "wan2_rx_dropped": s.Wan2.RxDropped.Val, - "wan2_rx_errors": s.Wan2.RxErrors.Val, - "wan2_rx_multicast": s.Wan2.RxMulticast.Val, - "wan2_rx_packets": s.Wan2.RxPackets.Val, - "wan2_type": s.Wan2.Type, - "wan2_speed": s.Wan2.Speed.Val, - "wan2_up": s.Wan2.Up.Val, - "wan2_tx_bytes": s.Wan2.TxBytes.Val, - "wan2_tx_bytes-r": s.Wan2.TxBytesR.Val, - "wan2_tx_dropped": s.Wan2.TxDropped.Val, - "wan2_tx_errors": s.Wan2.TxErrors.Val, - "wan2_tx_packets": s.Wan2.TxPackets.Val, - "loadavg_1": s.SysStats.Loadavg1.Val, - "loadavg_5": s.SysStats.Loadavg5.Val, - "loadavg_15": s.SysStats.Loadavg15.Val, - "mem_used": s.SysStats.MemUsed.Val, - "mem_buffer": s.SysStats.MemBuffer.Val, - "mem_total": s.SysStats.MemTotal.Val, - "cpu": s.SystemStats.CPU.Val, - "mem": s.SystemStats.Mem.Val, - "system_uptime": s.SystemStats.Uptime.Val, - "lan-rx_bytes": s.Stat.LanRxBytes.Val, - "lan-rx_packets": s.Stat.LanRxPackets.Val, - "lan-tx_bytes": s.Stat.LanTxBytes.Val, - "lan-tx_packets": s.Stat.LanTxPackets.Val, - "wan-rx_bytes": s.Stat.WanRxBytes.Val, - "wan-rx_dropped": s.Stat.WanRxDropped.Val, - "wan-rx_packets": s.Stat.WanRxPackets.Val, - "wan-tx_bytes": s.Stat.WanTxBytes.Val, - "wan-tx_packets": s.Stat.WanTxPackets.Val, + "lan-rx_bytes": s.Stat.Gw.LanRxBytes.Val, + "lan-rx_packets": s.Stat.Gw.LanRxPackets.Val, + "lan-tx_bytes": s.Stat.Gw.LanTxBytes.Val, + "lan-tx_packets": s.Stat.Gw.LanTxPackets.Val, } + /* + for _, p := range s.PortTable { + t := map[string]string{ + "device_name": tags["name"], + "site_name": tags["site_name"], + "name": p.Name, + "ifname": p.Ifname, + "ip": p.IP, + "mac": p.Mac, + "up": p.Up.Txt, + "speed": p.Speed.Txt, + "full_duplex": p.FullDuplex.Txt, + "enable": p.Enable.Txt, + } + f := map[string]interface{}{ + "rx_bytes": p.RxBytes.Val, + "rx_dropped": p.RxDropped.Val, + "rx_errors": p.RxErrors.Val, + "rx_packets": p.RxBytes.Val, + "tx_bytes": p.TxBytes.Val, + "tx_dropped": p.TxDropped.Val, + "tx_errors": p.TxErrors.Val, + "tx_packets": p.TxPackets.Val, + "rx_multicast": p.RxMulticast.Val, + "dns_servers": strings.Join(p.DNS, ","), + } + r.send(&metric{Table: "usg_ports", Tags: t, Fields: f}) + } + */ + fields = Combine(fields, u.batchSysStats(r, s.SysStats, s.SystemStats)) r.send(&metric{Table: "usg", Tags: tags, Fields: fields}) + u.batchNetworkTable(r, tags, s.NetworkTable) + u.batchUSGwans(r, tags, s.Wan1, s.Wan2) +} - for _, p := range s.NetworkTable { +func (u *InfluxUnifi) batchUSGwans(r report, tags map[string]string, wans ...unifi.Wan) { + for _, wan := range wans { + if !wan.Up.Val { + continue + } tags := map[string]string{ - "device_name": s.Name, - "device_id": s.ID, - "device_mac": s.Mac, - "site_name": s.SiteName, + "device_name": tags["name"], + "site_name": tags["site_name"], + "wan_name": wan.Name, + } + fields := map[string]interface{}{ + "bytes-r": wan.BytesR.Val, + "enable": wan.Enable.Val, + "full_duplex": wan.FullDuplex.Val, + "gateway": wan.Gateway, + "ifname": wan.Ifname, + "ip": wan.IP, + "mac": wan.Mac, + "max_speed": wan.MaxSpeed.Val, + "name": wan.Name, + "rx_bytes": wan.RxBytes.Val, + "rx_bytes-r": wan.RxBytesR.Val, + "rx_dropped": wan.RxDropped.Val, + "rx_errors": wan.RxErrors.Val, + "rx_multicast": wan.RxMulticast.Val, + "rx_packets": wan.RxPackets.Val, + "type": wan.Type, + "speed": wan.Speed.Val, + "up": wan.Up.Val, + "tx_bytes": wan.TxBytes.Val, + "tx_bytes-r": wan.TxBytesR.Val, + "tx_dropped": wan.TxDropped.Val, + "tx_errors": wan.TxErrors.Val, + "tx_packets": wan.TxPackets.Val, + } + r.send(&metric{Table: "usg_wan_ports", Tags: tags, Fields: fields}) + } +} + +func (u *InfluxUnifi) batchNetworkTable(r report, tags map[string]string, nt unifi.NetworkTable) { + for _, p := range nt { + tags := map[string]string{ + "device_name": tags["name"], + "site_name": tags["site_name"], "up": p.Up.Txt, "enabled": p.Enabled.Txt, - "site_id": p.SiteID, "ip": p.IP, - "ip_subnet": p.IPSubnet, "mac": p.Mac, "name": p.Name, "domain_name": p.DomainName, @@ -133,34 +140,4 @@ func (u *InfluxUnifi) batchUSG(r report, s *unifi.USG) { } r.send(&metric{Table: "usg_networks", Tags: tags, Fields: fields}) } - for _, p := range s.PortTable { - tags := map[string]string{ - "device_name": s.Name, - "device_id": s.ID, - "device_mac": s.Mac, - "site_name": s.SiteName, - "name": p.Name, - "ifname": p.Ifname, - "ip": p.IP, - "mac": p.Mac, - "up": p.Up.Txt, - "speed": p.Speed.Txt, - "full_duplex": p.FullDuplex.Txt, - "enable": p.Enable.Txt, - } - fields := map[string]interface{}{ - "rx_bytes": p.RxBytes.Val, - "rx_dropped": p.RxDropped.Val, - "rx_errors": p.RxErrors.Val, - "rx_packets": p.RxBytes.Val, - "tx_bytes": p.TxBytes.Val, - "tx_dropped": p.TxDropped.Val, - "tx_errors": p.TxErrors.Val, - "tx_packets": p.TxPackets.Val, - "rx_multicast": p.RxMulticast.Val, - "dns_servers": strings.Join(p.DNS, ","), - } - r.send(&metric{Table: "usg_ports", Tags: tags, Fields: fields}) - - } } diff --git a/pkg/influxunifi/usw.go b/pkg/influxunifi/usw.go index 60a88853..2187c95e 100644 --- a/pkg/influxunifi/usw.go +++ b/pkg/influxunifi/usw.go @@ -19,7 +19,7 @@ func (u *InfluxUnifi) batchUSW(r report, s *unifi.USW) { "serial": s.Serial, "type": s.Type, } - fields := map[string]interface{}{ + fields := Combine(map[string]interface{}{ "guest-num_sta": s.GuestNumSta.Val, "ip": s.IP, "bytes": s.Bytes.Val, @@ -31,15 +31,6 @@ func (u *InfluxUnifi) batchUSW(r report, s *unifi.USW) { "uptime": s.Uptime.Val, "state": s.State.Val, "user-num_sta": s.UserNumSta.Val, - "loadavg_1": s.SysStats.Loadavg1.Val, - "loadavg_5": s.SysStats.Loadavg5.Val, - "loadavg_15": s.SysStats.Loadavg15.Val, - "mem_buffer": s.SysStats.MemBuffer.Val, - "mem_used": s.SysStats.MemUsed.Val, - "mem_total": s.SysStats.MemTotal.Val, - "cpu": s.SystemStats.CPU.Val, - "mem": s.SystemStats.Mem.Val, - "system_uptime": s.SystemStats.Uptime.Val, "stat_bytes": s.Stat.Sw.Bytes.Val, "stat_rx_bytes": s.Stat.Sw.RxBytes.Val, "stat_rx_crypts": s.Stat.Sw.RxCrypts.Val, @@ -52,21 +43,24 @@ func (u *InfluxUnifi) batchUSW(r report, s *unifi.USW) { "stat_tx_errors": s.Stat.Sw.TxErrors.Val, "stat_tx_packets": s.Stat.Sw.TxPackets.Val, "stat_tx_retries": s.Stat.Sw.TxRetries.Val, - } + }, u.batchSysStats(r, s.SysStats, s.SystemStats)) r.send(&metric{Table: "usw", Tags: tags, Fields: fields}) + u.batchPortTable(r, tags, s.PortTable) +} - for _, p := range s.PortTable { +func (u *InfluxUnifi) batchPortTable(r report, tags map[string]string, pt []unifi.Port) { + for _, p := range pt { if !p.Up.Val || !p.Enable.Val { continue // only record UP ports. } tags := map[string]string{ - "site_name": s.SiteName, - "device_name": s.Name, + "site_name": tags["site_name"], + "device_name": tags["name"], "name": p.Name, "poe_mode": p.PoeMode, "port_poe": p.PortPoe.Txt, "port_idx": p.PortIdx.Txt, - "port_id": s.Name + " Port " + p.PortIdx.Txt, + "port_id": tags["name"] + " Port " + p.PortIdx.Txt, "poe_enable": p.PoeEnable.Txt, "flowctrl_rx": p.FlowctrlRx.Txt, "flowctrl_tx": p.FlowctrlTx.Txt, From ec3bae40be549d9aef02cb15073955801a36ccbc Mon Sep 17 00:00:00 2001 From: davidnewhall2 Date: Sat, 30 Nov 2019 19:30:21 -0800 Subject: [PATCH 06/10] test fix --- pkg/influxunifi/metrics.go | 3 +-- pkg/influxunifi/report.go | 11 +++-------- pkg/influxunifi/uap.go | 4 ++-- pkg/influxunifi/udm.go | 6 +++--- pkg/influxunifi/usg.go | 2 +- pkg/influxunifi/usw.go | 2 +- 6 files changed, 11 insertions(+), 17 deletions(-) diff --git a/pkg/influxunifi/metrics.go b/pkg/influxunifi/metrics.go index af8bd274..90a95a31 100644 --- a/pkg/influxunifi/metrics.go +++ b/pkg/influxunifi/metrics.go @@ -8,7 +8,6 @@ import ( "time" "github.com/davidnewhall/unifi-poller/pkg/metrics" - _ "github.com/influxdata/influxdb1-client" influx "github.com/influxdata/influxdb1-client/v2" ) @@ -60,6 +59,7 @@ func (u *InfluxUnifi) ReportMetrics(m *metrics.Metrics) (*Report, error) { go u.collect(r, r.ch) // Batch all the points. u.loopPoints(r) + r.wg.Wait() // wait for all points to finish batching! // Send all the points. if err = u.influx.Write(r.bp); err != nil { @@ -139,5 +139,4 @@ func (u *InfluxUnifi) loopPoints(r report) { u.batchUDM(r, s) } }() - r.wait() } diff --git a/pkg/influxunifi/report.go b/pkg/influxunifi/report.go index 42211c26..5d1e760d 100644 --- a/pkg/influxunifi/report.go +++ b/pkg/influxunifi/report.go @@ -21,14 +21,10 @@ type Report struct { bp influx.BatchPoints } -// satisfy gomnd -const one = 1 - // report is an internal interface that can be mocked and overrridden for tests. type report interface { add() done() - wait() send(m *metric) error(err error) batch(m *metric, pt *influx.Point) @@ -39,6 +35,9 @@ func (r *Report) metrics() *metrics.Metrics { return r.Metrics } +// satisfy gomnd +const one = 1 + func (r *Report) add() { r.wg.Add(one) } @@ -52,10 +51,6 @@ func (r *Report) send(m *metric) { r.ch <- m } -func (r *Report) wait() { - r.wg.Wait() -} - /* The following methods are not thread safe. */ func (r *Report) error(err error) { diff --git a/pkg/influxunifi/uap.go b/pkg/influxunifi/uap.go index 005ef640..dc7c6214 100644 --- a/pkg/influxunifi/uap.go +++ b/pkg/influxunifi/uap.go @@ -19,7 +19,7 @@ func (u *InfluxUnifi) batchUAP(r report, s *unifi.UAP) { "serial": s.Serial, "type": s.Type, } - fields := Combine(u.processUAPstats(r, s.Stat.Ap), u.batchSysStats(r, s.SysStats, s.SystemStats)) + fields := Combine(u.processUAPstats(s.Stat.Ap), u.batchSysStats(s.SysStats, s.SystemStats)) fields["ip"] = s.IP fields["bytes"] = s.Bytes.Val fields["last_seen"] = s.LastSeen.Val @@ -34,7 +34,7 @@ func (u *InfluxUnifi) batchUAP(r report, s *unifi.UAP) { u.processVAPs(r, tags, s.VapTable, s.RadioTable, s.RadioTableStats) } -func (u *InfluxUnifi) processUAPstats(r report, ap *unifi.Ap) map[string]interface{} { +func (u *InfluxUnifi) processUAPstats(ap *unifi.Ap) map[string]interface{} { // Accumulative Statistics. return map[string]interface{}{ "stat_user-rx_packets": ap.UserRxPackets.Val, diff --git a/pkg/influxunifi/udm.go b/pkg/influxunifi/udm.go index 66cf78d9..cbe43f1f 100644 --- a/pkg/influxunifi/udm.go +++ b/pkg/influxunifi/udm.go @@ -16,7 +16,7 @@ func Combine(in ...map[string]interface{}) map[string]interface{} { } // batchSysStats is used by all device types. -func (u *InfluxUnifi) batchSysStats(r report, s unifi.SysStats, ss unifi.SystemStats) map[string]interface{} { +func (u *InfluxUnifi) batchSysStats(s unifi.SysStats, ss unifi.SystemStats) map[string]interface{} { return map[string]interface{}{ "loadavg_1": s.Loadavg1.Val, "loadavg_5": s.Loadavg5.Val, @@ -72,7 +72,7 @@ func (u *InfluxUnifi) batchUDM(r report, s *unifi.UDM) { "lan-rx_packets": s.Stat.Gw.LanRxPackets.Val, "lan-tx_bytes": s.Stat.Gw.LanTxBytes.Val, "lan-tx_packets": s.Stat.Gw.LanTxPackets.Val, - }, u.batchSysStats(r, s.SysStats, s.SystemStats)) + }, u.batchSysStats(s.SysStats, s.SystemStats)) r.send(&metric{Table: "usg", Tags: tags, Fields: fields}) u.batchNetworkTable(r, tags, s.NetworkTable) u.batchUSGwans(r, tags, s.Wan1, s.Wan2) @@ -124,7 +124,7 @@ func (u *InfluxUnifi) batchUDM(r report, s *unifi.UDM) { "serial": s.Serial, "type": s.Type, } - fields = u.processUAPstats(r, s.Stat.Ap) + fields = u.processUAPstats(s.Stat.Ap) fields["ip"] = s.IP fields["bytes"] = s.Bytes.Val fields["last_seen"] = s.LastSeen.Val diff --git a/pkg/influxunifi/usg.go b/pkg/influxunifi/usg.go index 54f0142c..db3df2b7 100644 --- a/pkg/influxunifi/usg.go +++ b/pkg/influxunifi/usg.go @@ -73,7 +73,7 @@ func (u *InfluxUnifi) batchUSG(r report, s *unifi.USG) { r.send(&metric{Table: "usg_ports", Tags: t, Fields: f}) } */ - fields = Combine(fields, u.batchSysStats(r, s.SysStats, s.SystemStats)) + fields = Combine(fields, u.batchSysStats(s.SysStats, s.SystemStats)) r.send(&metric{Table: "usg", Tags: tags, Fields: fields}) u.batchNetworkTable(r, tags, s.NetworkTable) u.batchUSGwans(r, tags, s.Wan1, s.Wan2) diff --git a/pkg/influxunifi/usw.go b/pkg/influxunifi/usw.go index 2187c95e..ce669ca1 100644 --- a/pkg/influxunifi/usw.go +++ b/pkg/influxunifi/usw.go @@ -43,7 +43,7 @@ func (u *InfluxUnifi) batchUSW(r report, s *unifi.USW) { "stat_tx_errors": s.Stat.Sw.TxErrors.Val, "stat_tx_packets": s.Stat.Sw.TxPackets.Val, "stat_tx_retries": s.Stat.Sw.TxRetries.Val, - }, u.batchSysStats(r, s.SysStats, s.SystemStats)) + }, u.batchSysStats(s.SysStats, s.SystemStats)) r.send(&metric{Table: "usw", Tags: tags, Fields: fields}) u.batchPortTable(r, tags, s.PortTable) } From 9eeeaebabd8dc5c56f252ab84e08a8a5a6572c05 Mon Sep 17 00:00:00 2001 From: davidnewhall2 Date: Sun, 1 Dec 2019 00:43:57 -0800 Subject: [PATCH 07/10] fixes --- pkg/influxunifi/clients.go | 2 + pkg/influxunifi/uap.go | 188 +++++++++++++++++++------------------ pkg/influxunifi/udm.go | 5 +- pkg/influxunifi/usg.go | 30 +++--- pkg/influxunifi/usw.go | 8 +- pkg/poller/influx.go | 6 ++ pkg/poller/start.go | 41 ++++---- 7 files changed, 151 insertions(+), 129 deletions(-) diff --git a/pkg/influxunifi/clients.go b/pkg/influxunifi/clients.go index f954da17..127ab7e2 100644 --- a/pkg/influxunifi/clients.go +++ b/pkg/influxunifi/clients.go @@ -37,6 +37,8 @@ func (u *InfluxUnifi) batchClient(r report, s *unifi.Client) { "ip": s.IP, "essid": s.Essid, "bssid": s.Bssid, + "channel": s.Channel.Val, + "hostname": s.Name, "radio_desc": s.RadioDescription, "satisfaction": s.Satisfaction.Val, "bytes_r": s.BytesR, diff --git a/pkg/influxunifi/uap.go b/pkg/influxunifi/uap.go index dc7c6214..81d4be17 100644 --- a/pkg/influxunifi/uap.go +++ b/pkg/influxunifi/uap.go @@ -31,7 +31,9 @@ func (u *InfluxUnifi) batchUAP(r report, s *unifi.UAP) { fields["guest-num_sta"] = int(s.GuestNumSta.Val) fields["num_sta"] = s.NumSta.Val r.send(&metric{Table: "uap", Tags: tags, Fields: fields}) - u.processVAPs(r, tags, s.VapTable, s.RadioTable, s.RadioTableStats) + u.processRadTable(r, tags, s.RadioTable, s.RadioTableStats) + u.processVAPTable(r, tags, s.VapTable) + } func (u *InfluxUnifi) processUAPstats(ap *unifi.Ap) map[string]interface{} { @@ -72,99 +74,101 @@ func (u *InfluxUnifi) processUAPstats(ap *unifi.Ap) map[string]interface{} { } } -// processVAPs creates points for Wifi Radios. This works with several types of UAP-capable devices. -func (u *InfluxUnifi) processVAPs(r report, tags map[string]string, vt unifi.VapTable, rt unifi.RadioTable, rts unifi.RadioTableStats) { - // Loop each virtual AP (ESSID) and extract data for it - // from radio_tables and radio_table_stats. +// processVAPTable creates points for Wifi Radios. This works with several types of UAP-capable devices. +func (u *InfluxUnifi) processVAPTable(r report, t map[string]string, vt unifi.VapTable) { for _, s := range vt { - t := make(map[string]string) // tags - f := make(map[string]interface{}) // fields - t["device_name"] = tags["name"] - t["site_name"] = tags["site_name"] - t["ap_mac"] = s.ApMac - t["bssid"] = s.Bssid - t["id"] = s.ID - t["name"] = s.Name - t["radio_name"] = s.RadioName - t["essid"] = s.Essid - t["site_id"] = s.SiteID - t["usage"] = s.Usage - t["state"] = s.State - t["is_guest"] = s.IsGuest.Txt - - f["ccq"] = s.Ccq - f["mac_filter_rejections"] = s.MacFilterRejections - f["num_satisfaction_sta"] = s.NumSatisfactionSta.Val - f["avg_client_signal"] = s.AvgClientSignal.Val - f["satisfaction"] = s.Satisfaction.Val - f["satisfaction_now"] = s.SatisfactionNow.Val - f["rx_bytes"] = s.RxBytes.Val - f["rx_crypts"] = s.RxCrypts.Val - f["rx_dropped"] = s.RxDropped.Val - f["rx_errors"] = s.RxErrors.Val - f["rx_frags"] = s.RxFrags.Val - f["rx_nwids"] = s.RxNwids.Val - f["rx_packets"] = s.RxPackets.Val - f["tx_bytes"] = s.TxBytes.Val - f["tx_dropped"] = s.TxDropped.Val - f["tx_errors"] = s.TxErrors.Val - f["tx_packets"] = s.TxPackets.Val - f["tx_power"] = s.TxPower.Val - f["tx_retries"] = s.TxRetries.Val - f["tx_combined_retries"] = s.TxCombinedRetries.Val - f["tx_data_mpdu_bytes"] = s.TxDataMpduBytes.Val - f["tx_rts_retries"] = s.TxRtsRetries.Val - f["tx_success"] = s.TxSuccess.Val - f["tx_total"] = s.TxTotal.Val - f["tx_tcp_goodbytes"] = s.TxTCPStats.Goodbytes.Val - f["tx_tcp_lat_avg"] = s.TxTCPStats.LatAvg.Val - f["tx_tcp_lat_max"] = s.TxTCPStats.LatMax.Val - f["tx_tcp_lat_min"] = s.TxTCPStats.LatMin.Val - f["rx_tcp_goodbytes"] = s.RxTCPStats.Goodbytes.Val - f["rx_tcp_lat_avg"] = s.RxTCPStats.LatAvg.Val - f["rx_tcp_lat_max"] = s.RxTCPStats.LatMax.Val - f["rx_tcp_lat_min"] = s.RxTCPStats.LatMin.Val - f["wifi_tx_latency_mov_avg"] = s.WifiTxLatencyMov.Avg.Val - f["wifi_tx_latency_mov_max"] = s.WifiTxLatencyMov.Max.Val - f["wifi_tx_latency_mov_min"] = s.WifiTxLatencyMov.Min.Val - f["wifi_tx_latency_mov_total"] = s.WifiTxLatencyMov.Total.Val - f["wifi_tx_latency_mov_cuont"] = s.WifiTxLatencyMov.TotalCount.Val - - // XXX: This is busted. It needs its own table.... - for _, p := range rt { - if p.Name != s.RadioName { - continue - } - t["channel"] = p.Channel.Txt - t["radio"] = p.Radio - f["current_antenna_gain"] = p.CurrentAntennaGain.Val - f["ht"] = p.Ht.Txt - f["max_txpower"] = p.MaxTxpower.Val - f["min_txpower"] = p.MinTxpower.Val - f["nss"] = p.Nss.Val - f["radio_caps"] = p.RadioCaps.Val - f["tx_power"] = p.TxPower.Val + tags := map[string]string{ + "device_name": t["name"], + "site_name": t["site_name"], + "ap_mac": s.ApMac, + "bssid": s.Bssid, + "id": s.ID, + "name": s.Name, + "radio_name": s.RadioName, + "essid": s.Essid, + "site_id": s.SiteID, + "usage": s.Usage, + "state": s.State, + "is_guest": s.IsGuest.Txt, } - - for _, p := range rts { - if p.Name != s.RadioName { - continue - } - f["ast_be_xmit"] = p.AstBeXmit.Val - f["channel"] = p.Channel.Val - f["cu_self_rx"] = p.CuSelfRx.Val - f["cu_self_tx"] = p.CuSelfTx.Val - f["cu_total"] = p.CuTotal.Val - f["extchannel"] = p.Extchannel.Val - f["gain"] = p.Gain.Val - f["guest-num_sta"] = p.GuestNumSta.Val - f["num_sta"] = p.NumSta.Val - f["radio"] = p.Radio - f["tx_packets"] = p.TxPackets.Val - f["tx_power"] = p.TxPower.Val - f["tx_retries"] = p.TxRetries.Val - f["user-num_sta"] = p.UserNumSta.Val + fields := map[string]interface{}{ + "ccq": s.Ccq, + "mac_filter_rejections": s.MacFilterRejections, + "num_satisfaction_sta": s.NumSatisfactionSta.Val, + "avg_client_signal": s.AvgClientSignal.Val, + "satisfaction": s.Satisfaction.Val, + "satisfaction_now": s.SatisfactionNow.Val, + "rx_bytes": s.RxBytes.Val, + "rx_crypts": s.RxCrypts.Val, + "rx_dropped": s.RxDropped.Val, + "rx_errors": s.RxErrors.Val, + "rx_frags": s.RxFrags.Val, + "rx_nwids": s.RxNwids.Val, + "rx_packets": s.RxPackets.Val, + "tx_bytes": s.TxBytes.Val, + "tx_dropped": s.TxDropped.Val, + "tx_errors": s.TxErrors.Val, + "tx_packets": s.TxPackets.Val, + "tx_power": s.TxPower.Val, + "tx_retries": s.TxRetries.Val, + "tx_combined_retries": s.TxCombinedRetries.Val, + "tx_data_mpdu_bytes": s.TxDataMpduBytes.Val, + "tx_rts_retries": s.TxRtsRetries.Val, + "tx_success": s.TxSuccess.Val, + "tx_total": s.TxTotal.Val, + "tx_tcp_goodbytes": s.TxTCPStats.Goodbytes.Val, + "tx_tcp_lat_avg": s.TxTCPStats.LatAvg.Val, + "tx_tcp_lat_max": s.TxTCPStats.LatMax.Val, + "tx_tcp_lat_min": s.TxTCPStats.LatMin.Val, + "rx_tcp_goodbytes": s.RxTCPStats.Goodbytes.Val, + "rx_tcp_lat_avg": s.RxTCPStats.LatAvg.Val, + "rx_tcp_lat_max": s.RxTCPStats.LatMax.Val, + "rx_tcp_lat_min": s.RxTCPStats.LatMin.Val, + "wifi_tx_latency_mov_avg": s.WifiTxLatencyMov.Avg.Val, + "wifi_tx_latency_mov_max": s.WifiTxLatencyMov.Max.Val, + "wifi_tx_latency_mov_min": s.WifiTxLatencyMov.Min.Val, + "wifi_tx_latency_mov_total": s.WifiTxLatencyMov.Total.Val, + "wifi_tx_latency_mov_cuont": s.WifiTxLatencyMov.TotalCount.Val, } - r.send(&metric{Table: "uap_vaps", Tags: t, Fields: f}) + r.send(&metric{Table: "uap_vaps", Tags: tags, Fields: fields}) + } +} + +func (u *InfluxUnifi) processRadTable(r report, t map[string]string, rt unifi.RadioTable, rts unifi.RadioTableStats) { + for _, p := range rt { + tags := map[string]string{ + "device_name": t["name"], + "site_name": t["site_name"], + "channel": p.Channel.Txt, + "radio": p.Radio, + } + fields := map[string]interface{}{ + "current_antenna_gain": p.CurrentAntennaGain.Val, + "ht": p.Ht.Txt, + "max_txpower": p.MaxTxpower.Val, + "min_txpower": p.MinTxpower.Val, + "nss": p.Nss.Val, + "radio_caps": p.RadioCaps.Val, + } + for _, t := range rts { + if t.Name == p.Name { + fields["ast_be_xmit"] = t.AstBeXmit.Val + fields["channel"] = t.Channel.Val + fields["cu_self_rx"] = t.CuSelfRx.Val + fields["cu_self_tx"] = t.CuSelfTx.Val + fields["cu_total"] = t.CuTotal.Val + fields["extchannel"] = t.Extchannel.Val + fields["gain"] = t.Gain.Val + fields["guest-num_sta"] = t.GuestNumSta.Val + fields["num_sta"] = t.NumSta.Val + fields["radio"] = t.Radio + fields["tx_packets"] = t.TxPackets.Val + fields["tx_power"] = t.TxPower.Val + fields["tx_retries"] = t.TxRetries.Val + fields["user-num_sta"] = t.UserNumSta.Val + break + } + } + r.send(&metric{Table: "uap_radios", Tags: tags, Fields: fields}) } } diff --git a/pkg/influxunifi/udm.go b/pkg/influxunifi/udm.go index cbe43f1f..c88eed34 100644 --- a/pkg/influxunifi/udm.go +++ b/pkg/influxunifi/udm.go @@ -74,7 +74,7 @@ func (u *InfluxUnifi) batchUDM(r report, s *unifi.UDM) { "lan-tx_packets": s.Stat.Gw.LanTxPackets.Val, }, u.batchSysStats(s.SysStats, s.SystemStats)) r.send(&metric{Table: "usg", Tags: tags, Fields: fields}) - u.batchNetworkTable(r, tags, s.NetworkTable) + u.batchNetTable(r, tags, s.NetworkTable) u.batchUSGwans(r, tags, s.Wan1, s.Wan2) tags = map[string]string{ @@ -136,5 +136,6 @@ func (u *InfluxUnifi) batchUDM(r report, s *unifi.UDM) { fields["guest-num_sta"] = int(s.GuestNumSta.Val) fields["num_sta"] = s.NumSta.Val r.send(&metric{Table: "uap", Tags: tags, Fields: fields}) - u.processVAPs(r, tags, *s.VapTable, *s.RadioTable, *s.RadioTableStats) + u.processRadTable(r, tags, *s.RadioTable, *s.RadioTableStats) + u.processVAPTable(r, tags, *s.VapTable) } diff --git a/pkg/influxunifi/usg.go b/pkg/influxunifi/usg.go index db3df2b7..420f24d0 100644 --- a/pkg/influxunifi/usg.go +++ b/pkg/influxunifi/usg.go @@ -19,7 +19,7 @@ func (u *InfluxUnifi) batchUSG(r report, s *unifi.USG) { "serial": s.Serial, "type": s.Type, } - fields := map[string]interface{}{ + fields := Combine(map[string]interface{}{ "ip": s.IP, "bytes": s.Bytes.Val, "last_seen": s.LastSeen.Val, @@ -33,6 +33,7 @@ func (u *InfluxUnifi) batchUSG(r report, s *unifi.USG) { "version": s.Version, "num_desktop": s.NumDesktop.Val, "num_handheld": s.NumHandheld.Val, + "uplink_latency": s.Uplink.Latency.Val, "num_mobile": s.NumMobile.Val, "speedtest-status_latency": s.SpeedtestStatus.Latency.Val, "speedtest-status_runtime": s.SpeedtestStatus.Runtime.Val, @@ -43,7 +44,10 @@ func (u *InfluxUnifi) batchUSG(r report, s *unifi.USG) { "lan-rx_packets": s.Stat.Gw.LanRxPackets.Val, "lan-tx_bytes": s.Stat.Gw.LanTxBytes.Val, "lan-tx_packets": s.Stat.Gw.LanTxPackets.Val, - } + }, u.batchSysStats(s.SysStats, s.SystemStats)) + r.send(&metric{Table: "usg", Tags: tags, Fields: fields}) + u.batchNetTable(r, tags, s.NetworkTable) + u.batchUSGwans(r, tags, s.Wan1, s.Wan2) /* for _, p := range s.PortTable { t := map[string]string{ @@ -73,10 +77,6 @@ func (u *InfluxUnifi) batchUSG(r report, s *unifi.USG) { r.send(&metric{Table: "usg_ports", Tags: t, Fields: f}) } */ - fields = Combine(fields, u.batchSysStats(s.SysStats, s.SystemStats)) - r.send(&metric{Table: "usg", Tags: tags, Fields: fields}) - u.batchNetworkTable(r, tags, s.NetworkTable) - u.batchUSGwans(r, tags, s.Wan1, s.Wan2) } func (u *InfluxUnifi) batchUSGwans(r report, tags map[string]string, wans ...unifi.Wan) { @@ -87,27 +87,26 @@ func (u *InfluxUnifi) batchUSGwans(r report, tags map[string]string, wans ...uni tags := map[string]string{ "device_name": tags["name"], "site_name": tags["site_name"], - "wan_name": wan.Name, + "ip": wan.IP, + "purpose": wan.Name, + "mac": wan.Mac, + "ifname": wan.Ifname, + "type": wan.Type, + "up": wan.Up.Txt, + "enabled": wan.Enable.Txt, } fields := map[string]interface{}{ "bytes-r": wan.BytesR.Val, - "enable": wan.Enable.Val, "full_duplex": wan.FullDuplex.Val, "gateway": wan.Gateway, - "ifname": wan.Ifname, - "ip": wan.IP, - "mac": wan.Mac, "max_speed": wan.MaxSpeed.Val, - "name": wan.Name, "rx_bytes": wan.RxBytes.Val, "rx_bytes-r": wan.RxBytesR.Val, "rx_dropped": wan.RxDropped.Val, "rx_errors": wan.RxErrors.Val, "rx_multicast": wan.RxMulticast.Val, "rx_packets": wan.RxPackets.Val, - "type": wan.Type, "speed": wan.Speed.Val, - "up": wan.Up.Val, "tx_bytes": wan.TxBytes.Val, "tx_bytes-r": wan.TxBytesR.Val, "tx_dropped": wan.TxDropped.Val, @@ -118,7 +117,7 @@ func (u *InfluxUnifi) batchUSGwans(r report, tags map[string]string, wans ...uni } } -func (u *InfluxUnifi) batchNetworkTable(r report, tags map[string]string, nt unifi.NetworkTable) { +func (u *InfluxUnifi) batchNetTable(r report, tags map[string]string, nt unifi.NetworkTable) { for _, p := range nt { tags := map[string]string{ "device_name": tags["name"], @@ -130,6 +129,7 @@ func (u *InfluxUnifi) batchNetworkTable(r report, tags map[string]string, nt uni "name": p.Name, "domain_name": p.DomainName, "purpose": p.Purpose, + "is_guest": p.IsGuest.Txt, } fields := map[string]interface{}{ "num_sta": p.NumSta.Val, diff --git a/pkg/influxunifi/usw.go b/pkg/influxunifi/usw.go index ce669ca1..a62f5f81 100644 --- a/pkg/influxunifi/usw.go +++ b/pkg/influxunifi/usw.go @@ -48,19 +48,19 @@ func (u *InfluxUnifi) batchUSW(r report, s *unifi.USW) { u.batchPortTable(r, tags, s.PortTable) } -func (u *InfluxUnifi) batchPortTable(r report, tags map[string]string, pt []unifi.Port) { +func (u *InfluxUnifi) batchPortTable(r report, t map[string]string, pt []unifi.Port) { for _, p := range pt { if !p.Up.Val || !p.Enable.Val { continue // only record UP ports. } tags := map[string]string{ - "site_name": tags["site_name"], - "device_name": tags["name"], + "site_name": t["site_name"], + "device_name": t["name"], "name": p.Name, "poe_mode": p.PoeMode, "port_poe": p.PortPoe.Txt, "port_idx": p.PortIdx.Txt, - "port_id": tags["name"] + " Port " + p.PortIdx.Txt, + "port_id": t["name"] + " Port " + p.PortIdx.Txt, "poe_enable": p.PoeEnable.Txt, "flowctrl_rx": p.FlowctrlRx.Txt, "flowctrl_tx": p.FlowctrlTx.Txt, diff --git a/pkg/poller/influx.go b/pkg/poller/influx.go index 6dbc15c3..2abd83ad 100644 --- a/pkg/poller/influx.go +++ b/pkg/poller/influx.go @@ -9,6 +9,9 @@ import ( // GetInfluxDB returns an InfluxDB interface. func (u *UnifiPoller) GetInfluxDB() (err error) { + if u.Influx != nil { + return nil + } u.Influx, err = influxunifi.New(&influxunifi.Config{ Database: u.Config.InfluxDB, User: u.Config.InfluxUser, @@ -29,6 +32,9 @@ func (u *UnifiPoller) GetInfluxDB() (err error) { // determine if there was a read or write error and act on it. This is currently // called in two places in this library. One returns an error, one does not. func (u *UnifiPoller) CollectAndProcess() error { + if err := u.GetInfluxDB(); err != nil { + return err + } metrics, err := u.CollectMetrics() if err != nil { return err diff --git a/pkg/poller/start.go b/pkg/poller/start.go index ea68ba0b..1e1719c8 100644 --- a/pkg/poller/start.go +++ b/pkg/poller/start.go @@ -100,43 +100,52 @@ func (u *UnifiPoller) Run() error { switch strings.ToLower(u.Config.Mode) { default: - if err := u.GetInfluxDB(); err != nil { - return err - } return u.PollController() - case "influxlambda", "lambdainflux", "lambda_influx", "influx_lambda": - if err := u.GetInfluxDB(); err != nil { - return err - } u.LastCheck = time.Now() return u.CollectAndProcess() - case "prometheus", "exporter": return u.RunPrometheus() + case "both": + return u.RunBoth() } } +// RunBoth starts the prometheus exporter and influxdb exporter at the same time. +// This will likely double the amount of polls your controller receives. +func (u *UnifiPoller) RunBoth() error { + e := make(chan error) + defer close(e) + go func() { + e <- u.RunPrometheus() + }() + go func() { + e <- u.PollController() + }() + // If either method returns an error (even nil), bail out. + return <-e +} + // PollController runs forever, polling UniFi and pushing to InfluxDB -// This is started by Run() after everything checks out. +// This is started by Run() or RunBoth() after everything checks out. func (u *UnifiPoller) PollController() error { interval := u.Config.Interval.Round(time.Second) log.Printf("[INFO] Everything checks out! Poller started, interval: %v", interval) ticker := time.NewTicker(interval) defer ticker.Stop() + for u.LastCheck = range ticker.C { - var err error + // Some users need to re-auth every interval because the cookie times out. if u.Config.ReAuth { u.LogDebugf("Re-authenticating to UniFi Controller") - // Some users need to re-auth every interval because the cookie times out. - if err = u.Unifi.Login(); err != nil { - u.LogError(err, "re-authenticating") + if err := u.Unifi.Login(); err != nil { + return err } } - if err == nil { - // Only run this if the authentication procedure didn't return error. - _ = u.CollectAndProcess() + if err := u.CollectAndProcess(); err != nil { + return err } + // check for errors from the unifi polls. if u.errorCount > 0 { return fmt.Errorf("too many errors, stopping poller") } From dc9abc8ca845155da8f228aeed8426caf2593621 Mon Sep 17 00:00:00 2001 From: davidnewhall2 Date: Sun, 1 Dec 2019 03:26:13 -0800 Subject: [PATCH 08/10] more fixes --- pkg/influxunifi/uap.go | 1 - pkg/influxunifi/usg.go | 1 + pkg/promunifi/site.go | 2 +- pkg/promunifi/udm.go | 2 +- pkg/promunifi/usg.go | 10 ++++++++-- 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/pkg/influxunifi/uap.go b/pkg/influxunifi/uap.go index 81d4be17..94ca7e1f 100644 --- a/pkg/influxunifi/uap.go +++ b/pkg/influxunifi/uap.go @@ -33,7 +33,6 @@ func (u *InfluxUnifi) batchUAP(r report, s *unifi.UAP) { r.send(&metric{Table: "uap", Tags: tags, Fields: fields}) u.processRadTable(r, tags, s.RadioTable, s.RadioTableStats) u.processVAPTable(r, tags, s.VapTable) - } func (u *InfluxUnifi) processUAPstats(ap *unifi.Ap) map[string]interface{} { diff --git a/pkg/influxunifi/usg.go b/pkg/influxunifi/usg.go index 420f24d0..57fdad4f 100644 --- a/pkg/influxunifi/usg.go +++ b/pkg/influxunifi/usg.go @@ -34,6 +34,7 @@ func (u *InfluxUnifi) batchUSG(r report, s *unifi.USG) { "num_desktop": s.NumDesktop.Val, "num_handheld": s.NumHandheld.Val, "uplink_latency": s.Uplink.Latency.Val, + "uplink_speed": s.Uplink.Speed.Val, "num_mobile": s.NumMobile.Val, "speedtest-status_latency": s.SpeedtestStatus.Latency.Val, "speedtest-status_runtime": s.SpeedtestStatus.Runtime.Val, diff --git a/pkg/promunifi/site.go b/pkg/promunifi/site.go index 0acc3cec..5d7ff9c3 100644 --- a/pkg/promunifi/site.go +++ b/pkg/promunifi/site.go @@ -72,7 +72,7 @@ func (u *promUnifi) exportSite(r report, s *unifi.Site) { r.send([]*metric{ {u.Site.TxBytesR, prometheus.GaugeValue, h.TxBytesR, labels}, {u.Site.RxBytesR, prometheus.GaugeValue, h.RxBytesR, labels}, - {u.Site.Uptime, prometheus.GaugeValue, h.Latency, labels}, + {u.Site.Uptime, prometheus.GaugeValue, h.Uptime, labels}, {u.Site.Latency, prometheus.GaugeValue, h.Latency.Val / 1000, labels}, {u.Site.XputUp, prometheus.GaugeValue, h.XputUp, labels}, {u.Site.XputDown, prometheus.GaugeValue, h.XputDown, labels}, diff --git a/pkg/promunifi/udm.go b/pkg/promunifi/udm.go index 9a17b41b..f7c80f13 100644 --- a/pkg/promunifi/udm.go +++ b/pkg/promunifi/udm.go @@ -96,7 +96,7 @@ func (u *promUnifi) exportUDM(r report, d *unifi.UDM) { u.exportUSWstats(r, labels, d.Stat.Sw) u.exportPortTable(r, labels, d.PortTable) // Gateway Data - u.exportUSGstats(r, labels, d.Stat.Gw, d.SpeedtestStatus) + u.exportUSGstats(r, labels, d.Stat.Gw, d.SpeedtestStatus, d.Uplink) u.exportWANPorts(r, labels, d.Wan1, d.Wan2) // Wireless Data - UDM (non-pro) only if d.Stat.Ap != nil && d.VapTable != nil { diff --git a/pkg/promunifi/usg.go b/pkg/promunifi/usg.go index b8764522..2aaa6e26 100644 --- a/pkg/promunifi/usg.go +++ b/pkg/promunifi/usg.go @@ -28,6 +28,8 @@ type usg struct { WanTxMulticast *prometheus.Desc WanBytesR *prometheus.Desc Latency *prometheus.Desc + UplinkLatency *prometheus.Desc + UplinkSpeed *prometheus.Desc Runtime *prometheus.Desc XputDownload *prometheus.Desc XputUpload *prometheus.Desc @@ -60,6 +62,8 @@ func descUSG(ns string) *usg { LanTxPackets: prometheus.NewDesc(ns+"lan_transmit_packets_total", "LAN Transmit Packets Total", labels, nil), LanTxBytes: prometheus.NewDesc(ns+"lan_transmit_bytes_total", "LAN Transmit Bytes Total", labels, nil), Latency: prometheus.NewDesc(ns+"speedtest_latency_seconds", "Speedtest Latency", labels, nil), + UplinkLatency: prometheus.NewDesc(ns+"uplink_latency_seconds", "Uplink Latency", labels, nil), + UplinkSpeed: prometheus.NewDesc(ns+"uplink_speed_mbps", "Uplink Speed", labels, nil), Runtime: prometheus.NewDesc(ns+"speedtest_runtime", "Speedtest Run Time", labels, nil), XputDownload: prometheus.NewDesc(ns+"speedtest_download", "Speedtest Download Rate", labels, nil), XputUpload: prometheus.NewDesc(ns+"speedtest_upload", "Speedtest Upload Rate", labels, nil), @@ -90,10 +94,10 @@ func (u *promUnifi) exportUSG(r report, d *unifi.USG) { {u.Device.Mem, prometheus.GaugeValue, d.SystemStats.Mem, labels}, }) u.exportWANPorts(r, labels, d.Wan1, d.Wan2) - u.exportUSGstats(r, labels, d.Stat.Gw, d.SpeedtestStatus) + u.exportUSGstats(r, labels, d.Stat.Gw, d.SpeedtestStatus, d.Uplink) } -func (u *promUnifi) exportUSGstats(r report, labels []string, gw *unifi.Gw, st unifi.SpeedtestStatus) { +func (u *promUnifi) exportUSGstats(r report, labels []string, gw *unifi.Gw, st unifi.SpeedtestStatus, ul unifi.Uplink) { labelLan := []string{"lan", labels[6], labels[7]} labelWan := []string{"all", labels[6], labels[7]} r.send([]*metric{ @@ -110,6 +114,8 @@ func (u *promUnifi) exportUSGstats(r report, labels []string, gw *unifi.Gw, st u {u.USG.LanTxPackets, prometheus.CounterValue, gw.LanTxPackets, labelLan}, {u.USG.LanTxBytes, prometheus.CounterValue, gw.LanTxBytes, labelLan}, {u.USG.LanRxDropped, prometheus.CounterValue, gw.LanRxDropped, labelLan}, + {u.USG.UplinkLatency, prometheus.GaugeValue, ul.Latency.Val / 1000, labelWan}, + {u.USG.UplinkSpeed, prometheus.GaugeValue, ul.Speed, labelWan}, // Speed Test Stats {u.USG.Latency, prometheus.GaugeValue, st.Latency.Val / 1000, labelWan}, {u.USG.Runtime, prometheus.GaugeValue, st.Runtime, labelWan}, From 32c11072695660528d6bf3f8c94a3d1f677c3fa3 Mon Sep 17 00:00:00 2001 From: davidnewhall2 Date: Sun, 1 Dec 2019 14:03:27 -0800 Subject: [PATCH 09/10] add a few missing metrics --- pkg/influxunifi/usg.go | 4 ++++ pkg/promunifi/uap.go | 10 +++++----- pkg/promunifi/usw.go | 1 + 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/pkg/influxunifi/usg.go b/pkg/influxunifi/usg.go index 57fdad4f..74add993 100644 --- a/pkg/influxunifi/usg.go +++ b/pkg/influxunifi/usg.go @@ -45,6 +45,7 @@ func (u *InfluxUnifi) batchUSG(r report, s *unifi.USG) { "lan-rx_packets": s.Stat.Gw.LanRxPackets.Val, "lan-tx_bytes": s.Stat.Gw.LanTxBytes.Val, "lan-tx_packets": s.Stat.Gw.LanTxPackets.Val, + "lan-rx_dropped": s.Stat.Gw.LanRxDropped.Val, }, u.batchSysStats(s.SysStats, s.SystemStats)) r.send(&metric{Table: "usg", Tags: tags, Fields: fields}) u.batchNetTable(r, tags, s.NetworkTable) @@ -105,6 +106,7 @@ func (u *InfluxUnifi) batchUSGwans(r report, tags map[string]string, wans ...uni "rx_bytes-r": wan.RxBytesR.Val, "rx_dropped": wan.RxDropped.Val, "rx_errors": wan.RxErrors.Val, + "rx_broadcast": wan.RxBroadcast.Val, "rx_multicast": wan.RxMulticast.Val, "rx_packets": wan.RxPackets.Val, "speed": wan.Speed.Val, @@ -113,6 +115,8 @@ func (u *InfluxUnifi) batchUSGwans(r report, tags map[string]string, wans ...uni "tx_dropped": wan.TxDropped.Val, "tx_errors": wan.TxErrors.Val, "tx_packets": wan.TxPackets.Val, + "tx_broadcast": wan.TxBroadcast.Val, + "tx_multicast": wan.TxMulticast.Val, } r.send(&metric{Table: "usg_wan_ports", Tags: tags, Fields: fields}) } diff --git a/pkg/promunifi/uap.go b/pkg/promunifi/uap.go index ed8507df..676e3ad3 100644 --- a/pkg/promunifi/uap.go +++ b/pkg/promunifi/uap.go @@ -152,16 +152,16 @@ func descUAP(ns string) *uap { RadioTxPower: prometheus.NewDesc(ns+"radio_transmit_power", "Radio Transmit Power", labelR, nil), RadioAstBeXmit: prometheus.NewDesc(ns+"radio_ast_be_xmit", "Radio AstBe Transmit", labelR, nil), RadioChannel: prometheus.NewDesc(ns+"radio_channel", "Radio Channel", labelR, nil), - RadioCuSelfRx: prometheus.NewDesc(ns+"radio_channel_utilization_receive", "Radio Channel Utilization Receive", labelR, nil), - RadioCuSelfTx: prometheus.NewDesc(ns+"radio_channel_utilization_transmit", "Radio Channel Utilization Transmit", labelR, nil), - RadioCuTotal: prometheus.NewDesc(ns+"radio_channel_utilization_total", "Radio Channel Utilization", labelR, nil), + RadioCuSelfRx: prometheus.NewDesc(ns+"radio_channel_utilization_receive_percent", "Radio Channel Utilization Receive", labelR, nil), + RadioCuSelfTx: prometheus.NewDesc(ns+"radio_channel_utilization_transmit_percent", "Radio Channel Utilization Transmit", labelR, nil), + RadioCuTotal: prometheus.NewDesc(ns+"radio_channel_utilization_percent", "Radio Channel Utilization", labelR, nil), RadioExtchannel: prometheus.NewDesc(ns+"radio_ext_channel", "Radio Ext Channel", labelR, nil), RadioGain: prometheus.NewDesc(ns+"radio_gain", "Radio Gain", labelR, nil), RadioGuestNumSta: prometheus.NewDesc(ns+"radio_guest_stations", "Radio Guest Station Count", labelR, nil), RadioNumSta: prometheus.NewDesc(ns+"radio_stations", "Radio Total Station Count", labelR, nil), RadioUserNumSta: prometheus.NewDesc(ns+"radio_user_stations", "Radio User Station Count", labelR, nil), - RadioTxPackets: prometheus.NewDesc(ns+"radio_transmit_packets_total", "Radio Transmitted Packets", labelR, nil), - RadioTxRetries: prometheus.NewDesc(ns+"radio_transmit_retries_total", "Radio Transmit Retries", labelR, nil), + RadioTxPackets: prometheus.NewDesc(ns+"radio_transmit_packets", "Radio Transmitted Packets", labelR, nil), + RadioTxRetries: prometheus.NewDesc(ns+"radio_transmit_retries", "Radio Transmit Retries", labelR, nil), } } diff --git a/pkg/promunifi/usw.go b/pkg/promunifi/usw.go index a02b15f4..350c3b05 100644 --- a/pkg/promunifi/usw.go +++ b/pkg/promunifi/usw.go @@ -176,6 +176,7 @@ func (u *promUnifi) exportPortTable(r report, labels []string, pt []unifi.Port) {u.USW.TxDropped, prometheus.CounterValue, p.TxDropped, labelP}, {u.USW.TxErrors, prometheus.CounterValue, p.TxErrors, labelP}, {u.USW.TxMulticast, prometheus.CounterValue, p.TxMulticast, labelP}, + {u.USW.TxPackets, prometheus.CounterValue, p.TxPackets, labelP}, }) } } From f4e55340fcf695dc85e9c5c7dd33295d9fb0052b Mon Sep 17 00:00:00 2001 From: davidnewhall2 Date: Sun, 1 Dec 2019 14:39:18 -0800 Subject: [PATCH 10/10] a couple others missing --- pkg/influxunifi/uap.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/influxunifi/uap.go b/pkg/influxunifi/uap.go index 94ca7e1f..75b47b8d 100644 --- a/pkg/influxunifi/uap.go +++ b/pkg/influxunifi/uap.go @@ -84,6 +84,7 @@ func (u *InfluxUnifi) processVAPTable(r report, t map[string]string, vt unifi.Va "id": s.ID, "name": s.Name, "radio_name": s.RadioName, + "radio": s.Radio, "essid": s.Essid, "site_id": s.SiteID, "usage": s.Usage, @@ -97,6 +98,8 @@ func (u *InfluxUnifi) processVAPTable(r report, t map[string]string, vt unifi.Va "avg_client_signal": s.AvgClientSignal.Val, "satisfaction": s.Satisfaction.Val, "satisfaction_now": s.SatisfactionNow.Val, + "num_sta": s.NumSta, + "channel": s.Channel, "rx_bytes": s.RxBytes.Val, "rx_crypts": s.RxCrypts.Val, "rx_dropped": s.RxDropped.Val,