allow pulling specific sites through output plugins

This commit is contained in:
davidnewhall2 2019-12-17 02:39:36 -08:00
parent da75406310
commit 9022ab288d
6 changed files with 90 additions and 14 deletions

View File

@ -69,10 +69,13 @@ func (u *InfluxUnifi) PollController() {
log.Printf("[INFO] Everything checks out! Poller started, InfluxDB interval: %v", interval) log.Printf("[INFO] Everything checks out! Poller started, InfluxDB interval: %v", interval)
for u.LastCheck = range ticker.C { for u.LastCheck = range ticker.C {
metrics, err := u.Collector.Metrics() metrics, ok, err := u.Collector.Metrics()
if err != nil { if err != nil {
u.Collector.LogErrorf("%v", err) u.Collector.LogErrorf("%v", err)
continue
if !ok {
continue
}
} }
report, err := u.ReportMetrics(metrics) report, err := u.ReportMetrics(metrics)

View File

@ -44,6 +44,7 @@ func init() {
u := &InputUnifi{} u := &InputUnifi{}
poller.NewInput(&poller.InputPlugin{ poller.NewInput(&poller.InputPlugin{
Name: "unifi",
Input: u, // this library implements poller.Input interface for Metrics(). Input: u, // this library implements poller.Input interface for Metrics().
Config: u, // Defines our config data interface. Config: u, // Defines our config data interface.
}) })

View File

@ -47,15 +47,25 @@ func (u *InputUnifi) Initialize(l poller.Logger) error {
} }
// Metrics grabs all the measurements from a UniFi controller and returns them. // Metrics grabs all the measurements from a UniFi controller and returns them.
func (u *InputUnifi) Metrics() (*poller.Metrics, error) { func (u *InputUnifi) Metrics() (*poller.Metrics, bool, error) {
return u.MetricsFrom(poller.Filter{})
}
// MetricsFrom grabs all the measurements from a UniFi controller and returns them.
func (u *InputUnifi) MetricsFrom(filter poller.Filter) (*poller.Metrics, bool, error) {
if u.Config.Disable { if u.Config.Disable {
return nil, nil return nil, false, nil
} }
errs := []string{} errs := []string{}
metrics := &poller.Metrics{} metrics := &poller.Metrics{}
ok := false
for _, c := range u.Config.Controllers { for _, c := range u.Config.Controllers {
if filter.Term != "" && c.Name != filter.Term {
continue
}
m, err := u.collectController(c) m, err := u.collectController(c)
if err != nil { if err != nil {
errs = append(errs, err.Error()) errs = append(errs, err.Error())
@ -65,6 +75,8 @@ func (u *InputUnifi) Metrics() (*poller.Metrics, error) {
continue continue
} }
ok = true
metrics.Sites = append(metrics.Sites, m.Sites...) metrics.Sites = append(metrics.Sites, m.Sites...)
metrics.Clients = append(metrics.Clients, m.Clients...) metrics.Clients = append(metrics.Clients, m.Clients...)
metrics.IDSList = append(metrics.IDSList, m.IDSList...) metrics.IDSList = append(metrics.IDSList, m.IDSList...)
@ -84,10 +96,10 @@ func (u *InputUnifi) Metrics() (*poller.Metrics, error) {
} }
if len(errs) > 0 { if len(errs) > 0 {
return metrics, fmt.Errorf(strings.Join(errs, ", ")) return metrics, ok, fmt.Errorf(strings.Join(errs, ", "))
} }
return metrics, nil return metrics, ok, nil
} }
// RawMetrics returns API output from the first configured unifi controller. // RawMetrics returns API output from the first configured unifi controller.

View File

@ -15,13 +15,15 @@ var (
// Input plugins must implement this interface. // Input plugins must implement this interface.
type Input interface { type Input interface {
Initialize(Logger) error // Called once on startup to initialize the plugin. Initialize(Logger) error // Called once on startup to initialize the plugin.
Metrics() (*Metrics, error) // Called every time new metrics are requested. Metrics() (*Metrics, bool, error) // Called every time new metrics are requested.
MetricsFrom(Filter) (*Metrics, bool, error) // Called every time new metrics are requested.
RawMetrics(Filter) ([]byte, error) RawMetrics(Filter) ([]byte, error)
} }
// InputPlugin describes an input plugin's consumable interface. // InputPlugin describes an input plugin's consumable interface.
type InputPlugin struct { type InputPlugin struct {
Name string
Config interface{} // Each config is passed into an unmarshaller later. Config interface{} // Each config is passed into an unmarshaller later.
Input Input
} }
@ -61,12 +63,13 @@ func (u *UnifiPoller) InitializeInputs() error {
} }
// Metrics aggregates all the measurements from all configured inputs and returns them. // Metrics aggregates all the measurements from all configured inputs and returns them.
func (u *UnifiPoller) Metrics() (*Metrics, error) { func (u *UnifiPoller) Metrics() (*Metrics, bool, error) {
errs := []string{} errs := []string{}
metrics := &Metrics{} metrics := &Metrics{}
ok := false
for _, input := range inputs { for _, input := range inputs {
m, err := input.Metrics() m, _, err := input.Metrics()
if err != nil { if err != nil {
errs = append(errs, err.Error()) errs = append(errs, err.Error())
} }
@ -75,6 +78,8 @@ func (u *UnifiPoller) Metrics() (*Metrics, error) {
continue continue
} }
ok = true
metrics.Sites = append(metrics.Sites, m.Sites...) metrics.Sites = append(metrics.Sites, m.Sites...)
metrics.Clients = append(metrics.Clients, m.Clients...) metrics.Clients = append(metrics.Clients, m.Clients...)
metrics.IDSList = append(metrics.IDSList, m.IDSList...) metrics.IDSList = append(metrics.IDSList, m.IDSList...)
@ -99,5 +104,54 @@ func (u *UnifiPoller) Metrics() (*Metrics, error) {
err = fmt.Errorf(strings.Join(errs, ", ")) err = fmt.Errorf(strings.Join(errs, ", "))
} }
return metrics, err return metrics, ok, err
}
// MetricsFrom aggregates all the measurements from all configured inputs and returns them.
func (u *UnifiPoller) MetricsFrom(filter Filter) (*Metrics, bool, error) {
errs := []string{}
metrics := &Metrics{}
ok := false
for _, input := range inputs {
if input.Name != filter.Type {
continue
}
m, _, err := input.MetricsFrom(filter)
if err != nil {
errs = append(errs, err.Error())
}
if m == nil {
continue
}
ok = true
metrics.Sites = append(metrics.Sites, m.Sites...)
metrics.Clients = append(metrics.Clients, m.Clients...)
metrics.IDSList = append(metrics.IDSList, m.IDSList...)
if m.Devices == nil {
continue
}
if metrics.Devices == nil {
metrics.Devices = &unifi.Devices{}
}
metrics.UAPs = append(metrics.UAPs, m.UAPs...)
metrics.USGs = append(metrics.USGs, m.USGs...)
metrics.USWs = append(metrics.USWs, m.USWs...)
metrics.UDMs = append(metrics.UDMs, m.UDMs...)
}
var err error
if len(errs) > 0 {
err = fmt.Errorf(strings.Join(errs, ", "))
}
return metrics, ok, err
} }

View File

@ -13,7 +13,8 @@ var (
// Collect is passed into output packages so they may collect metrics to output. // Collect is passed into output packages so they may collect metrics to output.
// Output packages must implement this interface. // Output packages must implement this interface.
type Collect interface { type Collect interface {
Metrics() (*Metrics, error) Metrics() (*Metrics, bool, error)
MetricsFrom(Filter) (*Metrics, bool, error)
Logger Logger
} }

View File

@ -140,12 +140,17 @@ func (u *promUnifi) Describe(ch chan<- *prometheus.Desc) {
func (u *promUnifi) Collect(ch chan<- prometheus.Metric) { func (u *promUnifi) Collect(ch chan<- prometheus.Metric) {
var err error var err error
ok := false
r := &Report{Config: u.Config, ch: make(chan []*metric, buffer), Start: time.Now()} r := &Report{Config: u.Config, ch: make(chan []*metric, buffer), Start: time.Now()}
defer r.close() defer r.close()
if r.Metrics, err = u.Collector.Metrics(); err != nil { if r.Metrics, ok, err = u.Collector.Metrics(); err != nil {
r.error(ch, prometheus.NewInvalidDesc(fmt.Errorf("metric fetch failed")), err) r.error(ch, prometheus.NewInvalidDesc(fmt.Errorf("metric fetch failed")), err)
return
if !ok {
return
}
} }
r.Fetch = time.Since(r.Start) r.Fetch = time.Since(r.Start)