Base layout .. maybe.
This commit is contained in:
parent
dd27f90a62
commit
9bd4737730
|
|
@ -46,11 +46,12 @@
|
|||
version = "v1.0.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:eb04f69c8991e52eff33c428bd729e04208bf03235be88e4df0d88497c6861b9"
|
||||
digest = "1:eb8832cdc904ff89b70c524ab305bf3384c6411f9df6b9f2a41fddc2220e6613"
|
||||
name = "github.com/prometheus/client_golang"
|
||||
packages = [
|
||||
"prometheus",
|
||||
"prometheus/internal",
|
||||
"prometheus/promauto",
|
||||
"prometheus/promhttp",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
|
|
@ -127,6 +128,8 @@
|
|||
input-imports = [
|
||||
"github.com/BurntSushi/toml",
|
||||
"github.com/influxdata/influxdb1-client/v2",
|
||||
"github.com/prometheus/client_golang/prometheus",
|
||||
"github.com/prometheus/client_golang/prometheus/promauto",
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp",
|
||||
"github.com/spf13/pflag",
|
||||
"golift.io/unifi",
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ quiet = false
|
|||
# /metrics for polling collection by a prometheus server. This disables influxdb.
|
||||
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:61317"
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/davidnewhall/unifi-poller/promunifi"
|
||||
client "github.com/influxdata/influxdb1-client/v2"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"github.com/spf13/pflag"
|
||||
"golift.io/unifi"
|
||||
|
|
@ -98,19 +100,24 @@ func (u *UnifiPoller) Run() (err error) {
|
|||
case "prometheus", "exporter":
|
||||
u.Logf("Exporting Measurements at https://%s/metrics for Prometheus", u.Config.HTTPListen)
|
||||
u.Config.Mode = "http exporter"
|
||||
http.Handle("/metrics", promhttp.Handler())
|
||||
go func() {
|
||||
err = http.ListenAndServe(u.Config.HTTPListen, nil)
|
||||
if err != http.ErrServerClosed {
|
||||
log.Fatalf("[ERROR] http server: %v", err)
|
||||
}
|
||||
}()
|
||||
return u.PollController(u.ExportMetrics)
|
||||
http.Handle("/metrics", http.HandlerFunc(u.PromHandler))
|
||||
prometheus.MustRegister(promunifi.NewUnifiCollector(promunifi.UnifiCollectorOpts{
|
||||
CollectFn: u.ExportMetrics,
|
||||
ReportErrors: true,
|
||||
Namespace: "unifi",
|
||||
CollectIDS: true,
|
||||
}))
|
||||
err = http.ListenAndServe(u.Config.HTTPListen, nil)
|
||||
if err != http.ErrServerClosed {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
default:
|
||||
if err = u.GetInfluxDB(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
u.Logf("Logging Measurements to InfluxDB at %s as user %s", u.Config.InfluxURL, u.Config.InfluxUser)
|
||||
u.Config.Mode = "influx poller"
|
||||
return u.PollController(u.ReportMetrics)
|
||||
|
|
@ -128,9 +135,16 @@ func (u *UnifiPoller) GetInfluxDB() (err error) {
|
|||
if err != nil {
|
||||
return fmt.Errorf("influxdb: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// PromHandler logs /metrics requests and serves them with the prometheus handler.
|
||||
func (u *UnifiPoller) PromHandler(w http.ResponseWriter, r *http.Request) {
|
||||
u.LogDebugf("/metrics endpoint polled by %v", r.RemoteAddr)
|
||||
promhttp.Handler().ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
// GetUnifi returns a UniFi controller interface.
|
||||
func (u *UnifiPoller) GetUnifi() (err error) {
|
||||
// Create an authenticated session to the Unifi Controller.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import (
|
|||
|
||||
"github.com/davidnewhall/unifi-poller/influx"
|
||||
"github.com/davidnewhall/unifi-poller/metrics"
|
||||
"github.com/davidnewhall/unifi-poller/prometheus"
|
||||
client "github.com/influxdata/influxdb1-client/v2"
|
||||
"golift.io/unifi"
|
||||
)
|
||||
|
|
@ -84,14 +83,45 @@ func (u *UnifiPoller) CollectAndProcess(process func(*metrics.Metrics) error) er
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := u.AugmentMetrics(metrics); err != nil {
|
||||
return err
|
||||
}
|
||||
u.AugmentMetrics(metrics)
|
||||
err = process(metrics)
|
||||
u.LogError(err, "processing metrics")
|
||||
return err
|
||||
}
|
||||
|
||||
// ExportMetrics updates the internal metrics provided via
|
||||
// HTTP at /metrics for prometheus collection.
|
||||
func (u *UnifiPoller) ExportMetrics() *metrics.Metrics {
|
||||
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")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
metrics, err := u.CollectMetrics()
|
||||
if err != nil {
|
||||
u.LogErrorf("collecting metrics: %v", err)
|
||||
return nil
|
||||
}
|
||||
u.AugmentMetrics(metrics)
|
||||
u.LogExportReport(metrics)
|
||||
return metrics
|
||||
}
|
||||
|
||||
// LogExportReport writes a log line after exporting metrics via HTTP.
|
||||
func (u *UnifiPoller) LogExportReport(m *metrics.Metrics) {
|
||||
idsMsg := ""
|
||||
if u.Config.CollectIDS {
|
||||
idsMsg = fmt.Sprintf(", IDS Events: %d, ", len(m.IDSList))
|
||||
}
|
||||
u.Logf("UniFi Measurements Exported. Sites: %d, Clients: %d, "+
|
||||
"Wireless APs: %d, Gateways: %d, Switches: %d%s",
|
||||
len(m.Sites), len(m.Clients), len(m.UAPs),
|
||||
len(m.UDMs)+len(m.USGs), len(m.USWs), idsMsg)
|
||||
}
|
||||
|
||||
// CollectMetrics grabs all the measurements from a UniFi controller and returns them.
|
||||
func (u *UnifiPoller) CollectMetrics() (*metrics.Metrics, error) {
|
||||
m := &metrics.Metrics{TS: u.LastCheck} // At this point, it's the Current Check.
|
||||
|
|
@ -115,9 +145,9 @@ func (u *UnifiPoller) CollectMetrics() (*metrics.Metrics, error) {
|
|||
// AugmentMetrics is our middleware layer between collecting metrics and writing them.
|
||||
// This is where we can manipuate the returned data or make arbitrary decisions.
|
||||
// This function currently adds parent device names to client metrics.
|
||||
func (u *UnifiPoller) AugmentMetrics(metrics *metrics.Metrics) error {
|
||||
func (u *UnifiPoller) AugmentMetrics(metrics *metrics.Metrics) {
|
||||
if metrics == nil || metrics.Devices == nil || metrics.Clients == nil {
|
||||
return fmt.Errorf("nil metrics, augment impossible")
|
||||
return
|
||||
}
|
||||
devices := make(map[string]string)
|
||||
bssdIDs := make(map[string]string)
|
||||
|
|
@ -143,30 +173,6 @@ func (u *UnifiPoller) AugmentMetrics(metrics *metrics.Metrics) error {
|
|||
metrics.Clients[i].GwName = devices[c.GwMac]
|
||||
metrics.Clients[i].RadioDescription = bssdIDs[metrics.Clients[i].Bssid] + metrics.Clients[i].RadioProto
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExportMetrics updates the internal metrics provided via
|
||||
// HTTP at /metrics for prometheus collection.
|
||||
func (u *UnifiPoller) ExportMetrics(metrics *metrics.Metrics) error {
|
||||
m := &prometheus.Metrics{Metrics: metrics}
|
||||
for _, err := range m.ProcessExports() {
|
||||
u.LogError(err, "prometheus.ProcessExports")
|
||||
}
|
||||
u.LogExportReport(m)
|
||||
return nil
|
||||
}
|
||||
|
||||
// LogExportReport writes a log line after exporting metrics via HTTP.
|
||||
func (u *UnifiPoller) LogExportReport(m *prometheus.Metrics) {
|
||||
idsMsg := ""
|
||||
if u.Config.CollectIDS {
|
||||
idsMsg = fmt.Sprintf(", IDS Events: %d, ", len(m.IDSList))
|
||||
}
|
||||
u.Logf("UniFi Measurements Exported. Sites: %d, Clients: %d, "+
|
||||
"Wireless APs: %d, Gateways: %d, Switches: %d%s",
|
||||
len(m.Sites), len(m.Clients), len(m.UAPs),
|
||||
len(m.UDMs)+len(m.USGs), len(m.USWs), idsMsg)
|
||||
}
|
||||
|
||||
// ReportMetrics batches all the metrics and writes them to InfluxDB.
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
package prometheus
|
||||
|
||||
import "github.com/davidnewhall/unifi-poller/metrics"
|
||||
|
||||
// Metrics contains all the data from the controller.
|
||||
type Metrics struct {
|
||||
*metrics.Metrics
|
||||
}
|
||||
|
||||
// ProcessExports turns the data into exported data.
|
||||
func (m *Metrics) ProcessExports() []error {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
# prometheus
|
||||
|
||||
This package provides the methods to turn UniFi measurements into prometheus
|
||||
exported metrics with an HTTP listener.
|
||||
exported metrics.
|
||||
|
|
@ -0,0 +1,213 @@
|
|||
package promunifi
|
||||
|
||||
import (
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"golift.io/unifi"
|
||||
)
|
||||
|
||||
type client struct {
|
||||
Anomalies *prometheus.Desc
|
||||
BytesR *prometheus.Desc
|
||||
CCQ *prometheus.Desc
|
||||
Noise *prometheus.Desc
|
||||
RoamCount *prometheus.Desc
|
||||
RSSI *prometheus.Desc
|
||||
RxBytes *prometheus.Desc
|
||||
RxBytesR *prometheus.Desc
|
||||
RxPackets *prometheus.Desc
|
||||
RxRate *prometheus.Desc
|
||||
Signal *prometheus.Desc
|
||||
TxBytes *prometheus.Desc
|
||||
TxBytesR *prometheus.Desc
|
||||
TxPackets *prometheus.Desc
|
||||
TxPower *prometheus.Desc
|
||||
TxRate *prometheus.Desc
|
||||
Uptime *prometheus.Desc
|
||||
WifiTxAttempts *prometheus.Desc
|
||||
WiredRxBytes *prometheus.Desc
|
||||
WiredRxBytesR *prometheus.Desc
|
||||
WiredRxPackets *prometheus.Desc
|
||||
WiredTxBytes *prometheus.Desc
|
||||
WiredTxBytesR *prometheus.Desc
|
||||
WiredTxPackets *prometheus.Desc
|
||||
DpiStatsApp *prometheus.Desc
|
||||
DpiStatsCat *prometheus.Desc
|
||||
DpiStatsRxBytes *prometheus.Desc
|
||||
DpiStatsRxPackets *prometheus.Desc
|
||||
DpiStatsTxBytes *prometheus.Desc
|
||||
DpiStatsTxPackets *prometheus.Desc
|
||||
}
|
||||
|
||||
func descClient(ns string) *client {
|
||||
labels := []string{"id", "mac", "user_id", "site_id", "site_name",
|
||||
"network_id", "ap_mac", "gw_mac", "sw_mac", "ap_name", "gw_name",
|
||||
"sw_name", "radio_name", "radio", "radio_proto", "name", "channel",
|
||||
"vlan", "ip", "essid", "bssid", "radio_desc"}
|
||||
ns2 := "client"
|
||||
|
||||
return &client{
|
||||
Anomalies: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "anomalies"),
|
||||
"Client Anomalies", labels, nil,
|
||||
),
|
||||
BytesR: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "bytesr"),
|
||||
"Client Data Rate", labels, nil,
|
||||
),
|
||||
CCQ: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "ccq"),
|
||||
"Client Connection Quality", labels, nil,
|
||||
),
|
||||
Noise: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "noise"),
|
||||
"Client AP Noise", labels, nil,
|
||||
),
|
||||
RoamCount: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "roamcount"),
|
||||
"Client Roam Counter", labels, nil,
|
||||
),
|
||||
RSSI: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "rssi"),
|
||||
"Client RSSI", labels, nil,
|
||||
),
|
||||
RxBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "rxbytes"),
|
||||
"Client Receive Bytes", labels, nil,
|
||||
),
|
||||
RxBytesR: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "rxbytesr"),
|
||||
"Client Receive Data Rate", labels, nil,
|
||||
),
|
||||
RxPackets: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "rxpackets"),
|
||||
"Client Receive Packets", labels, nil,
|
||||
),
|
||||
RxRate: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "rxrate"),
|
||||
"Client Receive Rate", labels, nil,
|
||||
),
|
||||
Signal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "signal"),
|
||||
"Client Signal Strength", labels, nil,
|
||||
),
|
||||
TxBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "txbytes"),
|
||||
"Client Transmit Bytes", labels, nil,
|
||||
),
|
||||
TxBytesR: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "txbytesr"),
|
||||
"Client Transmit Data Rate", labels, nil,
|
||||
),
|
||||
TxPackets: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "txpackets"),
|
||||
"Client Transmit Packets", labels, nil,
|
||||
),
|
||||
TxPower: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "txpower"),
|
||||
"Client Transmit Power", labels, nil,
|
||||
),
|
||||
TxRate: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "txrate"),
|
||||
"Client Transmit Rate", labels, nil,
|
||||
),
|
||||
Uptime: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "uptime"),
|
||||
"Client Uptime", labels, nil,
|
||||
),
|
||||
WifiTxAttempts: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "wifitxattempts"),
|
||||
"Client Wifi Transmit Attempts", labels, nil,
|
||||
),
|
||||
WiredRxBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "wiredrxbytes"),
|
||||
"Client Wired Receive Bytes", labels, nil,
|
||||
),
|
||||
WiredRxBytesR: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "wiredrxbytesr"),
|
||||
"Client Wired Receive Data Rate", labels, nil,
|
||||
),
|
||||
WiredRxPackets: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "wiredrxpackets"),
|
||||
"Client Wired Receive Packets", labels, nil,
|
||||
),
|
||||
WiredTxBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "wiredtxbytes"),
|
||||
"Client Wired Transmit Bytes", labels, nil,
|
||||
),
|
||||
WiredTxBytesR: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "wiredtxbytesr"),
|
||||
"Client Wired Data Rate", labels, nil,
|
||||
),
|
||||
WiredTxPackets: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "wiredtxpackets"),
|
||||
"Client Wired Transmit Packets", labels, nil,
|
||||
),
|
||||
DpiStatsApp: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "dpistatsapp"),
|
||||
"Client DPI Stats App", labels, nil,
|
||||
),
|
||||
DpiStatsCat: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "dpistatscat"),
|
||||
"Client DPI Stats Cat", labels, nil,
|
||||
),
|
||||
DpiStatsRxBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "dpistatsrxbytes"),
|
||||
"Client DPI Stats Receive Bytes", labels, nil,
|
||||
),
|
||||
DpiStatsRxPackets: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "dpistatsrxpackets"),
|
||||
"Client DPI Stats Receive Packets", labels, nil,
|
||||
),
|
||||
DpiStatsTxBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "dpistatstxbytes"),
|
||||
"Client DPI Stats Transmit Bytes", labels, nil,
|
||||
),
|
||||
DpiStatsTxPackets: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(ns, ns2, "dpistatstxpackets"),
|
||||
"Client DPI Stats Transmit Packets", labels, nil,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// CollectClient exports Clients' Data
|
||||
func (u *unifiCollector) exportClient(c *unifi.Client) []*metricExports {
|
||||
labels := []string{c.ID, c.Mac, c.UserID, c.SiteID, c.SiteName,
|
||||
c.NetworkID, c.ApMac, c.GwMac, c.SwMac, c.ApName, c.GwName,
|
||||
c.SwName, c.RadioName, c.Radio, c.RadioProto, c.Name, c.Channel.Txt,
|
||||
c.Vlan.Txt, c.IP, c.Essid, c.Bssid, c.RadioDescription,
|
||||
}
|
||||
|
||||
return []*metricExports{
|
||||
{u.Client.Anomalies, prometheus.CounterValue, c.Anomalies, labels},
|
||||
{u.Client.Anomalies, prometheus.CounterValue, c.Anomalies, labels},
|
||||
{u.Client.BytesR, prometheus.GaugeValue, c.BytesR, labels},
|
||||
{u.Client.CCQ, prometheus.GaugeValue, c.Ccq, labels},
|
||||
{u.Client.Noise, prometheus.GaugeValue, c.Noise, labels},
|
||||
{u.Client.RoamCount, prometheus.CounterValue, c.RoamCount, labels},
|
||||
{u.Client.RSSI, prometheus.GaugeValue, c.Rssi, labels},
|
||||
{u.Client.RxBytes, prometheus.CounterValue, c.RxBytes, labels},
|
||||
{u.Client.RxBytesR, prometheus.GaugeValue, c.RxBytesR, labels},
|
||||
{u.Client.RxPackets, prometheus.CounterValue, c.RxPackets, labels},
|
||||
{u.Client.RxRate, prometheus.GaugeValue, c.RxRate, labels},
|
||||
{u.Client.Signal, prometheus.GaugeValue, c.Signal, labels},
|
||||
{u.Client.TxBytes, prometheus.CounterValue, c.TxBytes, labels},
|
||||
{u.Client.TxBytesR, prometheus.GaugeValue, c.TxBytesR, labels},
|
||||
{u.Client.TxPackets, prometheus.CounterValue, c.TxPackets, labels},
|
||||
{u.Client.TxPower, prometheus.GaugeValue, c.TxPower, labels},
|
||||
{u.Client.TxRate, prometheus.CounterValue, c.TxRate, labels},
|
||||
{u.Client.Uptime, prometheus.GaugeValue, c.Uptime, labels},
|
||||
{u.Client.WifiTxAttempts, prometheus.CounterValue, c.WifiTxAttempts, labels},
|
||||
{u.Client.WiredRxBytes, prometheus.CounterValue, c.WiredRxBytes, labels},
|
||||
{u.Client.WiredRxBytesR, prometheus.GaugeValue, c.WiredRxBytesR, labels},
|
||||
{u.Client.WiredRxPackets, prometheus.CounterValue, c.WiredRxPackets, labels},
|
||||
{u.Client.WiredTxBytes, prometheus.CounterValue, c.TxRate, labels},
|
||||
{u.Client.WiredTxBytesR, prometheus.GaugeValue, c.WiredTxBytesR, labels},
|
||||
{u.Client.WiredTxPackets, prometheus.CounterValue, c.WiredTxPackets, labels},
|
||||
{u.Client.DpiStatsApp, prometheus.GaugeValue, c.DpiStats.App, labels},
|
||||
{u.Client.DpiStatsCat, prometheus.GaugeValue, c.DpiStats.Cat, labels},
|
||||
{u.Client.DpiStatsRxBytes, prometheus.CounterValue, c.DpiStats.RxBytes, labels},
|
||||
{u.Client.DpiStatsRxPackets, prometheus.CounterValue, c.DpiStats.RxPackets, labels},
|
||||
{u.Client.DpiStatsTxBytes, prometheus.CounterValue, c.DpiStats.TxBytes, labels},
|
||||
{u.Client.DpiStatsTxPackets, prometheus.CounterValue, c.DpiStats.TxPackets, labels},
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
package promunifi
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/davidnewhall/unifi-poller/metrics"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// UnifiCollectorOpts defines the data needed to collect and report UniFi Metrics.
|
||||
type UnifiCollectorOpts struct {
|
||||
// If non-empty, each of the collected metrics is prefixed by the
|
||||
// provided string and an underscore ("_").
|
||||
Namespace string
|
||||
// If true, any error encountered during collection is reported as an
|
||||
// invalid metric (see NewInvalidMetric). Otherwise, errors are ignored
|
||||
// and the collected metrics will be incomplete. (Possibly, no metrics
|
||||
// will be collected at all.)
|
||||
ReportErrors bool
|
||||
// This function is passed to the Collect() method. The Collect method runs This
|
||||
// function to retreive the latest UniFi
|
||||
CollectFn func() *metrics.Metrics
|
||||
// Setting this to true will enable IDS exports.
|
||||
CollectIDS bool
|
||||
}
|
||||
|
||||
type unifiCollector struct {
|
||||
opts UnifiCollectorOpts
|
||||
Client *client
|
||||
// UAP *UAP
|
||||
// USG *USG
|
||||
// USW *USW
|
||||
// UDM *UDM
|
||||
// IDS *IDS
|
||||
// Site *Site
|
||||
}
|
||||
|
||||
type metricExports struct {
|
||||
Desc *prometheus.Desc
|
||||
ValueType prometheus.ValueType
|
||||
Value interface{}
|
||||
Labels []string
|
||||
}
|
||||
|
||||
// NewUnifiCollector returns a prometheus collector that will export any available
|
||||
// UniFi metrics. You must provide a collection function in the opts.
|
||||
func NewUnifiCollector(opts UnifiCollectorOpts) prometheus.Collector {
|
||||
if opts.CollectFn == nil {
|
||||
panic("nil collector function")
|
||||
}
|
||||
return &unifiCollector{
|
||||
opts: opts,
|
||||
Client: descClient(opts.Namespace),
|
||||
// UAP: descUAP(opts.Namespace),
|
||||
// USG: descUSG(opts.Namespace),
|
||||
// USW: descUSW(opts.Namespace),
|
||||
// UDM: descUDM(opts.Namespace),
|
||||
// Site: descSite(opts.Namespace),
|
||||
// IDS: descIDS(opts.Namespace),
|
||||
}
|
||||
}
|
||||
|
||||
// Describe satisfies the prometheus Collector. This returns all of the
|
||||
// metric descriptions that this packages produces.
|
||||
func (u *unifiCollector) Describe(ch chan<- *prometheus.Desc) {
|
||||
describe := func(from interface{}) {
|
||||
v := reflect.ValueOf(from)
|
||||
// Loop each struct member and send it to the provided channel.
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
desc, ok := v.Field(i).Interface().(*prometheus.Desc)
|
||||
if ok && desc != nil {
|
||||
ch <- desc
|
||||
}
|
||||
}
|
||||
}
|
||||
describe(u.Client)
|
||||
// describe(u.UAP)
|
||||
// describe(u.USG)
|
||||
// describe(u.USW)
|
||||
// describe(u.UDM)
|
||||
// describe(u.Site)
|
||||
// if u.opts.CollectIDS {
|
||||
// describe(u.IDS)
|
||||
// }
|
||||
}
|
||||
|
||||
// Collect satisifes the prometheus Collector. This runs the input method to get
|
||||
// the current metrics (from another package) then exports them for prometheus.
|
||||
func (u *unifiCollector) Collect(ch chan<- prometheus.Metric) {
|
||||
m := u.opts.CollectFn()
|
||||
|
||||
for _, asset := range m.Clients {
|
||||
u.export(ch, u.exportClient(asset), m.TS)
|
||||
}
|
||||
for _, asset := range m.Sites {
|
||||
u.export(ch, u.exportSite(asset), m.TS)
|
||||
}
|
||||
if u.opts.CollectIDS {
|
||||
for _, asset := range m.IDSList {
|
||||
u.export(ch, u.exportIDS(asset), m.TS)
|
||||
}
|
||||
}
|
||||
|
||||
if m.Devices == nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, asset := range m.Devices.UAPs {
|
||||
u.export(ch, u.exportUAP(asset), m.TS)
|
||||
}
|
||||
for _, asset := range m.Devices.USGs {
|
||||
u.export(ch, u.exportUSG(asset), m.TS)
|
||||
}
|
||||
for _, asset := range m.Devices.USWs {
|
||||
u.export(ch, u.exportUSW(asset), m.TS)
|
||||
}
|
||||
for _, asset := range m.Devices.UDMs {
|
||||
u.export(ch, u.exportUDM(asset), m.TS)
|
||||
}
|
||||
}
|
||||
|
||||
func (u *unifiCollector) export(ch chan<- prometheus.Metric, exports []*metricExports, ts time.Time) {
|
||||
for _, e := range exports {
|
||||
v, ok := e.Value.(float64)
|
||||
if !ok {
|
||||
if u.opts.ReportErrors {
|
||||
ch <- prometheus.NewInvalidMetric(e.Desc, fmt.Errorf("not a number"))
|
||||
}
|
||||
return
|
||||
}
|
||||
ch <- prometheus.NewMetricWithTimestamp(ts, prometheus.MustNewConstMetric(e.Desc, e.ValueType, v, e.Labels...))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package promunifi
|
||||
|
||||
import (
|
||||
"golift.io/unifi"
|
||||
)
|
||||
|
||||
// exportIDS exports Intrusion Detection System Data
|
||||
func (u *unifiCollector) exportIDS(i *unifi.IDS) []*metricExports {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package promunifi
|
||||
|
||||
import (
|
||||
"golift.io/unifi"
|
||||
)
|
||||
|
||||
// exportSite exports Network Site Data
|
||||
func (u *unifiCollector) exportSite(s *unifi.Site) []*metricExports {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package promunifi
|
||||
|
||||
import (
|
||||
"golift.io/unifi"
|
||||
)
|
||||
|
||||
// exportUAP exports Access Point Data
|
||||
func (u *unifiCollector) exportUAP(a *unifi.UAP) []*metricExports {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package promunifi
|
||||
|
||||
import (
|
||||
"golift.io/unifi"
|
||||
)
|
||||
|
||||
// exportUDM exports UniFi Dream Machine (and Pro) Data
|
||||
func (u *unifiCollector) exportUDM(d *unifi.UDM) []*metricExports {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package promunifi
|
||||
|
||||
import (
|
||||
"golift.io/unifi"
|
||||
)
|
||||
|
||||
// exportUSG Exports Security Gateway Data
|
||||
func (u *unifiCollector) exportUSG(s *unifi.USG) []*metricExports {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package promunifi
|
||||
|
||||
import (
|
||||
"golift.io/unifi"
|
||||
)
|
||||
|
||||
// exportUSW exports Network Switch Data
|
||||
func (u *unifiCollector) exportUSW(s *unifi.USW) []*metricExports {
|
||||
return nil
|
||||
}
|
||||
Loading…
Reference in New Issue