Rename all the packages
This commit is contained in:
parent
641095f2af
commit
f6c73e7edb
|
|
@ -0,0 +1,4 @@
|
||||||
|
# influx
|
||||||
|
|
||||||
|
This package provides the methods to turn UniFi measurements into influx
|
||||||
|
data-points with appropriate tags and fields.
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package pollerinflux
|
package influx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package pollerinflux
|
package influx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
influx "github.com/influxdata/influxdb1-client/v2"
|
influx "github.com/influxdata/influxdb1-client/v2"
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package pollerinflux
|
package influx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package pollerinflux
|
package influx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package pollerinflux
|
package influx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package pollerinflux
|
package influx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package pollerinflux
|
package influx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
4
main.go
4
main.go
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
@ -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"
|
||||||
|
|
@ -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`
|
||||||
|
|
@ -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.
|
||||||
|
|
@ -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
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package pollerunifi
|
package poller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -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,
|
||||||
|
|
@ -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.
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
# prometheus
|
||||||
|
|
||||||
|
This package provides the methods to turn UniFi measurements into prometheus
|
||||||
|
exported metrics with an HTTP listener.
|
||||||
Loading…
Reference in New Issue