trimming
This commit is contained in:
parent
1ace3e9619
commit
4b5072fd6d
|
|
@ -10,11 +10,12 @@ import (
|
|||
|
||||
"github.com/davidnewhall/unifi-poller/pkg/poller"
|
||||
influx "github.com/influxdata/influxdb1-client/v2"
|
||||
conf "golift.io/config"
|
||||
"golift.io/config"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultInterval = 30 * time.Second
|
||||
minimumInterval = 10 * time.Second
|
||||
defaultInfluxDB = "unifi"
|
||||
defaultInfluxUser = "unifi"
|
||||
defaultInfluxURL = "http://127.0.0.1:8086"
|
||||
|
|
@ -22,13 +23,13 @@ const (
|
|||
|
||||
// Config defines the data needed to store metrics in InfluxDB
|
||||
type Config struct {
|
||||
Interval conf.Duration `json:"interval,omitempty" toml:"interval,omitempty" xml:"interval" yaml:"interval"`
|
||||
Disable bool `json:"disable" toml:"disable" xml:"disable" yaml:"disable"`
|
||||
VerifySSL bool `json:"verify_ssl" toml:"verify_ssl" xml:"verify_ssl" yaml:"verify_ssl"`
|
||||
URL string `json:"url,omitempty" toml:"url,omitempty" xml:"url" yaml:"url"`
|
||||
User string `json:"user,omitempty" toml:"user,omitempty" xml:"user" yaml:"user"`
|
||||
Pass string `json:"pass,omitempty" toml:"pass,omitempty" xml:"pass" yaml:"pass"`
|
||||
DB string `json:"db,omitempty" toml:"db,omitempty" xml:"db" yaml:"db"`
|
||||
Interval config.Duration `json:"interval,omitempty" toml:"interval,omitempty" xml:"interval" yaml:"interval"`
|
||||
Disable bool `json:"disable" toml:"disable" xml:"disable" yaml:"disable"`
|
||||
VerifySSL bool `json:"verify_ssl" toml:"verify_ssl" xml:"verify_ssl" yaml:"verify_ssl"`
|
||||
URL string `json:"url,omitempty" toml:"url,omitempty" xml:"url" yaml:"url"`
|
||||
User string `json:"user,omitempty" toml:"user,omitempty" xml:"user" yaml:"user"`
|
||||
Pass string `json:"pass,omitempty" toml:"pass,omitempty" xml:"pass" yaml:"pass"`
|
||||
DB string `json:"db,omitempty" toml:"db,omitempty" xml:"db" yaml:"db"`
|
||||
}
|
||||
|
||||
// InfluxDB allows the data to be nested in the config file.
|
||||
|
|
@ -63,9 +64,9 @@ func init() {
|
|||
// This is started by Run() or RunBoth() after everything checks out.
|
||||
func (u *InfluxUnifi) PollController() {
|
||||
interval := u.Config.Interval.Round(time.Second)
|
||||
ticker := time.NewTicker(interval)
|
||||
log.Printf("[INFO] Everything checks out! Poller started, InfluxDB interval: %v", interval)
|
||||
|
||||
ticker := time.NewTicker(interval)
|
||||
for u.LastCheck = range ticker.C {
|
||||
metrics, err := u.Collector.Metrics()
|
||||
if err != nil {
|
||||
|
|
@ -128,12 +129,12 @@ func (u *InfluxUnifi) setConfigDefaults() {
|
|||
}
|
||||
|
||||
if u.Config.Interval.Duration == 0 {
|
||||
u.Config.Interval = conf.Duration{Duration: defaultInterval}
|
||||
} else if u.Config.Interval.Duration < defaultInterval/2 {
|
||||
u.Config.Interval = conf.Duration{Duration: defaultInterval / 2}
|
||||
u.Config.Interval = config.Duration{Duration: defaultInterval}
|
||||
} else if u.Config.Interval.Duration < minimumInterval {
|
||||
u.Config.Interval = config.Duration{Duration: minimumInterval}
|
||||
}
|
||||
|
||||
u.Config.Interval = conf.Duration{Duration: u.Config.Interval.Duration.Round(time.Second)}
|
||||
u.Config.Interval = config.Duration{Duration: u.Config.Interval.Duration.Round(time.Second)}
|
||||
}
|
||||
|
||||
// ReportMetrics batches all device and client data into influxdb data points.
|
||||
|
|
@ -179,6 +180,7 @@ func (u *InfluxUnifi) collect(r report, ch chan *metric) {
|
|||
// to the collect routine through the metric channel.
|
||||
func (u *InfluxUnifi) loopPoints(r report) {
|
||||
m := r.metrics()
|
||||
|
||||
r.add()
|
||||
go func() {
|
||||
defer r.done()
|
||||
|
|
@ -186,6 +188,7 @@ func (u *InfluxUnifi) loopPoints(r report) {
|
|||
u.batchSite(r, s)
|
||||
}
|
||||
}()
|
||||
|
||||
r.add()
|
||||
go func() {
|
||||
defer r.done()
|
||||
|
|
@ -193,6 +196,7 @@ func (u *InfluxUnifi) loopPoints(r report) {
|
|||
u.batchClient(r, s)
|
||||
}
|
||||
}()
|
||||
|
||||
r.add()
|
||||
go func() {
|
||||
defer r.done()
|
||||
|
|
@ -200,6 +204,7 @@ func (u *InfluxUnifi) loopPoints(r report) {
|
|||
u.batchIDS(r, s)
|
||||
}
|
||||
}()
|
||||
|
||||
if m.Devices == nil {
|
||||
return
|
||||
}
|
||||
|
|
@ -211,6 +216,7 @@ func (u *InfluxUnifi) loopPoints(r report) {
|
|||
u.batchUAP(r, s)
|
||||
}
|
||||
}()
|
||||
|
||||
r.add()
|
||||
go func() {
|
||||
defer r.done()
|
||||
|
|
@ -218,6 +224,7 @@ func (u *InfluxUnifi) loopPoints(r report) {
|
|||
u.batchUSG(r, s)
|
||||
}
|
||||
}()
|
||||
|
||||
r.add()
|
||||
go func() {
|
||||
defer r.done()
|
||||
|
|
@ -225,6 +232,7 @@ func (u *InfluxUnifi) loopPoints(r report) {
|
|||
u.batchUSW(r, s)
|
||||
}
|
||||
}()
|
||||
|
||||
r.add()
|
||||
go func() {
|
||||
defer r.done()
|
||||
|
|
|
|||
|
|
@ -31,13 +31,13 @@ const ENVConfigPrefix = "UP"
|
|||
|
||||
// UnifiPoller contains the application startup data, and auth info for UniFi & Influx.
|
||||
type UnifiPoller struct {
|
||||
Flag *Flag
|
||||
Flags *Flags
|
||||
Config *Config
|
||||
sync.Mutex // locks the Unifi struct member when re-authing to unifi.
|
||||
}
|
||||
|
||||
// Flag represents the CLI args available and their settings.
|
||||
type Flag struct {
|
||||
// Flags represents the CLI args available and their settings.
|
||||
type Flags struct {
|
||||
ConfigFile string
|
||||
DumpJSON string
|
||||
ShowVer bool
|
||||
|
|
@ -84,8 +84,8 @@ type Poller struct {
|
|||
// ParseConfigs parses the poller config and the config for each registered output plugin.
|
||||
func (u *UnifiPoller) ParseConfigs() error {
|
||||
// Parse config file.
|
||||
if err := config.ParseFile(u.Config, u.Flag.ConfigFile); err != nil {
|
||||
u.Flag.Usage()
|
||||
if err := config.ParseFile(u.Config, u.Flags.ConfigFile); err != nil {
|
||||
u.Flags.Usage()
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -99,7 +99,7 @@ func (u *UnifiPoller) ParseConfigs() error {
|
|||
|
||||
for _, o := range outputs {
|
||||
// Parse config file for each output plugin.
|
||||
if err := config.ParseFile(o.Config, u.Flag.ConfigFile); err != nil {
|
||||
if err := config.ParseFile(o.Config, u.Flags.ConfigFile); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,12 +37,12 @@ func (u *UnifiPoller) DumpJSONPayload() (err error) {
|
|||
switch sites, err := u.GetFilteredSites(config); {
|
||||
case err != nil:
|
||||
return err
|
||||
case StringInSlice(u.Flag.DumpJSON, []string{"d", "device", "devices"}):
|
||||
case StringInSlice(u.Flags.DumpJSON, []string{"d", "device", "devices"}):
|
||||
return u.dumpSitesJSON(config, unifi.APIDevicePath, "Devices", sites)
|
||||
case StringInSlice(u.Flag.DumpJSON, []string{"client", "clients", "c"}):
|
||||
case StringInSlice(u.Flags.DumpJSON, []string{"client", "clients", "c"}):
|
||||
return u.dumpSitesJSON(config, unifi.APIClientPath, "Clients", sites)
|
||||
case strings.HasPrefix(u.Flag.DumpJSON, "other "):
|
||||
apiPath := strings.SplitN(u.Flag.DumpJSON, " ", 2)[1]
|
||||
case strings.HasPrefix(u.Flags.DumpJSON, "other "):
|
||||
apiPath := strings.SplitN(u.Flags.DumpJSON, " ", 2)[1]
|
||||
_, _ = fmt.Fprintf(os.Stderr, "[INFO] Dumping Path '%s':\n", apiPath)
|
||||
return u.PrintRawAPIJSON(config, apiPath)
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ func (u *UnifiPoller) InitializeOutputs() error {
|
|||
}
|
||||
|
||||
if count < 1 {
|
||||
return fmt.Errorf("no output plugins configured")
|
||||
return fmt.Errorf("no output plugins imported")
|
||||
}
|
||||
|
||||
for err := range v {
|
||||
|
|
@ -64,7 +64,7 @@ func (u *UnifiPoller) InitializeOutputs() error {
|
|||
}
|
||||
|
||||
if count--; count < 1 {
|
||||
return fmt.Errorf("all output plugins have stopped")
|
||||
return fmt.Errorf("all output plugins have stopped, or none enabled")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,15 +10,9 @@ import (
|
|||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
// New returns a new poller struct preloaded with default values.
|
||||
// No need to call this if you call Start.c
|
||||
// New returns a new poller struct.
|
||||
func New() *UnifiPoller {
|
||||
return &UnifiPoller{
|
||||
Config: &Config{},
|
||||
Flag: &Flag{
|
||||
ConfigFile: DefaultConfFile,
|
||||
},
|
||||
}
|
||||
return &UnifiPoller{Config: &Config{}, Flags: &Flags{}}
|
||||
}
|
||||
|
||||
// Start begins the application from a CLI.
|
||||
|
|
@ -27,15 +21,15 @@ func New() *UnifiPoller {
|
|||
func (u *UnifiPoller) Start() error {
|
||||
log.SetOutput(os.Stdout)
|
||||
log.SetFlags(log.LstdFlags)
|
||||
u.Flag.Parse(os.Args[1:])
|
||||
u.Flags.Parse(os.Args[1:])
|
||||
|
||||
if u.Flag.ShowVer {
|
||||
if u.Flags.ShowVer {
|
||||
fmt.Printf("%s v%s\n", AppName, version.Version)
|
||||
return nil // don't run anything else w/ version request.
|
||||
}
|
||||
|
||||
if u.Flag.DumpJSON == "" { // do not print this when dumping JSON.
|
||||
u.Logf("Loading Configuration File: %s", u.Flag.ConfigFile)
|
||||
if u.Flags.DumpJSON == "" { // do not print this when dumping JSON.
|
||||
u.Logf("Loading Configuration File: %s", u.Flags.ConfigFile)
|
||||
}
|
||||
|
||||
// Parse config file and ENV variables.
|
||||
|
|
@ -53,7 +47,7 @@ func (u *UnifiPoller) Start() error {
|
|||
}}
|
||||
}
|
||||
|
||||
if u.Flag.DumpJSON != "" {
|
||||
if u.Flags.DumpJSON != "" {
|
||||
return u.DumpJSONPayload()
|
||||
}
|
||||
|
||||
|
|
@ -66,7 +60,7 @@ func (u *UnifiPoller) Start() error {
|
|||
}
|
||||
|
||||
// Parse turns CLI arguments into data structures. Called by Start() on startup.
|
||||
func (f *Flag) Parse(args []string) {
|
||||
func (f *Flags) Parse(args []string) {
|
||||
f.FlagSet = pflag.NewFlagSet(AppName, pflag.ExitOnError)
|
||||
f.Usage = func() {
|
||||
fmt.Printf("Usage: %s [--config=/path/to/up.conf] [--version]", AppName)
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ type metric struct {
|
|||
|
||||
// Report accumulates counters that are printed to a log line.
|
||||
type Report struct {
|
||||
Config
|
||||
Total int // Total count of metrics recorded.
|
||||
Errors int // Total count of errors recording metrics.
|
||||
Zeros int // Total count of metrics equal to zero.
|
||||
|
|
@ -74,7 +75,6 @@ type Report struct {
|
|||
Start time.Time // Time collection began.
|
||||
ch chan []*metric
|
||||
wg sync.WaitGroup
|
||||
Config
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
@ -97,27 +97,28 @@ func (u *promUnifi) Run(c poller.Collect) error {
|
|||
u.Config.Namespace = strings.Replace(poller.AppName, "-", "", -1)
|
||||
}
|
||||
|
||||
u.Config.Namespace = strings.Replace(u.Config.Namespace, "-", "_", -1)
|
||||
|
||||
if u.Config.HTTPListen == "" {
|
||||
u.Config.HTTPListen = defaultHTTPListen
|
||||
}
|
||||
|
||||
name := strings.Replace(u.Config.Namespace, "-", "_", -1)
|
||||
prometheus.MustRegister(version.NewCollector(u.Config.Namespace))
|
||||
|
||||
ns := name
|
||||
if ns = strings.Trim(ns, "_") + "_"; ns == "_" {
|
||||
ns = ""
|
||||
if u.Config.Namespace = strings.Trim(u.Config.Namespace, "_") + "_"; u.Config.Namespace == "_" {
|
||||
u.Config.Namespace = ""
|
||||
}
|
||||
|
||||
prometheus.MustRegister(version.NewCollector(name))
|
||||
prometheus.MustRegister(&promUnifi{
|
||||
Collector: c,
|
||||
Client: descClient(ns + "client_"),
|
||||
Device: descDevice(ns + "device_"), // stats for all device types.
|
||||
UAP: descUAP(ns + "device_"),
|
||||
USG: descUSG(ns + "device_"),
|
||||
USW: descUSW(ns + "device_"),
|
||||
Site: descSite(ns + "site_"),
|
||||
Client: descClient(u.Config.Namespace + "client_"),
|
||||
Device: descDevice(u.Config.Namespace + "device_"), // stats for all device types.
|
||||
UAP: descUAP(u.Config.Namespace + "device_"),
|
||||
USG: descUSG(u.Config.Namespace + "device_"),
|
||||
USW: descUSW(u.Config.Namespace + "device_"),
|
||||
Site: descSite(u.Config.Namespace + "site_"),
|
||||
})
|
||||
|
||||
c.Logf("Exporting Measurements for Prometheus at https://%s/metrics, namespace: %s", u.Config.HTTPListen, u.Config.Namespace)
|
||||
|
||||
return http.ListenAndServe(u.Config.HTTPListen, nil)
|
||||
|
|
@ -185,12 +186,14 @@ func (u *promUnifi) exportMetrics(r report, ch chan<- prometheus.Metric, ourChan
|
|||
r.error(ch, m.Desc, fmt.Sprintf("not a number: %v", m.Value))
|
||||
}
|
||||
}
|
||||
|
||||
r.done()
|
||||
}
|
||||
}
|
||||
|
||||
func (u *promUnifi) loopExports(r report) {
|
||||
m := r.metrics()
|
||||
|
||||
r.add()
|
||||
go func() {
|
||||
defer r.done()
|
||||
|
|
|
|||
Loading…
Reference in New Issue