allow dynamic controller scrapes
This commit is contained in:
		
							parent
							
								
									1dd5b4761c
								
							
						
					
					
						commit
						17e7c8edb3
					
				|  | @ -46,11 +46,12 @@ | |||
|   version = "v1.6.0" | ||||
| 
 | ||||
| [[projects]] | ||||
|   digest = "1:7097829edd12fd7211fca0d29496b44f94ef9e6d72f88fb64f3d7b06315818ad" | ||||
|   digest = "1:eb04f69c8991e52eff33c428bd729e04208bf03235be88e4df0d88497c6861b9" | ||||
|   name = "github.com/prometheus/client_golang" | ||||
|   packages = [ | ||||
|     "prometheus", | ||||
|     "prometheus/internal", | ||||
|     "prometheus/promhttp", | ||||
|   ] | ||||
|   pruneopts = "UT" | ||||
|   revision = "170205fb58decfd011f1550d4cfb737230d7ae4f" | ||||
|  | @ -99,11 +100,11 @@ | |||
| 
 | ||||
| [[projects]] | ||||
|   branch = "master" | ||||
|   digest = "1:68fe4216878f16dd6ef33413365fbbe8d2eb781177c7adab874cfc752ce96a7e" | ||||
|   digest = "1:07f0cb66f649e51f9ef23441f8dfc34a73e7d9bf0832417abcbad578f1d8c8d6" | ||||
|   name = "golang.org/x/sys" | ||||
|   packages = ["windows"] | ||||
|   pruneopts = "UT" | ||||
|   revision = "4a24b406529242041050cb1dec3e0e4c46a5f1b6" | ||||
|   revision = "af0d71d358abe0ba3594483a5d519f429dbae3e9" | ||||
| 
 | ||||
| [[projects]] | ||||
|   digest = "1:54742bef5cb29f706614c9edcfdeb29fb5992f26090f26ca955f575dddf54f9e" | ||||
|  | @ -113,14 +114,6 @@ | |||
|   revision = "961061d377655468e9da4a9333e71b9b77402470" | ||||
|   version = "v0.0.1" | ||||
| 
 | ||||
| [[projects]] | ||||
|   digest = "1:54742bef5cb29f706614c9edcfdeb29fb5992f26090f26ca955f575dddf54f9e" | ||||
|   name = "golift.io/config" | ||||
|   packages = ["."] | ||||
|   pruneopts = "UT" | ||||
|   revision = "961061d377655468e9da4a9333e71b9b77402470" | ||||
|   version = "v0.0.1" | ||||
| 
 | ||||
