Rename all the packages

This commit is contained in:
davidnewhall2 2019-11-12 00:31:44 -08:00
parent 641095f2af
commit f6c73e7edb
19 changed files with 117 additions and 95 deletions

4
influx/README.md Normal file
View File

@ -0,0 +1,4 @@
# influx
This package provides the methods to turn UniFi measurements into influx
data-points with appropriate tags and fields.

View File

@ -1,4 +1,4 @@
package pollerinflux package influx
import ( import (
"time" "time"

View File

@ -1,4 +1,4 @@
package pollerinflux package influx
import ( import (
influx "github.com/influxdata/influxdb1-client/v2" influx "github.com/influxdata/influxdb1-client/v2"

75
influx/metrics.go Normal file
View File

@ -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
}

View File

@ -1,4 +1,4 @@
package pollerinflux package influx
import ( import (
"strings" "strings"

View File

@ -1,4 +1,4 @@
package pollerinflux package influx
import ( import (
"time" "time"

View File

@ -1,4 +1,4 @@
package pollerinflux package influx
import ( import (
"time" "time"

View File

@ -1,4 +1,4 @@
package pollerinflux package influx
import ( import (
"strings" "strings"

View File

@ -1,4 +1,4 @@
package pollerinflux package influx
import ( import (
"time" "time"

View File

@ -3,12 +3,12 @@ package main
import ( import (
"log" "log"
"github.com/davidnewhall/unifi-poller/pollerunifi" "github.com/davidnewhall/unifi-poller/poller"
) )
// Keep it simple. // Keep it simple.
func main() { func main() {
if err := pollerunifi.Start(); err != nil { if err := poller.Start(); err != nil {
log.Fatalln("[ERROR]", err) log.Fatalln("[ERROR]", err)
} }
} }

View File

@ -1,6 +1,6 @@
// +build darwin // +build darwin
package pollerunifi package poller
// DefaultConfFile is where to find config is --config is not prvided. // DefaultConfFile is where to find config is --config is not prvided.
const DefaultConfFile = "/usr/local/etc/unifi-poller/up.conf" const DefaultConfFile = "/usr/local/etc/unifi-poller/up.conf"

View File

@ -1,6 +1,6 @@
// +build !windows,!darwin // +build !windows,!darwin
package pollerunifi package poller
// DefaultConfFile is where to find config is --config is not prvided. // DefaultConfFile is where to find config is --config is not prvided.
const DefaultConfFile = "/etc/unifi-poller/up.conf" const DefaultConfFile = "/etc/unifi-poller/up.conf"

View File

@ -1,6 +1,6 @@
// +build windows // +build windows
package pollerunifi package poller
// DefaultConfFile is where to find config is --config is not prvided. // DefaultConfFile is where to find config is --config is not prvided.
const DefaultConfFile = `C:\ProgramData\unifi-poller\up.conf` const DefaultConfFile = `C:\ProgramData\unifi-poller\up.conf`

View File

@ -1,4 +1,4 @@
package pollerunifi package poller
import ( import (
"encoding/json" "encoding/json"
@ -56,16 +56,6 @@ type Flag struct {
*pflag.FlagSet *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. // 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.

View File

@ -1,4 +1,4 @@
package pollerunifi package poller
import ( import (
"fmt" "fmt"
@ -20,14 +20,17 @@ func (u *UnifiPoller) DumpJSONPayload() (err error) {
if err != nil { if err != nil {
return err return err
} }
fmt.Fprintf(os.Stderr, "[INFO] Authenticated to UniFi Controller @ %v as user %v", fmt.Fprintf(os.Stderr, "[INFO] Authenticated to UniFi Controller @ %v as user %v",
u.Config.UnifiBase, u.Config.UnifiUser) u.Config.UnifiBase, u.Config.UnifiUser)
if err := u.CheckSites(); err != nil { if err := u.CheckSites(); err != nil {
return err return err
} }
u.Unifi.ErrorLog = func(m string, v ...interface{}) { u.Unifi.ErrorLog = func(m string, v ...interface{}) {
fmt.Fprintf(os.Stderr, "[ERROR] "+m, v...) fmt.Fprintf(os.Stderr, "[ERROR] "+m, v...)
} // Log all errors to stderr. } // Log all errors to stderr.
switch sites, err := u.GetFilteredSites(); { switch sites, err := u.GetFilteredSites(); {
case err != nil: case err != nil:
return err return err

View File

@ -1,4 +1,4 @@
package pollerunifi package poller
import ( import (
"fmt" "fmt"

View File

@ -1,4 +1,5 @@
package pollerunifi // Package poller provides the CLI interface to setup unifi-poller.
package poller
import ( import (
"crypto/tls" "crypto/tls"
@ -9,7 +10,7 @@ import (
"strings" "strings"
"time" "time"
influx "github.com/influxdata/influxdb1-client/v2" client "github.com/influxdata/influxdb1-client/v2"
"github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/spf13/pflag" "github.com/spf13/pflag"
"golift.io/unifi" "golift.io/unifi"
@ -113,7 +114,7 @@ func (u *UnifiPoller) Run() (err error) {
// GetInfluxDB returns an InfluxDB interface. // GetInfluxDB returns an InfluxDB interface.
func (u *UnifiPoller) GetInfluxDB() (err error) { func (u *UnifiPoller) GetInfluxDB() (err error) {
u.Influx, err = influx.NewHTTPClient(influx.HTTPConfig{ u.Influx, err = client.NewHTTPClient(client.HTTPConfig{
Addr: u.Config.InfluxURL, Addr: u.Config.InfluxURL,
Username: u.Config.InfluxUser, Username: u.Config.InfluxUser,
Password: u.Config.InfluxPass, Password: u.Config.InfluxPass,

View File

@ -1,4 +1,4 @@
package pollerunifi package poller
import ( import (
"fmt" "fmt"
@ -6,8 +6,8 @@ import (
"strings" "strings"
"time" "time"
"github.com/davidnewhall/unifi-poller/pollerinflux" "github.com/davidnewhall/unifi-poller/influx"
influx "github.com/influxdata/influxdb1-client/v2" client "github.com/influxdata/influxdb1-client/v2"
"golift.io/unifi" "golift.io/unifi"
) )
@ -47,7 +47,7 @@ FIRST:
// PollController runs forever, polling UniFi // PollController runs forever, polling UniFi
// and pushing to influx OR exporting for prometheus. // and pushing to influx OR exporting for prometheus.
// This is started by Run() after everything checks out. // 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) interval := u.Config.Interval.Round(time.Second)
log.Printf("[INFO] Everything checks out! Poller started in %v mode, interval: %v", u.Config.Mode, interval) log.Printf("[INFO] Everything checks out! Poller started in %v mode, interval: %v", u.Config.Mode, interval)
ticker := time.NewTicker(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 // 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 // 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. // 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() metrics, err := u.CollectMetrics()
if err != nil { if err != nil {
return err 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. // 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. // This also creates an InfluxDB writer, and returns an error if that fails.
func (u *UnifiPoller) CollectMetrics() (*Metrics, error) { func (u *UnifiPoller) CollectMetrics() (*influx.Metrics, error) {
m := &Metrics{TS: u.LastCheck} // At this point, it's the Current Check. m := &influx.Metrics{TS: u.LastCheck} // At this point, it's the Current Check.
var err error var err error
// Get the sites we care about. // Get the sites we care about.
m.Sites, err = u.GetFilteredSites() m.Sites, err = u.GetFilteredSites()
@ -109,7 +109,7 @@ func (u *UnifiPoller) CollectMetrics() (*Metrics, error) {
m.Devices, err = u.Unifi.GetDevices(m.Sites) m.Devices, err = u.Unifi.GetDevices(m.Sites)
u.LogError(err, "unifi.GetDevices()") u.LogError(err, "unifi.GetDevices()")
// Make a new Influx Points Batcher. // 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") u.LogError(err, "influx.NewBatchPoints")
return m, err return m, err
} }
@ -117,7 +117,7 @@ func (u *UnifiPoller) CollectMetrics() (*Metrics, error) {
// AugmentMetrics is our middleware layer between collecting metrics and writing them. // 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 is where we can manipuate the returned data or make arbitrary decisions.
// This function currently adds parent device names to client metrics. // 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 { if metrics == nil || metrics.Devices == nil || metrics.Clients == nil {
return fmt.Errorf("nil metrics, augment impossible") 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 // ExportMetrics updates the internal metrics provided via
// HTTP at /metrics for prometheus collection. // 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. 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. // ReportMetrics batches all the metrics and writes them to InfluxDB.
// Returns an error if the write to influx fails. // 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. // Batch (and send) all the points.
for _, err := range metrics.ProcessPoints() { for _, err := range metrics.ProcessPoints() {
u.LogError(err, "asset.Points()") u.LogError(err, "metrics.ProcessPoints")
} }
err := u.Influx.Write(metrics.BatchPoints) err := u.Influx.Write(metrics.BatchPoints)
if err != nil { if err != nil {
@ -185,61 +185,6 @@ func (u *UnifiPoller) ReportMetrics(metrics *Metrics) error {
return nil 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. // 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.

4
prometheus/README.md Normal file
View File

@ -0,0 +1,4 @@
# prometheus
This package provides the methods to turn UniFi measurements into prometheus
exported metrics with an HTTP listener.