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)
for u.LastCheck = range ticker.C {
metrics, err := u.Collector.Metrics()
metrics, ok, err := u.Collector.Metrics()
if err != nil {
u.Collector.LogErrorf("%v", err)
continue
if !ok {
continue
}
}
report, err := u.ReportMetrics(metrics)

View File

@ -44,6 +44,7 @@ func init() {
u := &InputUnifi{}
poller.NewInput(&poller.InputPlugin{
Name: "unifi",
Input: u, // this library implements poller.Input interface for Metrics().
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.
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 {
return nil, nil
return nil, false, nil
}
errs := []string{}
metrics := &poller.Metrics{}
ok := false
for _, c := range u.Config.Controllers {
if filter.Term != "" && c.Name != filter.Term {
continue
}
m, err := u.collectController(c)
if err != nil {
errs = append(errs, err.Error())
@ -65,6 +75,8 @@ func (u *InputUnifi) Metrics() (*poller.Metrics, error) {
continue
}
ok = true
metrics.Sites = append(metrics.Sites, m.Sites...)
metrics.Clients = append(metrics.Clients, m.Clients...)
metrics.IDSList = append(metrics.IDSList, m.IDSList...)
@ -84,10 +96,10 @@ func (u *InputUnifi) Metrics() (*poller.Metrics, error) {
}
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.

View File

@ -15,13 +15,15 @@ var (
// Input plugins must implement this interface.
type Input interface {
Initialize(Logger) error // Called once on startup to initialize the plugin.
Metrics() (*Metrics, error) // Called every time new metrics are requested.
Initialize(Logger) error // Called once on startup to initialize the plugin.
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)
}
// InputPlugin describes an input plugin's consumable interface.
type InputPlugin struct {
Name string
Config interface{} // Each config is passed into an unmarshaller later.
Input
}
@ -61,12 +63,13 @@ func (u *UnifiPoller) InitializeInputs() error {
}
// 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{}
metrics := &Metrics{}
ok := false
for _, input := range inputs {
m, err := input.Metrics()
m, _, err := input.Metrics()
if err != nil {
errs = append(errs, err.Error())
}
@ -75,6 +78,8 @@ func (u *UnifiPoller) Metrics() (*Metrics, error) {
continue
}
ok = true
metrics.Sites = append(metrics.Sites, m.Sites...)
metrics.Clients = append(metrics.Clients, m.Clients...)
metrics.IDSList = append(metrics.IDSList, m.IDSList...)
@ -99,5 +104,54 @@ func (u *UnifiPoller) Metrics() (*Metrics, error) {
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.
// Output packages must implement this interface.
type Collect interface {
Metrics() (*Metrics, error)
Metrics() (*Metrics, bool, error)
MetricsFrom(Filter) (*Metrics, bool, error)
Logger
}

View File

@ -140,12 +140,17 @@ func (u *promUnifi) Describe(ch chan<- *prometheus.Desc) {
func (u *promUnifi) Collect(ch chan<- prometheus.Metric) {
var err error
ok := false
r := &Report{Config: u.Config, ch: make(chan []*metric, buffer), Start: time.Now()}
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)
return
if !ok {
return
}
}
r.Fetch = time.Since(r.Start)