| [[projects]] | ||||
|   digest = "1:2883cea734f2766f41ff9c9d4aefccccc53e3d44f5c8b08893b9c218cf666722" | ||||
|   name = "golift.io/unifi" | ||||
|  | @ -143,10 +136,10 @@ | |||
|   input-imports = [ | ||||
|     "github.com/influxdata/influxdb1-client/v2", | ||||
|     "github.com/prometheus/client_golang/prometheus", | ||||
|     "github.com/prometheus/client_golang/prometheus/promhttp", | ||||
|     "github.com/prometheus/common/version", | ||||
|     "github.com/spf13/pflag", | ||||
|     "golift.io/cnfg", | ||||
|     "golift.io/config", | ||||
|     "golift.io/unifi", | ||||
|   ] | ||||
|   solver-name = "gps-cdcl" | ||||
|  |  | |||
|  | @ -10,7 +10,7 @@ import ( | |||
| 
 | ||||
| 	"github.com/davidnewhall/unifi-poller/pkg/poller" | ||||
| 	influx "github.com/influxdata/influxdb1-client/v2" | ||||
| 	"golift.io/config" | ||||
| 	"golift.io/cnfg" | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
|  | @ -23,13 +23,13 @@ const ( | |||
| 
 | ||||
| // Config defines the data needed to store metrics in InfluxDB
 | ||||
| type Config struct { | ||||
| 	Interval  config.Duration `json:"interval,omitempty" toml:"interval,omitempty" xml:"interval" yaml:"interval"` | ||||
| 	Disable   bool            `json:"disable" toml:"disable" xml:"disable,attr" 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  cnfg.Duration `json:"interval,omitempty" toml:"interval,omitempty" xml:"interval" yaml:"interval"` | ||||
| 	Disable   bool          `json:"disable" toml:"disable" xml:"disable,attr" 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.
 | ||||
|  | @ -133,12 +133,12 @@ func (u *InfluxUnifi) setConfigDefaults() { | |||
| 	} | ||||
| 
 | ||||
| 	if u.Config.Interval.Duration == 0 { | ||||
| 		u.Config.Interval = config.Duration{Duration: defaultInterval} | ||||
| 		u.Config.Interval = cnfg.Duration{Duration: defaultInterval} | ||||
| 	} else if u.Config.Interval.Duration < minimumInterval { | ||||
| 		u.Config.Interval = config.Duration{Duration: minimumInterval} | ||||
| 		u.Config.Interval = cnfg.Duration{Duration: minimumInterval} | ||||
| 	} | ||||
| 
 | ||||
| 	u.Config.Interval = config.Duration{Duration: u.Config.Interval.Duration.Round(time.Second)} | ||||
| 	u.Config.Interval = cnfg.Duration{Duration: u.Config.Interval.Duration.Round(time.Second)} | ||||
| } | ||||
| 
 | ||||
| // ReportMetrics batches all device and client data into influxdb data points.
 | ||||
|  |  | |||
|  | @ -15,6 +15,49 @@ func (u *InputUnifi) isNill(c *Controller) bool { | |||
| 	return c.Unifi == nil | ||||
| } | ||||
| 
 | ||||
| func (u *InputUnifi) dynamicController(url string) (*poller.Metrics, bool, error) { | ||||
| 	c := u.Config.Default // copy defaults into new controller
 | ||||
| 	c.Name = url | ||||
| 	c.URL = url | ||||
| 
 | ||||
| 	u.Logf("Authenticating to Dynamic UniFi Controller: %s", url) | ||||
| 
 | ||||
| 	if err := u.getUnifi(&c); err != nil { | ||||
| 		return nil, false, fmt.Errorf("authenticating to %s: %v", url, err) | ||||
| 	} | ||||
| 
 | ||||
| 	metrics := &poller.Metrics{} | ||||
| 	ok, err := u.appendController(&c, metrics) | ||||
| 
 | ||||
| 	return metrics, ok, err | ||||
| } | ||||
| 
 | ||||
| func (u *InputUnifi) appendController(c *Controller, metrics *poller.Metrics) (bool, error) { | ||||
| 	m, err := u.collectController(c) | ||||
| 	if err != nil || m == nil { | ||||
| 		return false, err | ||||
| 	} | ||||
| 
 | ||||
| 	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 { | ||||
| 		return true, nil | ||||
| 	} | ||||
| 
 | ||||
| 	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...) | ||||
| 
 | ||||
| 	return true, nil | ||||
| } | ||||
| 
 | ||||
| func (u *InputUnifi) collectController(c *Controller) (*poller.Metrics, error) { | ||||
| 	if u.isNill(c) { | ||||
| 		u.Logf("Re-authenticating to UniFi Controller: %s", c.URL) | ||||
|  |  | |||
|  | @ -13,6 +13,13 @@ import ( | |||
| 	"golift.io/unifi" | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	defaultURL  = "https://127.0.0.1:8443" | ||||
| 	defaultUser = "unifipoller" | ||||
| 	defaultPass = "unifipollerp4$$w0rd" | ||||
| 	defaultSite = "all" | ||||
| ) | ||||
| 
 | ||||
| // InputUnifi contains the running data.
 | ||||
| type InputUnifi struct { | ||||
| 	Config *Config `json:"unifi" toml:"unifi" xml:"unifi" yaml:"unifi"` | ||||
|  | @ -36,7 +43,9 @@ type Controller struct { | |||
| // Config contains our configuration data
 | ||||
| type Config struct { | ||||
| 	sync.RWMutex               // locks the Unifi struct member when re-authing to unifi.
 | ||||
| 	Default      Controller    `json:"defaults" toml:"defaults" xml:"default" yaml:"defaults"` | ||||
| 	Disable      bool          `json:"disable" toml:"disable" xml:"disable" yaml:"disable"` | ||||
| 	Dynamic      bool          `json:"dynamic" toml:"dynamic" xml:"dynamic" yaml:"dynamic"` | ||||
| 	Controllers  []*Controller `json:"controllers" toml:"controller" xml:"controller" yaml:"controllers"` | ||||
| } | ||||
| 
 | ||||
|  | @ -147,6 +156,28 @@ func (u *InputUnifi) dumpSitesJSON(c *Controller, path, name string, sites unifi | |||
| 	return allJSON, nil | ||||
| } | ||||
| 
 | ||||
| func (u *InputUnifi) setDefaults(c *Controller) { | ||||
| 	if c.URL == "" { | ||||
| 		c.URL = defaultURL | ||||
| 	} | ||||
| 
 | ||||
| 	if c.Name == "" { | ||||
| 		c.Name = c.URL | ||||
| 	} | ||||
| 
 | ||||
| 	if c.Pass == "" { | ||||
| 		c.Pass = defaultPass | ||||
| 	} | ||||
| 
 | ||||
| 	if c.User == "" { | ||||
| 		c.User = defaultUser | ||||
| 	} | ||||
| 
 | ||||
| 	if len(c.Sites) < 1 { | ||||
| 		c.Sites = []string{defaultSite} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // StringInSlice returns true if a string is in a slice.
 | ||||
| func StringInSlice(str string, slice []string) bool { | ||||
| 	for _, s := range slice { | ||||
|  |  | |||
|  | @ -19,16 +19,15 @@ func (u *InputUnifi) Initialize(l poller.Logger) error { | |||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	if len(u.Config.Controllers) < 1 { | ||||
| 		return fmt.Errorf("no unifi controllers defined for unifi input") | ||||
| 	if u.setDefaults(&u.Config.Default); len(u.Config.Controllers) < 1 { | ||||
| 		new := u.Config.Default // copy defaults.
 | ||||
| 		u.Config.Controllers = []*Controller{&new} | ||||
| 	} | ||||
| 
 | ||||
| 	u.Logger = l | ||||
| 
 | ||||
| 	for i, c := range u.Config.Controllers { | ||||
| 		if c.Name == "" { | ||||
| 			u.Config.Controllers[i].Name = c.URL | ||||
| 		} | ||||
| 	for _, c := range u.Config.Controllers { | ||||
| 		u.setDefaults(c) | ||||
| 
 | ||||
| 		switch err := u.getUnifi(c); err { | ||||
| 		case nil: | ||||
|  | @ -48,12 +47,12 @@ 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, bool, error) { | ||||
| 	return u.MetricsFrom(poller.Filter{}) | ||||
| 	return u.MetricsFrom(nil) | ||||
| } | ||||
| 
 | ||||
| // 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 { | ||||
| func (u *InputUnifi) MetricsFrom(filter *poller.Filter) (*poller.Metrics, bool, error) { | ||||
| 	if u.Config.Disable || filter == nil || filter.Term == "" { | ||||
| 		return nil, false, nil | ||||
| 	} | ||||
| 
 | ||||
|  | @ -61,49 +60,36 @@ func (u *InputUnifi) MetricsFrom(filter poller.Filter) (*poller.Metrics, bool, e | |||
| 	metrics := &poller.Metrics{} | ||||
| 	ok := false | ||||
| 
 | ||||
| 	// Check if the request is for an existing, configured controller.
 | ||||
| 	for _, c := range u.Config.Controllers { | ||||
| 		if filter.Term != "" && c.Name != filter.Term { | ||||
| 		if !strings.EqualFold(c.Name, filter.Term) { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		m, err := u.collectController(c) | ||||
| 		exists, err := u.appendController(c, metrics) | ||||
| 		if err != nil { | ||||
| 			errs = append(errs, err.Error()) | ||||
| 		} | ||||
| 
 | ||||
| 		if m == nil { | ||||
| 			continue | ||||
| 		if exists { | ||||
| 			ok = true | ||||
| 		} | ||||
| 
 | ||||
| 		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...) | ||||
| 	} | ||||
| 
 | ||||
| 	if len(errs) > 0 { | ||||
| 		return metrics, ok, fmt.Errorf(strings.Join(errs, ", ")) | ||||
| 	} | ||||
| 
 | ||||
| 	if u.Config.Dynamic && !ok && strings.HasPrefix(filter.Term, "http") { | ||||
| 		// Attempt to a dynamic metrics fetch from an unconfigured controller.
 | ||||
| 		return u.dynamicController(filter.Term) | ||||
| 	} | ||||
| 
 | ||||
| 	return metrics, ok, nil | ||||
| } | ||||
| 
 | ||||
| // RawMetrics returns API output from the first configured unifi controller.
 | ||||
| func (u *InputUnifi) RawMetrics(filter poller.Filter) ([]byte, error) { | ||||
| func (u *InputUnifi) RawMetrics(filter *poller.Filter) ([]byte, error) { | ||||
| 	c := u.Config.Controllers[0] // We could pull the controller number from the filter.
 | ||||
| 	if u.isNill(c) { | ||||
| 		u.Logf("Re-authenticating to UniFi Controller: %s", c.URL) | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ func (u *UnifiPoller) DumpJSONPayload() (err error) { | |||
| 	u.Config.Quiet = true | ||||
| 
 | ||||
| 	split := strings.SplitN(u.Flags.DumpJSON, " ", 2) | ||||
| 	filter := Filter{Type: split[0]} | ||||
| 	filter := &Filter{Type: split[0]} | ||||
| 
 | ||||
| 	if len(split) > 1 { | ||||
| 		filter.Term = split[1] | ||||
|  |  | |||
|  | @ -15,10 +15,10 @@ var ( | |||
| 
 | ||||
| // Input plugins must implement this interface.
 | ||||
| type Input interface { | ||||
| 	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) | ||||
| 	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.
 | ||||
|  | @ -108,7 +108,7 @@ func (u *UnifiPoller) Metrics() (*Metrics, bool, error) { | |||
| } | ||||
| 
 | ||||
| // MetricsFrom aggregates all the measurements from all configured inputs and returns them.
 | ||||
| func (u *UnifiPoller) MetricsFrom(filter Filter) (*Metrics, bool, error) { | ||||
| func (u *UnifiPoller) MetricsFrom(filter *Filter) (*Metrics, bool, error) { | ||||
| 	errs := []string{} | ||||
| 	metrics := &Metrics{} | ||||
| 	ok := false | ||||
|  |  | |||
|  | @ -14,7 +14,7 @@ var ( | |||
| // Output packages must implement this interface.
 | ||||
| type Collect interface { | ||||
| 	Metrics() (*Metrics, bool, error) | ||||
| 	MetricsFrom(Filter) (*Metrics, bool, error) | ||||
| 	MetricsFrom(*Filter) (*Metrics, bool, error) | ||||
| 	Logger | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -11,6 +11,7 @@ import ( | |||
| 
 | ||||
| 	"github.com/davidnewhall/unifi-poller/pkg/poller" | ||||
| 	"github.com/prometheus/client_golang/prometheus" | ||||
| 	"github.com/prometheus/client_golang/prometheus/promhttp" | ||||
| 	"github.com/prometheus/common/version" | ||||
| 	"golift.io/unifi" | ||||
| ) | ||||
|  | @ -77,6 +78,11 @@ type Report struct { | |||
| 	wg      sync.WaitGroup | ||||
| } | ||||
| 
 | ||||
| type target struct { | ||||
| 	*poller.Filter | ||||
| 	*promUnifi | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	u := &promUnifi{Prometheus: &Prometheus{}} | ||||
| 
 | ||||
|  | @ -103,6 +109,8 @@ func (u *promUnifi) Run(c poller.Collect) error { | |||
| 		u.Config.HTTPListen = defaultHTTPListen | ||||
| 	} | ||||
| 
 | ||||
| 	mux := http.NewServeMux() | ||||
| 
 | ||||
| 	prometheus.MustRegister(version.NewCollector(u.Config.Namespace)) | ||||
| 	prometheus.MustRegister(&promUnifi{ | ||||
| 		Collector: c, | ||||
|  | @ -115,8 +123,43 @@ func (u *promUnifi) Run(c poller.Collect) error { | |||
| 	}) | ||||
| 	c.Logf("Exporting Measurements for Prometheus at https://%s/metrics, namespace: %s", | ||||
| 		u.Config.HTTPListen, u.Config.Namespace) | ||||
| 	mux.Handle("/metrics", promhttp.HandlerFor( | ||||
| 		prometheus.DefaultGatherer, promhttp.HandlerOpts{ErrorHandling: promhttp.ContinueOnError}, | ||||
| 	)) | ||||
| 	mux.HandleFunc("/scrape", u.ScrapeHandler) | ||||
| 
 | ||||
| 	return http.ListenAndServe(u.Config.HTTPListen, nil) | ||||
| 	return http.ListenAndServe(u.Config.HTTPListen, mux) | ||||
| } | ||||
| 
 | ||||
| // ScrapeHandler allows prometheus to scrape a single source, instead of all sources.
 | ||||
| func (u *promUnifi) ScrapeHandler(w http.ResponseWriter, r *http.Request) { | ||||
| 	t := &target{promUnifi: u, Filter: &poller.Filter{}} | ||||
| 	if t.Filter.Type = r.URL.Query().Get("input"); t.Filter.Type == "" { | ||||
| 		http.Error(w, `'input' parameter must be specified (try "unifi")`, 400) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if t.Filter.Term = r.URL.Query().Get("target"); t.Filter.Term == "" { | ||||
| 		http.Error(w, "'target' parameter must be specified, configured name, or unconfigured url", 400) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	registry := prometheus.NewRegistry() | ||||
| 
 | ||||
| 	registry.MustRegister(t) | ||||
| 	promhttp.HandlerFor( | ||||
| 		registry, promhttp.HandlerOpts{ErrorHandling: promhttp.ContinueOnError}, | ||||
| 	).ServeHTTP(w, r) | ||||
| } | ||||
| 
 | ||||
| // Describe satisfies the prometheus Collector. This returns all of the
 | ||||
| // metric descriptions that this packages produces.
 | ||||
| func (t *target) Describe(ch chan<- *prometheus.Desc) { | ||||
| 	t.promUnifi.Describe(ch) | ||||
| } | ||||
| 
 | ||||
| func (t *target) Collect(ch chan<- prometheus.Metric) { | ||||
| 	t.promUnifi.collect(ch, t.Filter) | ||||
| } | ||||
| 
 | ||||
| // Describe satisfies the prometheus Collector. This returns all of the
 | ||||
|  | @ -138,6 +181,10 @@ func (u *promUnifi) Describe(ch chan<- *prometheus.Desc) { | |||
| // Collect satisfies the prometheus Collector. This runs the input method to get
 | ||||
| // the current metrics (from another package) then exports them for prometheus.
 | ||||
| func (u *promUnifi) Collect(ch chan<- prometheus.Metric) { | ||||
| 	u.collect(ch, nil) | ||||
| } | ||||
| 
 | ||||
| func (u *promUnifi) collect(ch chan<- prometheus.Metric, filter *poller.Filter) { | ||||
| 	var err error | ||||
| 
 | ||||
| 	ok := false | ||||
|  | @ -145,7 +192,13 @@ func (u *promUnifi) Collect(ch chan<- prometheus.Metric) { | |||
| 	r := &Report{Config: u.Config, ch: make(chan []*metric, buffer), Start: time.Now()} | ||||
| 	defer r.close() | ||||
| 
 | ||||
| 	if r.Metrics, ok, err = u.Collector.Metrics(); err != nil { | ||||
| 	if filter == nil { | ||||
| 		r.Metrics, ok, err = u.Collector.Metrics() | ||||
| 	} else { | ||||
| 		r.Metrics, ok, err = u.Collector.MetricsFrom(filter) | ||||
| 	} | ||||
| 
 | ||||
| 	if err != nil { | ||||
| 		r.error(ch, prometheus.NewInvalidDesc(fmt.Errorf("metric fetch failed")), err) | ||||
| 
 | ||||
| 		if !ok { | ||||
|  |  | |||
|  | @ -4,17 +4,17 @@ import ( | |||
| 	"fmt" | ||||
| 
 | ||||
| 	"github.com/davidnewhall/unifi-poller/pkg/poller" | ||||
| 	"golift.io/config" | ||||
| 	"golift.io/cnfg" | ||||
| ) | ||||
| 
 | ||||
| // mysqlConfig represents the data that is unmarshalled from the up.conf config file for this plugins.
 | ||||
| type mysqlConfig struct { | ||||
| 	Interval config.Duration `json:"interval" toml:"interval" xml:"interval" yaml:"interval"` | ||||
| 	Host     string          `json:"host" toml:"host" xml:"host" yaml:"host"` | ||||
| 	User     string          `json:"user" toml:"user" xml:"user" yaml:"user"` | ||||
| 	Pass     string          `json:"pass" toml:"pass" xml:"pass" yaml:"pass"` | ||||
| 	DB       string          `json:"db" toml:"db" xml:"db" yaml:"db"` | ||||
| 	Table    string          `json:"table" toml:"table" xml:"table" yaml:"table"` | ||||
| 	Interval cnfg.Duration `json:"interval" toml:"interval" xml:"interval" yaml:"interval"` | ||||
| 	Host     string        `json:"host" toml:"host" xml:"host" yaml:"host"` | ||||
| 	User     string        `json:"user" toml:"user" xml:"user" yaml:"user"` | ||||
| 	Pass     string        `json:"pass" toml:"pass" xml:"pass" yaml:"pass"` | ||||
| 	DB       string        `json:"db" toml:"db" xml:"db" yaml:"db"` | ||||
| 	Table    string        `json:"table" toml:"table" xml:"table" yaml:"table"` | ||||
| 	// Maps do not work with ENV VARIABLES yet, but may in the future.
 | ||||
| 	Fields []string `json:"fields" toml:"fields" xml:"field" yaml:"fields"` | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue