Merge pull request #103 from davidnewhall/dn2_mv_influx
Add InfluxDB code to this app.
This commit is contained in:
commit
17cc985a50
|
|
@ -11,7 +11,7 @@ HBREPO="golift/homebrew-mugs"
|
||||||
MAINT="David Newhall II <david at sleepers dot pro>"
|
MAINT="David Newhall II <david at sleepers dot pro>"
|
||||||
VENDOR="Go Lift"
|
VENDOR="Go Lift"
|
||||||
DESC="Polls a UniFi controller and stores metrics in InfluxDB"
|
DESC="Polls a UniFi controller and stores metrics in InfluxDB"
|
||||||
GOLANGCI_LINT_ARGS="--enable-all -D gochecknoglobals"
|
GOLANGCI_LINT_ARGS="--enable-all -D gochecknoglobals -e dupl"
|
||||||
# Example must exist at examples/$CONFIG_FILE.example
|
# Example must exist at examples/$CONFIG_FILE.example
|
||||||
CONFIG_FILE="up.conf"
|
CONFIG_FILE="up.conf"
|
||||||
LICENSE="MIT"
|
LICENSE="MIT"
|
||||||
|
|
|
||||||
|
|
@ -30,12 +30,12 @@
|
||||||
version = "v1.0.3"
|
version = "v1.0.3"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:b981b3d72f49bc38f7a9856ec8fab47abeb17fdba1da4a69b0a5b5237dced54c"
|
digest = "1:356d0d631d02440e90ca29b31496b547d8e28f239eaee033fdf053c3c38d22db"
|
||||||
name = "golift.io/unifi"
|
name = "golift.io/unifi"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
pruneopts = "UT"
|
pruneopts = "UT"
|
||||||
revision = "0ac64b3ef5f855592abb1b95b062b254a184203c"
|
revision = "3f34e772e708a6cb7e838d6babb5928009bc96cc"
|
||||||
version = "v3.4.0"
|
version = "v4.0.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:4d2e5a73dc1500038e504a8d78b986630e3626dc027bc030ba5c75da257cdb96"
|
digest = "1:4d2e5a73dc1500038e504a8d78b986630e3626dc027bc030ba5c75da257cdb96"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
package unifipoller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
influx "github.com/influxdata/influxdb1-client/v2"
|
||||||
|
"golift.io/unifi"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ClientPoints 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) {
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
fields := map[string]interface{}{
|
||||||
|
"anomalies": c.Anomalies,
|
||||||
|
"ip": c.IP,
|
||||||
|
"essid": c.Essid,
|
||||||
|
"bssid": c.Bssid,
|
||||||
|
"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_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 {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return []*influx.Point{pt}, nil
|
||||||
|
}
|
||||||
|
|
@ -22,12 +22,6 @@ const (
|
||||||
defaultUnifURL = "https://127.0.0.1:8443"
|
defaultUnifURL = "https://127.0.0.1:8443"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Asset is used to give all devices and clients a common interface.
|
|
||||||
type Asset interface {
|
|
||||||
Points() ([]*influx.Point, error)
|
|
||||||
PointsAt(time.Time) ([]*influx.Point, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnifiPoller contains the application startup data, and auth info for UniFi & Influx.
|
// UnifiPoller contains the application startup data, and auth info for UniFi & Influx.
|
||||||
type UnifiPoller struct {
|
type UnifiPoller struct {
|
||||||
ConfigFile string
|
ConfigFile string
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,12 @@ import (
|
||||||
// DumpJSONPayload prints raw json from the UniFi Controller.
|
// DumpJSONPayload prints raw json from the UniFi Controller.
|
||||||
func (u *UnifiPoller) DumpJSONPayload() (err error) {
|
func (u *UnifiPoller) DumpJSONPayload() (err error) {
|
||||||
u.Quiet = true
|
u.Quiet = true
|
||||||
u.Unifi, err = unifi.NewUnifi(u.UnifiUser, u.UnifiPass, u.UnifiBase, u.VerifySSL)
|
u.Unifi, err = unifi.NewUnifi(&unifi.Config{
|
||||||
|
User: u.UnifiUser,
|
||||||
|
Pass: u.UnifiPass,
|
||||||
|
URL: u.UnifiBase,
|
||||||
|
VerifySSL: u.VerifySSL,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
package unifipoller
|
||||||
|
|
||||||
|
import (
|
||||||
|
influx "github.com/influxdata/influxdb1-client/v2"
|
||||||
|
"golift.io/unifi"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IDSPoints generates intrusion detection datapoints for InfluxDB.
|
||||||
|
// These points can be passed directly to influx.
|
||||||
|
func IDSPoints(i *unifi.IDS) ([]*influx.Point, error) {
|
||||||
|
tags := map[string]string{
|
||||||
|
"in_iface": i.InIface,
|
||||||
|
"event_type": i.EventType,
|
||||||
|
"proto": i.Proto,
|
||||||
|
"app_proto": i.AppProto,
|
||||||
|
"usgip": i.Usgip,
|
||||||
|
"country_code": i.SrcipGeo.CountryCode,
|
||||||
|
"country_name": i.SrcipGeo.CountryName,
|
||||||
|
"region": i.SrcipGeo.Region,
|
||||||
|
"city": i.SrcipGeo.City,
|
||||||
|
"postal_code": i.SrcipGeo.PostalCode,
|
||||||
|
"srcipASN": i.SrcipASN,
|
||||||
|
"usgipASN": i.UsgipASN,
|
||||||
|
"alert_category": i.InnerAlertCategory,
|
||||||
|
"subsystem": i.Subsystem,
|
||||||
|
"catname": i.Catname,
|
||||||
|
}
|
||||||
|
fields := map[string]interface{}{
|
||||||
|
"event_type": i.EventType,
|
||||||
|
"proto": i.Proto,
|
||||||
|
"app_proto": i.AppProto,
|
||||||
|
"usgip": i.Usgip,
|
||||||
|
"country_name": i.SrcipGeo.CountryName,
|
||||||
|
"city": i.SrcipGeo.City,
|
||||||
|
"postal_code": i.SrcipGeo.PostalCode,
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
package unifipoller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
influx "github.com/influxdata/influxdb1-client/v2"
|
||||||
|
"golift.io/unifi"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SitePoints 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 {
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
"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,
|
||||||
|
"nameservers": len(s.Nameservers),
|
||||||
|
"gateways": len(s.Gateways),
|
||||||
|
}
|
||||||
|
pt, err := influx.NewPoint("subsystems", tags, fields, time.Now())
|
||||||
|
if err != nil {
|
||||||
|
return points, err
|
||||||
|
}
|
||||||
|
points = append(points, pt)
|
||||||
|
}
|
||||||
|
return points, nil
|
||||||
|
}
|
||||||
|
|
@ -121,12 +121,17 @@ func (u *UnifiPoller) GetInfluxDB() (err error) {
|
||||||
// GetUnifi returns a UniFi controller interface.
|
// GetUnifi returns a UniFi controller interface.
|
||||||
func (u *UnifiPoller) GetUnifi() (err error) {
|
func (u *UnifiPoller) GetUnifi() (err error) {
|
||||||
// Create an authenticated session to the Unifi Controller.
|
// Create an authenticated session to the Unifi Controller.
|
||||||
u.Unifi, err = unifi.NewUnifi(u.UnifiUser, u.UnifiPass, u.UnifiBase, u.VerifySSL)
|
u.Unifi, err = unifi.NewUnifi(&unifi.Config{
|
||||||
|
User: u.UnifiUser,
|
||||||
|
Pass: u.UnifiPass,
|
||||||
|
URL: u.UnifiBase,
|
||||||
|
VerifySSL: u.VerifySSL,
|
||||||
|
ErrorLog: u.LogErrorf, // Log all errors.
|
||||||
|
DebugLog: u.LogDebugf, // Log debug messages.
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unifi controller: %v", err)
|
return fmt.Errorf("unifi controller: %v", err)
|
||||||
}
|
}
|
||||||
u.Unifi.ErrorLog = u.LogErrorf // Log all errors.
|
|
||||||
u.Unifi.DebugLog = u.LogDebugf // Log debug messages.
|
|
||||||
if err := u.CheckSites(); err != nil {
|
if err := u.CheckSites(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,276 @@
|
||||||
|
package unifipoller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
influx "github.com/influxdata/influxdb1-client/v2"
|
||||||
|
"golift.io/unifi"
|
||||||
|
)
|
||||||
|
|
||||||
|
// UAPPoints 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) {
|
||||||
|
tags := map[string]string{
|
||||||
|
"id": u.ID,
|
||||||
|
"mac": u.Mac,
|
||||||
|
"device_type": u.Stat.O,
|
||||||
|
"device_oid": u.Stat.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,
|
||||||
|
"isolated": u.Isolated.Txt,
|
||||||
|
"known_cfgversion": u.KnownCfgversion,
|
||||||
|
"model": u.Model,
|
||||||
|
"outdoor_mode_override": u.OutdoorModeOverride,
|
||||||
|
"serial": u.Serial,
|
||||||
|
"type": u.Type,
|
||||||
|
"vwireEnabled": u.VwireEnabled.Txt,
|
||||||
|
}
|
||||||
|
fields := map[string]interface{}{
|
||||||
|
"ip": u.IP,
|
||||||
|
"bytes": u.Bytes.Val,
|
||||||
|
"bytes_d": u.BytesD.Val,
|
||||||
|
"bytes_r": u.BytesR.Val,
|
||||||
|
"last_seen": u.LastSeen.Val,
|
||||||
|
"rx_bytes": u.RxBytes.Val,
|
||||||
|
"rx_bytes-d": u.RxBytesD.Val,
|
||||||
|
"tx_bytes": u.TxBytes.Val,
|
||||||
|
"tx_bytes-d": u.TxBytesD.Val,
|
||||||
|
"uptime": u.Uptime.Val,
|
||||||
|
"scanning": u.Scanning.Val,
|
||||||
|
"spectrum_scanning": u.SpectrumScanning.Val,
|
||||||
|
"roll_upgrade": u.Rollupgrade.Val,
|
||||||
|
"state": u.State,
|
||||||
|
"upgradable": u.Upgradable.Val,
|
||||||
|
"user-num_sta": u.UserNumSta,
|
||||||
|
"guest-num_sta": u.GuestNumSta,
|
||||||
|
"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_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,
|
||||||
|
"stat_guest-wifi0-rx_packets": u.Stat.GuestWifi0RxPackets.Val,
|
||||||
|
"stat_guest-wifi1-rx_packets": u.Stat.GuestWifi1RxPackets.Val,
|
||||||
|
"stat_user-wifi1-rx_packets": u.Stat.UserWifi1RxPackets.Val,
|
||||||
|
"stat_user-wifi0-rx_packets": u.Stat.UserWifi0RxPackets.Val,
|
||||||
|
"stat_user-rx_packets": u.Stat.UserRxPackets.Val,
|
||||||
|
"stat_guest-rx_packets": u.Stat.GuestRxPackets.Val,
|
||||||
|
"stat_wifi0-rx_packets": u.Stat.Wifi0RxPackets.Val,
|
||||||
|
"stat_wifi1-rx_packets": u.Stat.Wifi1RxPackets.Val,
|
||||||
|
"stat_rx_packets": u.Stat.RxPackets.Val,
|
||||||
|
"stat_guest-wifi0-rx_bytes": u.Stat.GuestWifi0RxBytes.Val,
|
||||||
|
"stat_guest-wifi1-rx_bytes": u.Stat.GuestWifi1RxBytes.Val,
|
||||||
|
"stat_user-wifi1-rx_bytes": u.Stat.UserWifi1RxBytes.Val,
|
||||||
|
"stat_user-wifi0-rx_bytes": u.Stat.UserWifi0RxBytes.Val,
|
||||||
|
"stat_user-rx_bytes": u.Stat.UserRxBytes.Val,
|
||||||
|
"stat_guest-rx_bytes": u.Stat.GuestRxBytes.Val,
|
||||||
|
"stat_wifi0-rx_bytes": u.Stat.Wifi0RxBytes.Val,
|
||||||
|
"stat_wifi1-rx_bytes": u.Stat.Wifi1RxBytes.Val,
|
||||||
|
"stat_rx_bytes": u.Stat.RxBytes.Val,
|
||||||
|
"stat_guest-wifi0-rx_errors": u.Stat.GuestWifi0RxErrors.Val,
|
||||||
|
"stat_guest-wifi1-rx_errors": u.Stat.GuestWifi1RxErrors.Val,
|
||||||
|
"stat_user-wifi1-rx_errors": u.Stat.UserWifi1RxErrors.Val,
|
||||||
|
"stat_user-wifi0-rx_errors": u.Stat.UserWifi0RxErrors.Val,
|
||||||
|
"stat_user-rx_errors": u.Stat.UserRxErrors.Val,
|
||||||
|
"stat_guest-rx_errors": u.Stat.GuestRxErrors.Val,
|
||||||
|
"stat_wifi0-rx_errors": u.Stat.Wifi0RxErrors.Val,
|
||||||
|
"stat_wifi1-rx_errors": u.Stat.Wifi1RxErrors.Val,
|
||||||
|
"stat_rx_errors": u.Stat.RxErrors.Val,
|
||||||
|
"stat_guest-wifi0-rx_dropped": u.Stat.GuestWifi0RxDropped.Val,
|
||||||
|
"stat_guest-wifi1-rx_dropped": u.Stat.GuestWifi1RxDropped.Val,
|
||||||
|
"stat_user-wifi1-rx_dropped": u.Stat.UserWifi1RxDropped.Val,
|
||||||
|
"stat_user-wifi0-rx_dropped": u.Stat.UserWifi0RxDropped.Val,
|
||||||
|
"stat_user-rx_dropped": u.Stat.UserRxDropped.Val,
|
||||||
|
"stat_guest-rx_dropped": u.Stat.GuestRxDropped.Val,
|
||||||
|
"stat_wifi0-rx_dropped": u.Stat.Wifi0RxDropped.Val,
|
||||||
|
"stat_wifi1-rx_dropped": u.Stat.Wifi1RxDropped.Val,
|
||||||
|
"stat_rx_dropped": u.Stat.RxDropped.Val,
|
||||||
|
"stat_guest-wifi0-rx_crypts": u.Stat.GuestWifi0RxCrypts.Val,
|
||||||
|
"stat_guest-wifi1-rx_crypts": u.Stat.GuestWifi1RxCrypts.Val,
|
||||||
|
"stat_user-wifi1-rx_crypts": u.Stat.UserWifi1RxCrypts.Val,
|
||||||
|
"stat_user-wifi0-rx_crypts": u.Stat.UserWifi0RxCrypts.Val,
|
||||||
|
"stat_user-rx_crypts": u.Stat.UserRxCrypts.Val,
|
||||||
|
"stat_guest-rx_crypts": u.Stat.GuestRxCrypts.Val,
|
||||||
|
"stat_wifi0-rx_crypts": u.Stat.Wifi0RxCrypts.Val,
|
||||||
|
"stat_wifi1-rx_crypts": u.Stat.Wifi1RxCrypts.Val,
|
||||||
|
"stat_rx_crypts": u.Stat.RxCrypts.Val,
|
||||||
|
"stat_guest-wifi0-rx_frags": u.Stat.GuestWifi0RxFrags.Val,
|
||||||
|
"stat_guest-wifi1-rx_frags": u.Stat.GuestWifi1RxFrags.Val,
|
||||||
|
"stat_user-wifi1-rx_frags": u.Stat.UserWifi1RxFrags.Val,
|
||||||
|
"stat_user-wifi0-rx_frags": u.Stat.UserWifi0RxFrags.Val,
|
||||||
|
"stat_user-rx_frags": u.Stat.UserRxFrags.Val,
|
||||||
|
"stat_guest-rx_frags": u.Stat.GuestRxFrags.Val,
|
||||||
|
"stat_wifi0-rx_frags": u.Stat.Wifi0RxFrags.Val,
|
||||||
|
"stat_wifi1-rx_frags": u.Stat.Wifi1RxFrags.Val,
|
||||||
|
"stat_rx_frags": u.Stat.RxFrags.Val,
|
||||||
|
"stat_guest-wifi0-tx_packets": u.Stat.GuestWifi0TxPackets.Val,
|
||||||
|
"stat_guest-wifi1-tx_packets": u.Stat.GuestWifi1TxPackets.Val,
|
||||||
|
"stat_user-wifi1-tx_packets": u.Stat.UserWifi1TxPackets.Val,
|
||||||
|
"stat_user-wifi0-tx_packets": u.Stat.UserWifi0TxPackets.Val,
|
||||||
|
"stat_user-tx_packets": u.Stat.UserTxPackets.Val,
|
||||||
|
"stat_guest-tx_packets": u.Stat.GuestTxPackets.Val,
|
||||||
|
"stat_wifi0-tx_packets": u.Stat.Wifi0TxPackets.Val,
|
||||||
|
"stat_wifi1-tx_packets": u.Stat.Wifi1TxPackets.Val,
|
||||||
|
"stat_tx_packets": u.Stat.TxPackets.Val,
|
||||||
|
"stat_guest-wifi0-tx_bytes": u.Stat.GuestWifi0TxBytes.Val,
|
||||||
|
"stat_guest-wifi1-tx_bytes": u.Stat.GuestWifi1TxBytes.Val,
|
||||||
|
"stat_user-wifi1-tx_bytes": u.Stat.UserWifi1TxBytes.Val,
|
||||||
|
"stat_user-wifi0-tx_bytes": u.Stat.UserWifi0TxBytes.Val,
|
||||||
|
"stat_user-tx_bytes": u.Stat.UserTxBytes.Val,
|
||||||
|
"stat_guest-tx_bytes": u.Stat.GuestTxBytes.Val,
|
||||||
|
"stat_wifi0-tx_bytes": u.Stat.Wifi0TxBytes.Val,
|
||||||
|
"stat_wifi1-tx_bytes": u.Stat.Wifi1TxBytes.Val,
|
||||||
|
"stat_tx_bytes": u.Stat.TxBytes.Val,
|
||||||
|
"stat_guest-wifi0-tx_errors": u.Stat.GuestWifi0TxErrors.Val,
|
||||||
|
"stat_guest-wifi1-tx_errors": u.Stat.GuestWifi1TxErrors.Val,
|
||||||
|
"stat_user-wifi1-tx_errors": u.Stat.UserWifi1TxErrors.Val,
|
||||||
|
"stat_user-wifi0-tx_errors": u.Stat.UserWifi0TxErrors.Val,
|
||||||
|
"stat_user-tx_errors": u.Stat.UserTxErrors.Val,
|
||||||
|
"stat_guest-tx_errors": u.Stat.GuestTxErrors.Val,
|
||||||
|
"stat_wifi0-tx_errors": u.Stat.Wifi0TxErrors.Val,
|
||||||
|
"stat_wifi1-tx_errors": u.Stat.Wifi1TxErrors.Val,
|
||||||
|
"stat_tx_errors": u.Stat.TxErrors.Val,
|
||||||
|
"stat_guest-wifi0-tx_dropped": u.Stat.GuestWifi0TxDropped.Val,
|
||||||
|
"stat_guest-wifi1-tx_dropped": u.Stat.GuestWifi1TxDropped.Val,
|
||||||
|
"stat_user-wifi1-tx_dropped": u.Stat.UserWifi1TxDropped.Val,
|
||||||
|
"stat_user-wifi0-tx_dropped": u.Stat.UserWifi0TxDropped.Val,
|
||||||
|
"stat_user-tx_dropped": u.Stat.UserTxDropped.Val,
|
||||||
|
"stat_guest-tx_dropped": u.Stat.GuestTxDropped.Val,
|
||||||
|
"stat_wifi0-tx_dropped": u.Stat.Wifi0TxDropped.Val,
|
||||||
|
"stat_wifi1-tx_dropped": u.Stat.Wifi1TxDropped.Val,
|
||||||
|
"stat_tx_dropped": u.Stat.TxDropped.Val,
|
||||||
|
"stat_guest-wifi0-tx_retries": u.Stat.GuestWifi0TxRetries.Val,
|
||||||
|
"stat_guest-wifi1-tx_retries": u.Stat.GuestWifi1TxRetries.Val,
|
||||||
|
"stat_user-wifi1-tx_retries": u.Stat.UserWifi1TxRetries.Val,
|
||||||
|
"stat_user-wifi0-tx_retries": u.Stat.UserWifi0TxRetries.Val,
|
||||||
|
"stat_user-tx_retries": u.Stat.UserTxRetries.Val,
|
||||||
|
"stat_guest-tx_retries": u.Stat.GuestTxRetries.Val,
|
||||||
|
"stat_wifi0-tx_retries": u.Stat.Wifi0TxRetries.Val,
|
||||||
|
"stat_wifi1-tx_retries": u.Stat.Wifi1TxRetries.Val,
|
||||||
|
}
|
||||||
|
pt, err := influx.NewPoint("uap", tags, fields, now)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
points := []*influx.Point{pt}
|
||||||
|
|
||||||
|
tags = make(map[string]string)
|
||||||
|
fields = make(map[string]interface{})
|
||||||
|
// Loop each virtual AP (ESSID) and extract data for it
|
||||||
|
// from radio_tables and radio_table_stats.
|
||||||
|
for _, s := range u.VapTable {
|
||||||
|
tags["device_name"] = u.Name
|
||||||
|
tags["device_id"] = u.ID
|
||||||
|
tags["device_mac"] = u.Mac
|
||||||
|
tags["site_name"] = u.SiteName
|
||||||
|
tags["ap_mac"] = s.ApMac
|
||||||
|
tags["bssid"] = s.Bssid
|
||||||
|
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
|
||||||
|
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
|
||||||
|
|
||||||
|
for _, p := range u.RadioTable {
|
||||||
|
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
|
||||||
|
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
|
||||||
|
fields["tx_power"] = p.TxPower.Val
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range u.RadioTableStats {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
pt, err := influx.NewPoint("uap_vaps", tags, fields, now)
|
||||||
|
if err != nil {
|
||||||
|
return points, err
|
||||||
|
}
|
||||||
|
points = append(points, pt)
|
||||||
|
}
|
||||||
|
return points, nil
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,319 @@
|
||||||
|
package unifipoller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
influx "github.com/influxdata/influxdb1-client/v2"
|
||||||
|
"golift.io/unifi"
|
||||||
|
)
|
||||||
|
|
||||||
|
// UDMPoints 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) {
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
"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,
|
||||||
|
}
|
||||||
|
pt, err := influx.NewPoint("usg", tags, fields, now)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
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_priority": u.StpPriority,
|
||||||
|
"stp_version": u.StpVersion,
|
||||||
|
}
|
||||||
|
fields = map[string]interface{}{
|
||||||
|
"fw_caps": u.FwCaps.Val,
|
||||||
|
"guest-num_sta": u.GuestNumSta.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.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,
|
||||||
|
"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": "0",
|
||||||
|
}
|
||||||
|
pt, err = influx.NewPoint("usw", tags, fields, now)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
points = append(points, 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,
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
pt, err = influx.NewPoint("usg_networks", tags, fields, now)
|
||||||
|
if err != nil {
|
||||||
|
return points, err
|
||||||
|
}
|
||||||
|
points = append(points, 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,
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
"full_duplex": p.FullDuplex.Val,
|
||||||
|
}
|
||||||
|
pt, err = influx.NewPoint("usw_ports", tags, fields, now)
|
||||||
|
if err != nil {
|
||||||
|
return points, err
|
||||||
|
}
|
||||||
|
points = append(points, pt)
|
||||||
|
}
|
||||||
|
return points, nil
|
||||||
|
}
|
||||||
|
|
@ -51,7 +51,7 @@ func (u *UnifiPoller) PollController() error {
|
||||||
var err error
|
var err error
|
||||||
if u.ReAuth {
|
if u.ReAuth {
|
||||||
// Some users need to re-auth every interval because the cookie times out.
|
// Some users need to re-auth every interval because the cookie times out.
|
||||||
if err = u.GetUnifi(); err != nil {
|
if err = u.Login(); err != nil {
|
||||||
u.LogError(err, "re-authenticating")
|
u.LogError(err, "re-authenticating")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -167,44 +167,47 @@ func (u *UnifiPoller) ReportMetrics(metrics *Metrics) error {
|
||||||
// we just log the errors and tally them on a counter. In reality, this never
|
// 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
|
// 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!
|
// still check&log it in case the data going is skewed up and causes errors!
|
||||||
func (m *Metrics) ProcessPoints() (errs []error) {
|
func (m *Metrics) ProcessPoints() []error {
|
||||||
for _, asset := range m.Sites {
|
errs := []error{}
|
||||||
errs = append(errs, m.processPoints(asset))
|
processPoints := func(m *Metrics, p []*influx.Point, err error) error {
|
||||||
}
|
if err != nil || p == nil {
|
||||||
for _, asset := range m.Clients {
|
|
||||||
errs = append(errs, m.processPoints(asset))
|
|
||||||
}
|
|
||||||
for _, asset := range m.IDSList {
|
|
||||||
errs = append(errs, m.processPoints(asset))
|
|
||||||
}
|
|
||||||
if m.Devices == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for _, asset := range m.UAPs {
|
|
||||||
errs = append(errs, m.processPoints(asset))
|
|
||||||
}
|
|
||||||
for _, asset := range m.USGs {
|
|
||||||
errs = append(errs, m.processPoints(asset))
|
|
||||||
}
|
|
||||||
for _, asset := range m.USWs {
|
|
||||||
errs = append(errs, m.processPoints(asset))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// processPoints is helper function for ProcessPoints.
|
|
||||||
func (m *Metrics) processPoints(asset Asset) error {
|
|
||||||
if asset == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
points, err := asset.PointsAt(m.TS)
|
|
||||||
if err != nil || points == nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
m.BatchPoints.AddPoints(points)
|
m.BatchPoints.AddPoints(p)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, asset := range m.Sites {
|
||||||
|
pts, err := SitePoints(asset, m.TS)
|
||||||
|
errs = append(errs, processPoints(m, pts, err))
|
||||||
|
}
|
||||||
|
for _, asset := range m.Clients {
|
||||||
|
pts, err := ClientPoints(asset, m.TS)
|
||||||
|
errs = append(errs, processPoints(m, pts, err))
|
||||||
|
}
|
||||||
|
for _, asset := range m.IDSList {
|
||||||
|
pts, err := IDSPoints(asset) // no m.TS.
|
||||||
|
errs = append(errs, processPoints(m, pts, err))
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.Devices == nil {
|
||||||
|
return errs
|
||||||
|
}
|
||||||
|
for _, asset := range m.UAPs {
|
||||||
|
pts, err := UAPPoints(asset, m.TS)
|
||||||
|
errs = append(errs, processPoints(m, pts, err))
|
||||||
|
}
|
||||||
|
for _, asset := range m.USGs {
|
||||||
|
pts, err := USGPoints(asset, m.TS)
|
||||||
|
errs = append(errs, processPoints(m, pts, err))
|
||||||
|
}
|
||||||
|
for _, asset := range m.USWs {
|
||||||
|
pts, err := USWPoints(asset, m.TS)
|
||||||
|
errs = append(errs, processPoints(m, pts, err))
|
||||||
|
}
|
||||||
|
return errs
|
||||||
|
}
|
||||||
|
|
||||||
// GetFilteredSites returns a list of sites to fetch data for.
|
// GetFilteredSites returns a list of sites to fetch data for.
|
||||||
// Omits requested but unconfigured sites. Grabs the full list from the
|
// Omits requested but unconfigured sites. Grabs the full list from the
|
||||||
// controller and returns the sites provided in the config file.
|
// controller and returns the sites provided in the config file.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,228 @@
|
||||||
|
package unifipoller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
influx "github.com/influxdata/influxdb1-client/v2"
|
||||||
|
"golift.io/unifi"
|
||||||
|
)
|
||||||
|
|
||||||
|
// USGPoints 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) {
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
pt, err := influx.NewPoint("usg", tags, fields, now)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
pt, err = influx.NewPoint("usg_networks", tags, fields, now)
|
||||||
|
if err != nil {
|
||||||
|
return points, err
|
||||||
|
}
|
||||||
|
points = append(points, pt)
|
||||||
|
}
|
||||||
|
for _, p := range u.PortTable {
|
||||||
|
tags := map[string]string{
|
||||||
|
"device_name": u.Name,
|
||||||
|
"device_id": u.ID,
|
||||||
|
"device_mac": u.Mac,
|
||||||
|
"site_name": u.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, ","),
|
||||||
|
}
|
||||||
|
pt, err = influx.NewPoint("usg_ports", tags, fields, now)
|
||||||
|
if err != nil {
|
||||||
|
return points, err
|
||||||
|
}
|
||||||
|
points = append(points, pt)
|
||||||
|
}
|
||||||
|
return points, nil
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,145 @@
|
||||||
|
package unifipoller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
influx "github.com/influxdata/influxdb1-client/v2"
|
||||||
|
"golift.io/unifi"
|
||||||
|
)
|
||||||
|
|
||||||
|
// USWPoints 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) {
|
||||||
|
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_priority": u.StpPriority,
|
||||||
|
"stp_version": u.StpVersion,
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
"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,
|
||||||
|
}
|
||||||
|
pt, err := influx.NewPoint("usw", tags, fields, now)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
"full_duplex": p.FullDuplex.Val,
|
||||||
|
}
|
||||||
|
pt, err = influx.NewPoint("usw_ports", tags, fields, now)
|
||||||
|
if err != nil {
|
||||||
|
return points, err
|
||||||
|
}
|
||||||
|
points = append(points, pt)
|
||||||
|
}
|
||||||
|
return points, nil
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue