not sure how far I got..
This commit is contained in:
parent
1b31e1449e
commit
b8d9ac9f88
|
|
@ -14,7 +14,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -66,29 +65,44 @@ type Flag struct {
|
||||||
*pflag.FlagSet
|
*pflag.FlagSet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Controller represents the configuration for a UniFi Controller.
|
||||||
|
// Each polled controller may have its own configuration.
|
||||||
|
type Controller struct {
|
||||||
|
Interval Duration `json:"interval,omitempty" toml:"interval,omitempty" xml:"interval" yaml:"interval"`
|
||||||
|
VerifySSL bool `json:"verify_ssl" toml:"verify_ssl" xml:"verify_ssl" yaml:"verify_ssl"`
|
||||||
|
SaveIDS bool `json:"save_ids" toml:"save_ids" xml:"save_ids" yaml:"save_ids"`
|
||||||
|
ReAuth bool `json:"reauthenticate" toml:"reauthenticate" xml:"reauthenticate" yaml:"reauthenticate"`
|
||||||
|
SaveSites bool `json:"save_sites,omitempty" toml:"save_sites,omitempty" xml:"save_sites" yaml:"save_sites"`
|
||||||
|
User string `json:"unifi_user,omitempty" toml:"unifi_user,omitempty" xml:"unifi_user" yaml:"unifi_user"`
|
||||||
|
Pass string `json:"unifi_pass,omitempty" toml:"unifi_pass,omitempty" xml:"unifi_pass" yaml:"unifi_pass"`
|
||||||
|
URL string `json:"unifi_url,omitempty" toml:"unifi_url,omitempty" xml:"unifi_url" yaml:"unifi_url"`
|
||||||
|
Sites []string `json:"sites,omitempty" toml:"sites,omitempty" xml:"sites" yaml:"sites"`
|
||||||
|
}
|
||||||
|
|
||||||
// Config represents the data needed to poll a controller and report to influxdb.
|
// Config represents the data needed to poll a controller and report to influxdb.
|
||||||
// This is all of the data stored in the config file.
|
// This is all of the data stored in the config file.
|
||||||
// Any with explicit defaults have omitempty on json and toml tags.
|
// Any with explicit defaults have omitempty on json and toml tags.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Interval Duration `json:"interval,omitempty" toml:"interval,omitempty" xml:"interval" yaml:"interval"`
|
Interval Duration `json:"interval,omitempty" toml:"interval,omitempty" xml:"interval" yaml:"interval"`
|
||||||
Debug bool `json:"debug" toml:"debug" xml:"debug" yaml:"debug"`
|
Debug bool `json:"debug" toml:"debug" xml:"debug" yaml:"debug"`
|
||||||
Quiet bool `json:"quiet,omitempty" toml:"quiet,omitempty" xml:"quiet" yaml:"quiet"`
|
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"`
|
VerifySSL bool `json:"verify_ssl" toml:"verify_ssl" xml:"verify_ssl" yaml:"verify_ssl"`
|
||||||
SaveIDS bool `json:"save_ids" toml:"save_ids" xml:"save_ids" yaml:"save_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"`
|
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"`
|
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"`
|
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"`
|
Mode string `json:"mode" toml:"mode" xml:"mode" yaml:"mode"`
|
||||||
HTTPListen string `json:"http_listen" toml:"http_listen" xml:"http_listen" yaml:"http_listen"`
|
HTTPListen string `json:"http_listen" toml:"http_listen" xml:"http_listen" yaml:"http_listen"`
|
||||||
Namespace string `json:"namespace" toml:"namespace" xml:"namespace" yaml:"namespace"`
|
Namespace string `json:"namespace" toml:"namespace" xml:"namespace" yaml:"namespace"`
|
||||||
InfluxURL string `json:"influx_url,omitempty" toml:"influx_url,omitempty" xml:"influx_url" yaml:"influx_url"`
|
InfluxURL string `json:"influx_url,omitempty" toml:"influx_url,omitempty" xml:"influx_url" yaml:"influx_url"`
|
||||||
InfluxUser string `json:"influx_user,omitempty" toml:"influx_user,omitempty" xml:"influx_user" yaml:"influx_user"`
|
InfluxUser string `json:"influx_user,omitempty" toml:"influx_user,omitempty" xml:"influx_user" yaml:"influx_user"`
|
||||||
InfluxPass string `json:"influx_pass,omitempty" toml:"influx_pass,omitempty" xml:"influx_pass" yaml:"influx_pass"`
|
InfluxPass string `json:"influx_pass,omitempty" toml:"influx_pass,omitempty" xml:"influx_pass" yaml:"influx_pass"`
|
||||||
InfluxDB string `json:"influx_db,omitempty" toml:"influx_db,omitempty" xml:"influx_db" yaml:"influx_db"`
|
InfluxDB string `json:"influx_db,omitempty" toml:"influx_db,omitempty" xml:"influx_db" yaml:"influx_db"`
|
||||||
UnifiUser string `json:"unifi_user,omitempty" toml:"unifi_user,omitempty" xml:"unifi_user" yaml:"unifi_user"`
|
UnifiUser string `json:"unifi_user,omitempty" toml:"unifi_user,omitempty" xml:"unifi_user" yaml:"unifi_user"`
|
||||||
UnifiPass string `json:"unifi_pass,omitempty" toml:"unifi_pass,omitempty" xml:"unifi_pass" yaml:"unifi_pass"`
|
UnifiPass string `json:"unifi_pass,omitempty" toml:"unifi_pass,omitempty" xml:"unifi_pass" yaml:"unifi_pass"`
|
||||||
UnifiBase string `json:"unifi_url,omitempty" toml:"unifi_url,omitempty" xml:"unifi_url" yaml:"unifi_url"`
|
UnifiBase string `json:"unifi_url,omitempty" toml:"unifi_url,omitempty" xml:"unifi_url" yaml:"unifi_url"`
|
||||||
Sites []string `json:"sites,omitempty" toml:"sites,omitempty" xml:"sites" yaml:"sites"`
|
Sites []string `json:"sites,omitempty" toml:"sites,omitempty" xml:"sites" yaml:"sites"`
|
||||||
|
Controller []*Controller `json:"controller,omitempty" toml:"controller,omitempty" xml:"controller" yaml:"controller"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Duration is used to UnmarshalTOML into a time.Duration value.
|
// Duration is used to UnmarshalTOML into a time.Duration value.
|
||||||
|
|
@ -126,44 +140,58 @@ func (c *Config) ParseENV() error {
|
||||||
for i := 0; i < t.NumField(); i++ { // Loop each Config struct member
|
for i := 0; i < t.NumField(); i++ { // Loop each Config struct member
|
||||||
tag := t.Field(i).Tag.Get("json") // Get the ENV variable name from "json" struct tag
|
tag := t.Field(i).Tag.Get("json") // Get the ENV variable name from "json" struct tag
|
||||||
tag = strings.Split(strings.ToUpper(tag), ",")[0] // Capitalize and remove ,omitempty suffix
|
tag = strings.Split(strings.ToUpper(tag), ",")[0] // Capitalize and remove ,omitempty suffix
|
||||||
env := os.Getenv(ENVConfigPrefix + tag) // Then pull value from OS.
|
|
||||||
if tag == "" || env == "" { // Skip if either are empty.
|
env := os.Getenv(ENVConfigPrefix + tag) // Then pull value from OS.
|
||||||
|
if tag == "" || env == "" { // Skip if either are empty.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reflect and update the u.Config struct member at position i.
|
if err := c.parseENV(reflect.ValueOf(c).Elem().Field(i), tag, env); err != nil {
|
||||||
switch field := reflect.ValueOf(c).Elem().Field(i); field.Type().String() {
|
return err
|
||||||
// Handle each member type appropriately (differently).
|
|
||||||
case "string":
|
|
||||||
// This is a reflect package method to update a struct member by index.
|
|
||||||
field.SetString(env)
|
|
||||||
|
|
||||||
case "int":
|
|
||||||
val, err := strconv.Atoi(env)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("%s: %v", tag, err)
|
|
||||||
}
|
|
||||||
field.Set(reflect.ValueOf(val))
|
|
||||||
|
|
||||||
case "[]string":
|
|
||||||
field.Set(reflect.ValueOf(strings.Split(env, ",")))
|
|
||||||
|
|
||||||
case path.Base(t.PkgPath()) + ".Duration":
|
|
||||||
val, err := time.ParseDuration(env)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("%s: %v", tag, err)
|
|
||||||
}
|
|
||||||
field.Set(reflect.ValueOf(Duration{val}))
|
|
||||||
|
|
||||||
case "bool":
|
|
||||||
val, err := strconv.ParseBool(env)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("%s: %v", tag, err)
|
|
||||||
}
|
|
||||||
field.SetBool(val)
|
|
||||||
}
|
}
|
||||||
// Add more types here if more types are added to the config struct.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Config) parseENV(field reflect.Value, tag, env string) error {
|
||||||
|
// Reflect and update the u.Config struct member at position i.
|
||||||
|
switch field.Type().String() {
|
||||||
|
// Handle each member type appropriately (differently).
|
||||||
|
case "string":
|
||||||
|
// This is a reflect package method to update a struct member by index.
|
||||||
|
field.SetString(env)
|
||||||
|
|
||||||
|
case "int":
|
||||||
|
val, err := strconv.Atoi(env)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("%s: %v", tag, err)
|
||||||
|
}
|
||||||
|
field.Set(reflect.ValueOf(val))
|
||||||
|
|
||||||
|
case "[]string":
|
||||||
|
field.Set(reflect.ValueOf(strings.Split(env, ",")))
|
||||||
|
|
||||||
|
case "poller.Duration":
|
||||||
|
val, err := time.ParseDuration(env)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("%s: %v", tag, err)
|
||||||
|
}
|
||||||
|
field.Set(reflect.ValueOf(Duration{val}))
|
||||||
|
|
||||||
|
case "bool":
|
||||||
|
val, err := strconv.ParseBool(env)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("%s: %v", tag, err)
|
||||||
|
}
|
||||||
|
field.SetBool(val)
|
||||||
|
|
||||||
|
case "poller.[]*Controller":
|
||||||
|
}
|
||||||
|
// Add more types here if more types are added to the config struct.
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) parseSlice(field reflect.Value, tag, env string) error {
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ type uclient struct {
|
||||||
func descClient(ns string) *uclient {
|
func descClient(ns string) *uclient {
|
||||||
labels := []string{"name", "mac", "site_name", "gw_name", "sw_name", "vlan", "ip", "oui", "network", "sw_port", "ap_name", "wired"}
|
labels := []string{"name", "mac", "site_name", "gw_name", "sw_name", "vlan", "ip", "oui", "network", "sw_port", "ap_name", "wired"}
|
||||||
labelW := append([]string{"radio_name", "radio", "radio_proto", "channel", "essid", "bssid", "radio_desc"}, labels...)
|
labelW := append([]string{"radio_name", "radio", "radio_proto", "channel", "essid", "bssid", "radio_desc"}, labels...)
|
||||||
|
|
||||||
return &uclient{
|
return &uclient{
|
||||||
Anomalies: prometheus.NewDesc(ns+"anomalies", "Client Anomalies", labelW, nil),
|
Anomalies: prometheus.NewDesc(ns+"anomalies", "Client Anomalies", labelW, nil),
|
||||||
BytesR: prometheus.NewDesc(ns+"transfer_rate_bytes", "Client Data Rate", labelW, nil),
|
BytesR: prometheus.NewDesc(ns+"transfer_rate_bytes", "Client Data Rate", labelW, nil),
|
||||||
|
|
@ -115,6 +116,7 @@ func (u *promUnifi) exportClient(r report, c *unifi.Client) {
|
||||||
{u.Client.BytesR, gauge, c.BytesR, labelW},
|
{u.Client.BytesR, gauge, c.BytesR, labelW},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
r.send([]*metric{{u.Client.Uptime, gauge, c.Uptime, labelW}})
|
r.send([]*metric{{u.Client.Uptime, gauge, c.Uptime, labelW}})
|
||||||
/* needs more "looking into"
|
/* needs more "looking into"
|
||||||
{u.Client.DpiStatsApp, gauge, c.DpiStats.App, labels},
|
{u.Client.DpiStatsApp, gauge, c.DpiStats.App, labels},
|
||||||
|
|
|
||||||
|
|
@ -75,9 +75,11 @@ func NewUnifiCollector(opts UnifiCollectorCnfg) prometheus.Collector {
|
||||||
if opts.CollectFn == nil {
|
if opts.CollectFn == nil {
|
||||||
panic("nil collector function")
|
panic("nil collector function")
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.Namespace = strings.Trim(opts.Namespace, "_") + "_"; opts.Namespace == "_" {
|
if opts.Namespace = strings.Trim(opts.Namespace, "_") + "_"; opts.Namespace == "_" {
|
||||||
opts.Namespace = ""
|
opts.Namespace = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
return &promUnifi{
|
return &promUnifi{
|
||||||
Config: opts,
|
Config: opts,
|
||||||
Client: descClient(opts.Namespace + "client_"),
|
Client: descClient(opts.Namespace + "client_"),
|
||||||
|
|
@ -94,6 +96,7 @@ func NewUnifiCollector(opts UnifiCollectorCnfg) prometheus.Collector {
|
||||||
func (u *promUnifi) Describe(ch chan<- *prometheus.Desc) {
|
func (u *promUnifi) Describe(ch chan<- *prometheus.Desc) {
|
||||||
for _, f := range []interface{}{u.Client, u.Device, u.UAP, u.USG, u.USW, u.Site} {
|
for _, f := range []interface{}{u.Client, u.Device, u.UAP, u.USG, u.USW, u.Site} {
|
||||||
v := reflect.Indirect(reflect.ValueOf(f))
|
v := reflect.Indirect(reflect.ValueOf(f))
|
||||||
|
|
||||||
// Loop each struct member and send it to the provided channel.
|
// Loop each struct member and send it to the provided channel.
|
||||||
for i := 0; i < v.NumField(); i++ {
|
for i := 0; i < v.NumField(); i++ {
|
||||||
desc, ok := v.Field(i).Interface().(*prometheus.Desc)
|
desc, ok := v.Field(i).Interface().(*prometheus.Desc)
|
||||||
|
|
@ -108,6 +111,7 @@ func (u *promUnifi) Describe(ch chan<- *prometheus.Desc) {
|
||||||
// the current metrics (from another package) then exports them for prometheus.
|
// the current metrics (from another package) then exports them for prometheus.
|
||||||
func (u *promUnifi) Collect(ch chan<- prometheus.Metric) {
|
func (u *promUnifi) Collect(ch chan<- prometheus.Metric) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
r := &Report{cf: u.Config, ch: make(chan []*metric, buffer), Start: time.Now()}
|
r := &Report{cf: u.Config, ch: make(chan []*metric, buffer), Start: time.Now()}
|
||||||
defer r.close()
|
defer r.close()
|
||||||
|
|
||||||
|
|
@ -116,6 +120,7 @@ func (u *promUnifi) Collect(ch chan<- prometheus.Metric) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r.Fetch = time.Since(r.Start)
|
r.Fetch = time.Since(r.Start)
|
||||||
|
|
||||||
if r.Metrics.Devices == nil {
|
if r.Metrics.Devices == nil {
|
||||||
r.Metrics.Devices = &unifi.Devices{}
|
r.Metrics.Devices = &unifi.Devices{}
|
||||||
}
|
}
|
||||||
|
|
@ -131,6 +136,7 @@ func (u *promUnifi) Collect(ch chan<- prometheus.Metric) {
|
||||||
func (u *promUnifi) exportMetrics(r report, ch chan<- prometheus.Metric, ourChan chan []*metric) {
|
func (u *promUnifi) exportMetrics(r report, ch chan<- prometheus.Metric, ourChan chan []*metric) {
|
||||||
descs := make(map[*prometheus.Desc]bool) // used as a counter
|
descs := make(map[*prometheus.Desc]bool) // used as a counter
|
||||||
defer r.report(descs)
|
defer r.report(descs)
|
||||||
|
|
||||||
for newMetrics := range ourChan {
|
for newMetrics := range ourChan {
|
||||||
for _, m := range newMetrics {
|
for _, m := range newMetrics {
|
||||||
descs[m.Desc] = true
|
descs[m.Desc] = true
|
||||||
|
|
|
||||||
|
|
@ -46,20 +46,24 @@ func (r *Report) report(descs map[*prometheus.Desc]bool) {
|
||||||
if r.cf.LoggingFn == nil {
|
if r.cf.LoggingFn == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
r.Descs = len(descs)
|
r.Descs = len(descs)
|
||||||
r.cf.LoggingFn(r)
|
r.cf.LoggingFn(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Report) export(m *metric, v float64) prometheus.Metric {
|
func (r *Report) export(m *metric, v float64) prometheus.Metric {
|
||||||
r.Total++
|
r.Total++
|
||||||
|
|
||||||
if v == 0 {
|
if v == 0 {
|
||||||
r.Zeros++
|
r.Zeros++
|
||||||
}
|
}
|
||||||
|
|
||||||
return prometheus.MustNewConstMetric(m.Desc, m.ValueType, v, m.Labels...)
|
return prometheus.MustNewConstMetric(m.Desc, m.ValueType, v, m.Labels...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Report) error(ch chan<- prometheus.Metric, d *prometheus.Desc, v interface{}) {
|
func (r *Report) error(ch chan<- prometheus.Metric, d *prometheus.Desc, v interface{}) {
|
||||||
r.Errors++
|
r.Errors++
|
||||||
|
|
||||||
if r.cf.ReportErrors {
|
if r.cf.ReportErrors {
|
||||||
ch <- prometheus.NewInvalidMetric(d, fmt.Errorf("error: %v", v))
|
ch <- prometheus.NewInvalidMetric(d, fmt.Errorf("error: %v", v))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,8 +66,7 @@ func descSite(ns string) *site {
|
||||||
|
|
||||||
func (u *promUnifi) exportSite(r report, s *unifi.Site) {
|
func (u *promUnifi) exportSite(r report, s *unifi.Site) {
|
||||||
for _, h := range s.Health {
|
for _, h := range s.Health {
|
||||||
labels := []string{h.Subsystem, h.Status, s.SiteName}
|
switch labels := []string{h.Subsystem, h.Status, s.SiteName}; labels[0] {
|
||||||
switch h.Subsystem {
|
|
||||||
case "www":
|
case "www":
|
||||||
r.send([]*metric{
|
r.send([]*metric{
|
||||||
{u.Site.TxBytesR, gauge, h.TxBytesR, labels},
|
{u.Site.TxBytesR, gauge, h.TxBytesR, labels},
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,7 @@ func descUAP(ns string) *uap {
|
||||||
labelA := []string{"stat", "site_name", "name"} // stat + labels[1:]
|
labelA := []string{"stat", "site_name", "name"} // stat + labels[1:]
|
||||||
labelV := []string{"vap_name", "bssid", "radio", "radio_name", "essid", "usage", "site_name", "name"}
|
labelV := []string{"vap_name", "bssid", "radio", "radio_name", "essid", "usage", "site_name", "name"}
|
||||||
labelR := []string{"radio_name", "radio", "site_name", "name"}
|
labelR := []string{"radio_name", "radio", "site_name", "name"}
|
||||||
|
|
||||||
return &uap{
|
return &uap{
|
||||||
// 3x each - stat table: total, guest, user
|
// 3x each - stat table: total, guest, user
|
||||||
ApWifiTxDropped: prometheus.NewDesc(ns+"stat_wifi_transmt_dropped_total", "Wifi Transmissions Dropped", labelA, nil),
|
ApWifiTxDropped: prometheus.NewDesc(ns+"stat_wifi_transmt_dropped_total", "Wifi Transmissions Dropped", labelA, nil),
|
||||||
|
|
@ -162,6 +163,7 @@ func (u *promUnifi) exportUAP(r report, d *unifi.UAP) {
|
||||||
if !d.Adopted.Val || d.Locating.Val {
|
if !d.Adopted.Val || d.Locating.Val {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
labels := []string{d.Type, d.SiteName, d.Name}
|
labels := []string{d.Type, d.SiteName, d.Name}
|
||||||
infoLabels := []string{d.Version, d.Model, d.Serial, d.Mac, d.IP, d.ID, d.Bytes.Txt, d.Uptime.Txt}
|
infoLabels := []string{d.Version, d.Model, d.Serial, d.Mac, d.IP, d.ID, d.Bytes.Txt, d.Uptime.Txt}
|
||||||
u.exportUAPstats(r, labels, d.Stat.Ap, d.BytesD, d.TxBytesD, d.RxBytesD, d.BytesR)
|
u.exportUAPstats(r, labels, d.Stat.Ap, d.BytesD, d.TxBytesD, d.RxBytesD, d.BytesR)
|
||||||
|
|
@ -181,6 +183,7 @@ func (u *promUnifi) exportUAPstats(r report, labels []string, ap *unifi.Ap, byte
|
||||||
if ap == nil {
|
if ap == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
labelU := []string{"user", labels[1], labels[2]}
|
labelU := []string{"user", labels[1], labels[2]}
|
||||||
labelG := []string{"guest", labels[1], labels[2]}
|
labelG := []string{"guest", labels[1], labels[2]}
|
||||||
r.send([]*metric{
|
r.send([]*metric{
|
||||||
|
|
@ -229,8 +232,8 @@ func (u *promUnifi) exportVAPtable(r report, labels []string, vt unifi.VapTable)
|
||||||
if !v.Up.Val {
|
if !v.Up.Val {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
labelV := []string{v.Name, v.Bssid, v.Radio, v.RadioName, v.Essid, v.Usage, labels[1], labels[2]}
|
|
||||||
|
|
||||||
|
labelV := []string{v.Name, v.Bssid, v.Radio, v.RadioName, v.Essid, v.Usage, labels[1], labels[2]}
|
||||||
r.send([]*metric{
|
r.send([]*metric{
|
||||||
{u.UAP.VAPCcq, gauge, float64(v.Ccq) / 1000.0, labelV},
|
{u.UAP.VAPCcq, gauge, float64(v.Ccq) / 1000.0, labelV},
|
||||||
{u.UAP.VAPMacFilterRejections, counter, v.MacFilterRejections, labelV},
|
{u.UAP.VAPMacFilterRejections, counter, v.MacFilterRejections, labelV},
|
||||||
|
|
@ -294,6 +297,7 @@ func (u *promUnifi) exportRADtable(r report, labels []string, rt unifi.RadioTabl
|
||||||
if t.Name != p.Name {
|
if t.Name != p.Name {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
r.send([]*metric{
|
r.send([]*metric{
|
||||||
{u.UAP.RadioTxPower, gauge, t.TxPower, labelR},
|
{u.UAP.RadioTxPower, gauge, t.TxPower, labelR},
|
||||||
{u.UAP.RadioAstBeXmit, gauge, t.AstBeXmit, labelR},
|
{u.UAP.RadioAstBeXmit, gauge, t.AstBeXmit, labelR},
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ type unifiDevice struct {
|
||||||
func descDevice(ns string) *unifiDevice {
|
func descDevice(ns string) *unifiDevice {
|
||||||
labels := []string{"type", "site_name", "name"}
|
labels := []string{"type", "site_name", "name"}
|
||||||
infoLabels := []string{"version", "model", "serial", "mac", "ip", "id", "bytes", "uptime"}
|
infoLabels := []string{"version", "model", "serial", "mac", "ip", "id", "bytes", "uptime"}
|
||||||
|
|
||||||
return &unifiDevice{
|
return &unifiDevice{
|
||||||
Info: prometheus.NewDesc(ns+"info", "Device Information", append(labels, infoLabels...), nil),
|
Info: prometheus.NewDesc(ns+"info", "Device Information", append(labels, infoLabels...), nil),
|
||||||
Uptime: prometheus.NewDesc(ns+"uptime_seconds", "Device Uptime", labels, nil),
|
Uptime: prometheus.NewDesc(ns+"uptime_seconds", "Device Uptime", labels, nil),
|
||||||
|
|
@ -63,6 +64,7 @@ func (u *promUnifi) exportUDM(r report, d *unifi.UDM) {
|
||||||
if !d.Adopted.Val || d.Locating.Val {
|
if !d.Adopted.Val || d.Locating.Val {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
labels := []string{d.Type, d.SiteName, d.Name}
|
labels := []string{d.Type, d.SiteName, d.Name}
|
||||||
infoLabels := []string{d.Version, d.Model, d.Serial, d.Mac, d.IP, d.ID, d.Bytes.Txt, d.Uptime.Txt}
|
infoLabels := []string{d.Version, d.Model, d.Serial, d.Mac, d.IP, d.ID, d.Bytes.Txt, d.Uptime.Txt}
|
||||||
// Shared data (all devices do this).
|
// Shared data (all devices do this).
|
||||||
|
|
@ -80,6 +82,7 @@ func (u *promUnifi) exportUDM(r report, d *unifi.UDM) {
|
||||||
{u.Device.Info, gauge, 1.0, append(labels, infoLabels...)},
|
{u.Device.Info, gauge, 1.0, append(labels, infoLabels...)},
|
||||||
{u.Device.Uptime, gauge, d.Uptime, labels},
|
{u.Device.Uptime, gauge, d.Uptime, labels},
|
||||||
})
|
})
|
||||||
|
|
||||||
// Wireless Data - UDM (non-pro) only
|
// Wireless Data - UDM (non-pro) only
|
||||||
if d.Stat.Ap != nil && d.VapTable != nil {
|
if d.Stat.Ap != nil && d.VapTable != nil {
|
||||||
u.exportUAPstats(r, labels, d.Stat.Ap, d.BytesD, d.TxBytesD, d.RxBytesD, d.BytesR)
|
u.exportUAPstats(r, labels, d.Stat.Ap, d.BytesD, d.TxBytesD, d.RxBytesD, d.BytesR)
|
||||||
|
|
@ -103,6 +106,7 @@ func (u *promUnifi) exportSTAcount(r report, labels []string, stas ...unifi.Flex
|
||||||
{u.Device.Counter, gauge, stas[0], append(labels, "user")},
|
{u.Device.Counter, gauge, stas[0], append(labels, "user")},
|
||||||
{u.Device.Counter, gauge, stas[1], append(labels, "guest")},
|
{u.Device.Counter, gauge, stas[1], append(labels, "guest")},
|
||||||
})
|
})
|
||||||
|
|
||||||
if len(stas) > 2 {
|
if len(stas) > 2 {
|
||||||
r.send([]*metric{
|
r.send([]*metric{
|
||||||
{u.Device.Counter, gauge, stas[2], append(labels, "desktop")},
|
{u.Device.Counter, gauge, stas[2], append(labels, "desktop")},
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@ func (u *promUnifi) exportUSG(r report, d *unifi.USG) {
|
||||||
if !d.Adopted.Val || d.Locating.Val {
|
if !d.Adopted.Val || d.Locating.Val {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
labels := []string{d.Type, d.SiteName, d.Name}
|
labels := []string{d.Type, d.SiteName, d.Name}
|
||||||
infoLabels := []string{d.Version, d.Model, d.Serial, d.Mac, d.IP, d.ID, d.Bytes.Txt, d.Uptime.Txt}
|
infoLabels := []string{d.Version, d.Model, d.Serial, d.Mac, d.IP, d.ID, d.Bytes.Txt, d.Uptime.Txt}
|
||||||
// Gateway System Data.
|
// Gateway System Data.
|
||||||
|
|
@ -91,6 +92,7 @@ func (u *promUnifi) exportUSGstats(r report, labels []string, gw *unifi.Gw, st u
|
||||||
if gw == nil {
|
if gw == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
labelLan := []string{"lan", labels[1], labels[2]}
|
labelLan := []string{"lan", labels[1], labels[2]}
|
||||||
labelWan := []string{"all", labels[1], labels[2]}
|
labelWan := []string{"all", labels[1], labels[2]}
|
||||||
r.send([]*metric{
|
r.send([]*metric{
|
||||||
|
|
@ -115,6 +117,7 @@ func (u *promUnifi) exportWANPorts(r report, labels []string, wans ...unifi.Wan)
|
||||||
if !wan.Up.Val {
|
if !wan.Up.Val {
|
||||||
continue // only record UP interfaces.
|
continue // only record UP interfaces.
|
||||||
}
|
}
|
||||||
|
|
||||||
labelWan := []string{wan.Name, labels[1], labels[2]}
|
labelWan := []string{wan.Name, labels[1], labels[2]}
|
||||||
r.send([]*metric{
|
r.send([]*metric{
|
||||||
{u.USG.WanRxPackets, counter, wan.RxPackets, labelWan},
|
{u.USG.WanRxPackets, counter, wan.RxPackets, labelWan},
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ func descUSW(ns string) *usw {
|
||||||
pns := ns + "port_"
|
pns := ns + "port_"
|
||||||
labelS := []string{"site_name", "name"}
|
labelS := []string{"site_name", "name"}
|
||||||
labelP := []string{"port_id", "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{
|
return &usw{
|
||||||
// This data may be derivable by sum()ing the port data.
|
// This data may be derivable by sum()ing the port data.
|
||||||
SwRxPackets: prometheus.NewDesc(ns+"switch_receive_packets_total", "Switch Packets Received Total", labelS, nil),
|
SwRxPackets: prometheus.NewDesc(ns+"switch_receive_packets_total", "Switch Packets Received Total", labelS, nil),
|
||||||
|
|
@ -94,6 +95,7 @@ func (u *promUnifi) exportUSW(r report, d *unifi.USW) {
|
||||||
if !d.Adopted.Val || d.Locating.Val {
|
if !d.Adopted.Val || d.Locating.Val {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
labels := []string{d.Type, d.SiteName, d.Name}
|
labels := []string{d.Type, d.SiteName, d.Name}
|
||||||
infoLabels := []string{d.Version, d.Model, d.Serial, d.Mac, d.IP, d.ID, d.Bytes.Txt, d.Uptime.Txt}
|
infoLabels := []string{d.Version, d.Model, d.Serial, d.Mac, d.IP, d.ID, d.Bytes.Txt, d.Uptime.Txt}
|
||||||
u.exportUSWstats(r, labels, d.Stat.Sw)
|
u.exportUSWstats(r, labels, d.Stat.Sw)
|
||||||
|
|
@ -105,13 +107,16 @@ func (u *promUnifi) exportUSW(r report, d *unifi.USW) {
|
||||||
{u.Device.Info, gauge, 1.0, append(labels, infoLabels...)},
|
{u.Device.Info, gauge, 1.0, append(labels, infoLabels...)},
|
||||||
{u.Device.Uptime, gauge, d.Uptime, labels},
|
{u.Device.Uptime, gauge, d.Uptime, labels},
|
||||||
})
|
})
|
||||||
|
|
||||||
// Switch System Data.
|
// Switch System Data.
|
||||||
if d.HasTemperature.Val {
|
if d.HasTemperature.Val {
|
||||||
r.send([]*metric{{u.Device.Temperature, gauge, d.GeneralTemperature, labels}})
|
r.send([]*metric{{u.Device.Temperature, gauge, d.GeneralTemperature, labels}})
|
||||||
}
|
}
|
||||||
|
|
||||||
if d.HasFan.Val {
|
if d.HasFan.Val {
|
||||||
r.send([]*metric{{u.Device.FanLevel, gauge, d.FanLevel, labels}})
|
r.send([]*metric{{u.Device.FanLevel, gauge, d.FanLevel, labels}})
|
||||||
}
|
}
|
||||||
|
|
||||||
if d.TotalMaxPower.Txt != "" {
|
if d.TotalMaxPower.Txt != "" {
|
||||||
r.send([]*metric{{u.Device.TotalMaxPower, gauge, d.TotalMaxPower, labels}})
|
r.send([]*metric{{u.Device.TotalMaxPower, gauge, d.TotalMaxPower, labels}})
|
||||||
}
|
}
|
||||||
|
|
@ -122,6 +127,7 @@ func (u *promUnifi) exportUSWstats(r report, labels []string, sw *unifi.Sw) {
|
||||||
if sw == nil {
|
if sw == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
labelS := labels[1:]
|
labelS := labels[1:]
|
||||||
r.send([]*metric{
|
r.send([]*metric{
|
||||||
{u.USW.SwRxPackets, counter, sw.RxPackets, labelS},
|
{u.USW.SwRxPackets, counter, sw.RxPackets, labelS},
|
||||||
|
|
@ -150,8 +156,10 @@ func (u *promUnifi) exportPRTtable(r report, labels []string, pt []unifi.Port) {
|
||||||
if !p.Up.Val || !p.Enable.Val {
|
if !p.Up.Val || !p.Enable.Val {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy labels, and add four new ones.
|
// Copy labels, and add four new ones.
|
||||||
labelP := []string{labels[2] + " Port " + p.PortIdx.Txt, p.PortIdx.Txt, p.Name, p.Mac, p.IP, labels[1], labels[2]}
|
labelP := []string{labels[2] + " Port " + p.PortIdx.Txt, p.PortIdx.Txt, p.Name, p.Mac, p.IP, labels[1], labels[2]}
|
||||||
|
|
||||||
if p.PoeEnable.Val && p.PortPoe.Val {
|
if p.PoeEnable.Val && p.PortPoe.Val {
|
||||||
r.send([]*metric{
|
r.send([]*metric{
|
||||||
{u.USW.PoeCurrent, gauge, p.PoeCurrent, labelP},
|
{u.USW.PoeCurrent, gauge, p.PoeCurrent, labelP},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue