From f6c73e7edbce33e403412bbfe7c11a07997fe1a4 Mon Sep 17 00:00:00 2001 From: davidnewhall2 Date: Tue, 12 Nov 2019 00:31:44 -0800 Subject: [PATCH] Rename all the packages --- influx/README.md | 4 ++ {pollerinflux => influx}/clients.go | 2 +- {pollerinflux => influx}/ids.go | 2 +- influx/metrics.go | 75 ++++++++++++++++++++++ {pollerinflux => influx}/site.go | 2 +- {pollerinflux => influx}/uap.go | 2 +- {pollerinflux => influx}/udm.go | 2 +- {pollerinflux => influx}/usg.go | 2 +- {pollerinflux => influx}/usw.go | 2 +- main.go | 4 +- {pollerunifi => poller}/build_macos.go | 2 +- {pollerunifi => poller}/build_unix.go | 2 +- {pollerunifi => poller}/build_windows.go | 2 +- {pollerunifi => poller}/config.go | 12 +--- {pollerunifi => poller}/dumper.go | 5 +- {pollerunifi => poller}/helpers.go | 2 +- {pollerunifi => poller}/start.go | 7 ++- {pollerunifi => poller}/unifi.go | 79 ++++-------------------- prometheus/README.md | 4 ++ 19 files changed, 117 insertions(+), 95 deletions(-) create mode 100644 influx/README.md rename {pollerinflux => influx}/clients.go (99%) rename {pollerinflux => influx}/ids.go (98%) create mode 100644 influx/metrics.go rename {pollerinflux => influx}/site.go (99%) rename {pollerinflux => influx}/uap.go (99%) rename {pollerinflux => influx}/udm.go (99%) rename {pollerinflux => influx}/usg.go (99%) rename {pollerinflux => influx}/usw.go (99%) rename {pollerunifi => poller}/build_macos.go (88%) rename {pollerunifi => poller}/build_unix.go (88%) rename {pollerunifi => poller}/build_windows.go (88%) rename {pollerunifi => poller}/config.go (96%) rename {pollerunifi => poller}/dumper.go (98%) rename {pollerunifi => poller}/helpers.go (98%) rename {pollerunifi => poller}/start.go (95%) rename {pollerunifi => poller}/unifi.go (71%) create mode 100644 prometheus/README.md diff --git a/influx/README.md b/influx/README.md new file mode 100644 index 00000000..cbc606c0 --- /dev/null +++ b/influx/README.md @@ -0,0 +1,4 @@ +# influx + +This package provides the methods to turn UniFi measurements into influx +data-points with appropriate tags and fields. diff --git a/pollerinflux/clients.go b/influx/clients.go similarity index 99% rename from pollerinflux/clients.go rename to influx/clients.go index 45f08e1c..114a9398 100644 --- a/pollerinflux/clients.go +++ b/influx/clients.go @@ -1,4 +1,4 @@ -package pollerinflux +package influx import ( "time" diff --git a/pollerinflux/ids.go b/influx/ids.go similarity index 98% rename from pollerinflux/ids.go rename to influx/ids.go index 740f66be..33f743ba 100644 --- a/pollerinflux/ids.go +++ b/influx/ids.go @@ -1,4 +1,4 @@ -package pollerinflux +package influx import ( influx "github.com/influxdata/influxdb1-client/v2" diff --git a/influx/metrics.go b/influx/metrics.go new file mode 100644 index 00000000..7eb49495 --- /dev/null +++ b/influx/metrics.go @@ -0,0 +1,75 @@ +// Package influx provides the methods to turn UniFi measurements into influx +// data-points with appropriate tags and fields. +package influx + +import ( + "time" + + client "github.com/influxdata/influxdb1-client/v2" + "golift.io/unifi" +) + +// Metrics contains all the data from the controller and an influx endpoint to send it to. +type Metrics struct { + TS time.Time + unifi.Sites + unifi.IDSList + unifi.Clients + *unifi.Devices + client.BatchPoints +} + +// ProcessPoints batches all device and client data into influxdb data points. +// Call this after you've collected all the data you care about. +// This function is sorta weird and returns a slice of errors. The reasoning is +// that some points may process while others fail, so we attempt to process them +// all. This is (usually) run in a loop, so we can't really exit on error, +// we just log the errors and tally them on a counter. In reality, this never +// returns any errors because we control the data going in; cool right? But we +// still check&log it in case the data going is skewed up and causes errors! +func (m *Metrics) ProcessPoints() []error { + errs := []error{} + processPoints := func(m *Metrics, p []*client.Point, err error) { + switch { + case err != nil: + errs = append(errs, err) + case p == nil: + default: + m.BatchPoints.AddPoints(p) + } + } + + for _, asset := range m.Sites { + pts, err := SitePoints(asset, m.TS) + processPoints(m, pts, err) + } + for _, asset := range m.Clients { + pts, err := ClientPoints(asset, m.TS) + processPoints(m, pts, err) + } + for _, asset := range m.IDSList { + pts, err := IDSPoints(asset) // no m.TS. + processPoints(m, pts, err) + } + + if m.Devices == nil { + return errs + } + for _, asset := range m.Devices.UAPs { + pts, err := UAPPoints(asset, m.TS) + processPoints(m, pts, err) + } + for _, asset := range m.Devices.USGs { + pts, err := USGPoints(asset, m.TS) + processPoints(m, pts, err) + } + for _, asset := range m.Devices.USWs { + pts, err := USWPoints(asset, m.TS) + processPoints(m, pts, err) + } + for _, asset := range m.Devices.UDMs { + pts, err := UDMPoints(asset, m.TS) + processPoints(m, pts, err) + } + return errs +} diff --git a/pollerinflux/site.go b/influx/site.go similarity index 99% rename from pollerinflux/site.go rename to influx/site.go index 0f12bbe4..78619024 100644 --- a/pollerinflux/site.go +++ b/influx/site.go @@ -1,4 +1,4 @@ -package pollerinflux +package influx import ( "strings" diff --git a/pollerinflux/uap.go b/influx/uap.go similarity index 99% rename from pollerinflux/uap.go rename to influx/uap.go index fc0668ff..02394e7c 100644 --- a/pollerinflux/uap.go +++ b/influx/uap.go @@ -1,4 +1,4 @@ -package pollerinflux +package influx import ( "time" diff --git a/pollerinflux/udm.go b/influx/udm.go similarity index 99% rename from pollerinflux/udm.go rename to influx/udm.go index 54d66389..2bbff525 100644 --- a/pollerinflux/udm.go +++ b/influx/udm.go @@ -1,4 +1,4 @@ -package pollerinflux +package influx import ( "time" diff --git a/pollerinflux/usg.go b/influx/usg.go similarity index 99% rename from pollerinflux/usg.go rename to influx/usg.go index 40c92233..8b358d0b 100644 --- a/pollerinflux/usg.go +++ b/influx/usg.go @@ -1,4 +1,4 @@ -package pollerinflux +package influx import ( "strings" diff --git a/pollerinflux/usw.go b/influx/usw.go similarity index 99% rename from pollerinflux/usw.go rename to influx/usw.go index aa608bb8..f2d1f9ea 100644 --- a/pollerinflux/usw.go +++ b/influx/usw.go @@ -1,4 +1,4 @@ -package pollerinflux +package influx import ( "time" diff --git a/main.go b/main.go index f3d3178f..c9ec4f3c 100644 --- a/main.go +++ b/main.go @@ -3,12 +3,12 @@ package main import ( "log" - "github.com/davidnewhall/unifi-poller/pollerunifi" + "github.com/davidnewhall/unifi-poller/poller" ) // Keep it simple. func main() { - if err := pollerunifi.Start(); err != nil { + if err := poller.Start(); err != nil { log.Fatalln("[ERROR]", err) } } diff --git a/pollerunifi/build_macos.go b/poller/build_macos.go similarity index 88% rename from pollerunifi/build_macos.go rename to poller/build_macos.go index 373263a3..1ab32471 100644 --- a/pollerunifi/build_macos.go +++ b/poller/build_macos.go @@ -1,6 +1,6 @@ // +build darwin -package pollerunifi +package poller // DefaultConfFile is where to find config is --config is not prvided. const DefaultConfFile = "/usr/local/etc/unifi-poller/up.conf" diff --git a/pollerunifi/build_unix.go b/poller/build_unix.go similarity index 88% rename from pollerunifi/build_unix.go rename to poller/build_unix.go index 8be9e240..c1001ac9 100644 --- a/pollerunifi/build_unix.go +++ b/poller/build_unix.go @@ -1,6 +1,6 @@ // +build !windows,!darwin -package pollerunifi +package poller // DefaultConfFile is where to find config is --config is not prvided. const DefaultConfFile = "/etc/unifi-poller/up.conf" diff --git a/pollerunifi/build_windows.go b/poller/build_windows.go similarity index 88% rename from pollerunifi/build_windows.go rename to poller/build_windows.go index 2a0538a7..5c31504f 100644 --- a/pollerunifi/build_windows.go +++ b/poller/build_windows.go @@ -1,6 +1,6 @@ // +build windows -package pollerunifi +package poller // DefaultConfFile is where to find config is --config is not prvided. const DefaultConfFile = `C:\ProgramData\unifi-poller\up.conf` diff --git a/pollerunifi/config.go b/poller/config.go similarity index 96% rename from pollerunifi/config.go rename to poller/config.go index 8953c2f5..58ef0f9b 100644 --- a/pollerunifi/config.go +++ b/poller/config.go @@ -1,4 +1,4 @@ -package pollerunifi +package poller import ( "encoding/json" @@ -56,16 +56,6 @@ type Flag struct { *pflag.FlagSet } -// Metrics contains all the data from the controller and an influx endpoint to send it to. -type Metrics struct { - TS time.Time - unifi.Sites - unifi.IDSList - unifi.Clients - *unifi.Devices - influx.BatchPoints -} - // Config represents the data needed to poll a controller and report to influxdb. // This is all of the data stored in the config file. // Any with explicit defaults have omitempty on json and toml tags. diff --git a/pollerunifi/dumper.go b/poller/dumper.go similarity index 98% rename from pollerunifi/dumper.go rename to poller/dumper.go index 8d20e217..da825485 100644 --- a/pollerunifi/dumper.go +++ b/poller/dumper.go @@ -1,4 +1,4 @@ -package pollerunifi +package poller import ( "fmt" @@ -20,14 +20,17 @@ func (u *UnifiPoller) DumpJSONPayload() (err error) { if err != nil { return err } + fmt.Fprintf(os.Stderr, "[INFO] Authenticated to UniFi Controller @ %v as user %v", u.Config.UnifiBase, u.Config.UnifiUser) if err := u.CheckSites(); err != nil { return err } + u.Unifi.ErrorLog = func(m string, v ...interface{}) { fmt.Fprintf(os.Stderr, "[ERROR] "+m, v...) } // Log all errors to stderr. + switch sites, err := u.GetFilteredSites(); { case err != nil: return err diff --git a/pollerunifi/helpers.go b/poller/helpers.go similarity index 98% rename from pollerunifi/helpers.go rename to poller/helpers.go index 6583daa7..3ac9bf4d 100644 --- a/pollerunifi/helpers.go +++ b/poller/helpers.go @@ -1,4 +1,4 @@ -package pollerunifi +package poller import ( "fmt" diff --git a/pollerunifi/start.go b/poller/start.go similarity index 95% rename from pollerunifi/start.go rename to poller/start.go index ae5c48cb..d9cbf8a8 100644 --- a/pollerunifi/start.go +++ b/poller/start.go @@ -1,4 +1,5 @@ -package pollerunifi +// Package poller provides the CLI interface to setup unifi-poller. +package poller import ( "crypto/tls" @@ -9,7 +10,7 @@ import ( "strings" "time" - influx "github.com/influxdata/influxdb1-client/v2" + client "github.com/influxdata/influxdb1-client/v2" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/spf13/pflag" "golift.io/unifi" @@ -113,7 +114,7 @@ func (u *UnifiPoller) Run() (err error) { // GetInfluxDB returns an InfluxDB interface. func (u *UnifiPoller) GetInfluxDB() (err error) { - u.Influx, err = influx.NewHTTPClient(influx.HTTPConfig{ + u.Influx, err = client.NewHTTPClient(client.HTTPConfig{ Addr: u.Config.InfluxURL, Username: u.Config.InfluxUser, Password: u.Config.InfluxPass, diff --git a/pollerunifi/unifi.go b/poller/unifi.go similarity index 71% rename from pollerunifi/unifi.go rename to poller/unifi.go index fe1db125..4e78ed19 100644 --- a/pollerunifi/unifi.go +++ b/poller/unifi.go @@ -1,4 +1,4 @@ -package pollerunifi +package poller import ( "fmt" @@ -6,8 +6,8 @@ import ( "strings" "time" - "github.com/davidnewhall/unifi-poller/pollerinflux" - influx "github.com/influxdata/influxdb1-client/v2" + "github.com/davidnewhall/unifi-poller/influx" + client "github.com/influxdata/influxdb1-client/v2" "golift.io/unifi" ) @@ -47,7 +47,7 @@ FIRST: // PollController runs forever, polling UniFi // and pushing to influx OR exporting for prometheus. // This is started by Run() after everything checks out. -func (u *UnifiPoller) PollController(process func(*Metrics) error) error { +func (u *UnifiPoller) PollController(process func(*influx.Metrics) error) error { interval := u.Config.Interval.Round(time.Second) log.Printf("[INFO] Everything checks out! Poller started in %v mode, interval: %v", u.Config.Mode, interval) ticker := time.NewTicker(interval) @@ -77,7 +77,7 @@ func (u *UnifiPoller) PollController(process func(*Metrics) error) error { // handle their own logging. An error is returned so the calling function may // determine if there was a read or write error and act on it. This is currently // called in two places in this library. One returns an error, one does not. -func (u *UnifiPoller) CollectAndProcess(process func(*Metrics) error) error { +func (u *UnifiPoller) CollectAndProcess(process func(*influx.Metrics) error) error { metrics, err := u.CollectMetrics() if err != nil { return err @@ -92,8 +92,8 @@ func (u *UnifiPoller) CollectAndProcess(process func(*Metrics) error) error { // CollectMetrics grabs all the measurements from a UniFi controller and returns them. // This also creates an InfluxDB writer, and returns an error if that fails. -func (u *UnifiPoller) CollectMetrics() (*Metrics, error) { - m := &Metrics{TS: u.LastCheck} // At this point, it's the Current Check. +func (u *UnifiPoller) CollectMetrics() (*influx.Metrics, error) { + m := &influx.Metrics{TS: u.LastCheck} // At this point, it's the Current Check. var err error // Get the sites we care about. m.Sites, err = u.GetFilteredSites() @@ -109,7 +109,7 @@ func (u *UnifiPoller) CollectMetrics() (*Metrics, error) { m.Devices, err = u.Unifi.GetDevices(m.Sites) u.LogError(err, "unifi.GetDevices()") // Make a new Influx Points Batcher. - m.BatchPoints, err = influx.NewBatchPoints(influx.BatchPointsConfig{Database: u.Config.InfluxDB}) + m.BatchPoints, err = client.NewBatchPoints(client.BatchPointsConfig{Database: u.Config.InfluxDB}) u.LogError(err, "influx.NewBatchPoints") return m, err } @@ -117,7 +117,7 @@ func (u *UnifiPoller) CollectMetrics() (*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) error { +func (u *UnifiPoller) AugmentMetrics(metrics *influx.Metrics) error { if metrics == nil || metrics.Devices == nil || metrics.Clients == nil { return fmt.Errorf("nil metrics, augment impossible") } @@ -150,7 +150,7 @@ func (u *UnifiPoller) AugmentMetrics(metrics *Metrics) error { // ExportMetrics updates the internal metrics provided via // HTTP at /metrics for prometheus collection. -func (u *UnifiPoller) ExportMetrics(metrics *Metrics) error { +func (u *UnifiPoller) ExportMetrics(metrics *influx.Metrics) error { /* This is where it gets complicated, and probably deserves its own package. */ @@ -159,10 +159,10 @@ func (u *UnifiPoller) ExportMetrics(metrics *Metrics) error { // ReportMetrics batches all the metrics and writes them to InfluxDB. // Returns an error if the write to influx fails. -func (u *UnifiPoller) ReportMetrics(metrics *Metrics) error { +func (u *UnifiPoller) ReportMetrics(metrics *influx.Metrics) error { // Batch (and send) all the points. for _, err := range metrics.ProcessPoints() { - u.LogError(err, "asset.Points()") + u.LogError(err, "metrics.ProcessPoints") } err := u.Influx.Write(metrics.BatchPoints) if err != nil { @@ -185,61 +185,6 @@ func (u *UnifiPoller) ReportMetrics(metrics *Metrics) error { return nil } -// ProcessPoints batches all device and client data into influxdb data points. -// Call this after you've collected all the data you care about. -// This function is sorta weird and returns a slice of errors. The reasoning is -// that some points may process while others fail, so we attempt to process them -// all. This is (usually) run in a loop, so we can't really exit on error, -// we just log the errors and tally them on a counter. In reality, this never -// returns any errors because we control the data going in; cool right? But we -// still check&log it in case the data going is skewed up and causes errors! -func (m *Metrics) ProcessPoints() []error { - errs := []error{} - processPoints := func(m *Metrics, p []*influx.Point, err error) { - switch { - case err != nil: - errs = append(errs, err) - case p == nil: - default: - m.BatchPoints.AddPoints(p) - } - } - - for _, asset := range m.Sites { - pts, err := pollerinflux.SitePoints(asset, m.TS) - processPoints(m, pts, err) - } - for _, asset := range m.Clients { - pts, err := pollerinflux.ClientPoints(asset, m.TS) - processPoints(m, pts, err) - } - for _, asset := range m.IDSList { - pts, err := pollerinflux.IDSPoints(asset) // no m.TS. - processPoints(m, pts, err) - } - - if m.Devices == nil { - return errs - } - for _, asset := range m.Devices.UAPs { - pts, err := pollerinflux.UAPPoints(asset, m.TS) - processPoints(m, pts, err) - } - for _, asset := range m.Devices.USGs { - pts, err := pollerinflux.USGPoints(asset, m.TS) - processPoints(m, pts, err) - } - for _, asset := range m.Devices.USWs { - pts, err := pollerinflux.USWPoints(asset, m.TS) - processPoints(m, pts, err) - } - for _, asset := range m.Devices.UDMs { - pts, err := pollerinflux.UDMPoints(asset, m.TS) - processPoints(m, pts, err) - } - return errs -} - // GetFilteredSites returns a list of sites to fetch data for. // Omits requested but unconfigured sites. Grabs the full list from the // controller and returns the sites provided in the config file. diff --git a/prometheus/README.md b/prometheus/README.md new file mode 100644 index 00000000..f883cfd4 --- /dev/null +++ b/prometheus/README.md @@ -0,0 +1,4 @@ +# prometheus + +This package provides the methods to turn UniFi measurements into prometheus +exported metrics with an HTTP listener.