move to a common pattern on output plugins to catch common issues
This commit is contained in:
parent
689423d4dd
commit
bd51cf59f3
|
|
@ -69,8 +69,8 @@
|
||||||
# How often to poll UniFi and report to Datadog.
|
# How often to poll UniFi and report to Datadog.
|
||||||
interval = "2m"
|
interval = "2m"
|
||||||
|
|
||||||
# To disable this output plugin
|
# To enable this output plugin
|
||||||
disable = true
|
enable = false
|
||||||
|
|
||||||
# Datadog Custom Options
|
# Datadog Custom Options
|
||||||
|
|
||||||
|
|
@ -84,7 +84,7 @@
|
||||||
# tags = [ "customer:abc_corp" ]
|
# tags = [ "customer:abc_corp" ]
|
||||||
|
|
||||||
# For more advanced options for very large amount of data collected see the upstream
|
# For more advanced options for very large amount of data collected see the upstream
|
||||||
# github.com/unpoller/datadogunifi repository README.
|
# github.com/unpoller/unpoller/pkg/datadogunifi repository README.
|
||||||
|
|
||||||
|
|
||||||
# Unpoller has an optional web server. To turn it on, set enable to true. If you
|
# Unpoller has an optional web server. To turn it on, set enable to true. If you
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,15 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"datadog": {
|
||||||
|
"enable": false,
|
||||||
|
"address": "localhost:8125",
|
||||||
|
"namespace": "",
|
||||||
|
"tags": [
|
||||||
|
"customer:abcde"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
"unifi": {
|
"unifi": {
|
||||||
"dynamic": false,
|
"dynamic": false,
|
||||||
"defaults": {
|
"defaults": {
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,13 @@ webserver:
|
||||||
accounts:
|
accounts:
|
||||||
captain: "$2a$04$mxw6i0LKH6u46oaLK2cq5eCTAAFkfNiRpzNbz.EyvJZZWNa2FzIlS"
|
captain: "$2a$04$mxw6i0LKH6u46oaLK2cq5eCTAAFkfNiRpzNbz.EyvJZZWNa2FzIlS"
|
||||||
|
|
||||||
|
datadog:
|
||||||
|
enable: false
|
||||||
|
address: localhost:8125
|
||||||
|
namespace: ""
|
||||||
|
tags:
|
||||||
|
- customer:abcdef
|
||||||
|
|
||||||
unifi:
|
unifi:
|
||||||
dynamic: false
|
dynamic: false
|
||||||
defaults:
|
defaults:
|
||||||
|
|
|
||||||
|
|
@ -112,13 +112,15 @@ type DatadogUnifi struct {
|
||||||
*Datadog
|
*Datadog
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ poller.OutputPlugin = &DatadogUnifi{}
|
||||||
|
|
||||||
func init() { // nolint: gochecknoinits
|
func init() { // nolint: gochecknoinits
|
||||||
u := &DatadogUnifi{Datadog: &Datadog{}, LastCheck: time.Now()}
|
u := &DatadogUnifi{Datadog: &Datadog{}, LastCheck: time.Now()}
|
||||||
|
|
||||||
poller.NewOutput(&poller.Output{
|
poller.NewOutput(&poller.Output{
|
||||||
Name: "datadog",
|
Name: "datadog",
|
||||||
Config: u.Datadog,
|
Config: u.Datadog,
|
||||||
Method: u.Run,
|
OutputPlugin: u,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -188,14 +190,26 @@ func (u *DatadogUnifi) setConfigDefaults() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *DatadogUnifi) Enabled() bool {
|
||||||
|
if u == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if u.Enable == nil || u.Config == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if u.Collector == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return *u.Enable
|
||||||
|
}
|
||||||
|
|
||||||
// Run runs a ticker to poll the unifi server and update Datadog.
|
// Run runs a ticker to poll the unifi server and update Datadog.
|
||||||
func (u *DatadogUnifi) Run(c poller.Collect) error {
|
func (u *DatadogUnifi) Run(c poller.Collect) error {
|
||||||
disabled := u == nil || u.Enable == nil || !(*u.Enable) || u.Config == nil
|
u.Collector = c
|
||||||
if disabled {
|
if !u.Enabled() {
|
||||||
u.LogDebugf("Datadog config is disabled, output is disabled.")
|
u.Logf("DataDog config missing (or disabled), DataDog output disabled!")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
u.Collector = c
|
|
||||||
u.Logf("Datadog is configured.")
|
u.Logf("Datadog is configured.")
|
||||||
u.setConfigDefaults()
|
u.setConfigDefaults()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,8 @@ type InfluxUnifi struct {
|
||||||
*InfluxDB
|
*InfluxDB
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ poller.OutputPlugin = &InfluxUnifi{}
|
||||||
|
|
||||||
type metric struct {
|
type metric struct {
|
||||||
Table string
|
Table string
|
||||||
Tags map[string]string
|
Tags map[string]string
|
||||||
|
|
@ -66,9 +68,9 @@ func init() { // nolint: gochecknoinits
|
||||||
u := &InfluxUnifi{InfluxDB: &InfluxDB{}, LastCheck: time.Now()}
|
u := &InfluxUnifi{InfluxDB: &InfluxDB{}, LastCheck: time.Now()}
|
||||||
|
|
||||||
poller.NewOutput(&poller.Output{
|
poller.NewOutput(&poller.Output{
|
||||||
Name: PluginName,
|
Name: PluginName,
|
||||||
Config: u.InfluxDB,
|
Config: u.InfluxDB,
|
||||||
Method: u.Run,
|
OutputPlugin: u,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -104,15 +106,31 @@ func (u *InfluxUnifi) PollController() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *InfluxUnifi) Enabled() bool {
|
||||||
|
if u == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if u.Config == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if u.Collector == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return !u.Disable
|
||||||
|
}
|
||||||
|
|
||||||
// Run runs a ticker to poll the unifi server and update influxdb.
|
// Run runs a ticker to poll the unifi server and update influxdb.
|
||||||
func (u *InfluxUnifi) Run(c poller.Collect) error {
|
func (u *InfluxUnifi) Run(c poller.Collect) error {
|
||||||
var err error
|
u.Collector = c
|
||||||
|
if !u.Enabled() {
|
||||||
if u.Collector = c; u.Config == nil || u.Disable {
|
|
||||||
u.Logf("InfluxDB config missing (or disabled), InfluxDB output disabled!")
|
u.Logf("InfluxDB config missing (or disabled), InfluxDB output disabled!")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
|
||||||
|
u.Collector = c
|
||||||
|
|
||||||
u.setConfigDefaults()
|
u.setConfigDefaults()
|
||||||
|
|
||||||
u.influx, err = influx.NewHTTPClient(influx.HTTPConfig{
|
u.influx, err = influx.NewHTTPClient(influx.HTTPConfig{
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,8 @@ type Loki struct {
|
||||||
last time.Time
|
last time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ poller.OutputPlugin = &Loki{}
|
||||||
|
|
||||||
// init is how this modular code is initialized by the main app.
|
// init is how this modular code is initialized by the main app.
|
||||||
// This module adds itself as an output module to the poller core.
|
// This module adds itself as an output module to the poller core.
|
||||||
func init() { // nolint: gochecknoinits
|
func init() { // nolint: gochecknoinits
|
||||||
|
|
@ -55,15 +57,26 @@ func init() { // nolint: gochecknoinits
|
||||||
}}
|
}}
|
||||||
|
|
||||||
poller.NewOutput(&poller.Output{
|
poller.NewOutput(&poller.Output{
|
||||||
Name: PluginName,
|
Name: PluginName,
|
||||||
Config: l,
|
Config: l,
|
||||||
Method: l.Run,
|
OutputPlugin: l,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *Loki) Enabled() bool {
|
||||||
|
if l == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if l.Config == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return !l.Disable
|
||||||
|
}
|
||||||
|
|
||||||
// Run is fired from the poller library after the Config is unmarshalled.
|
// Run is fired from the poller library after the Config is unmarshalled.
|
||||||
func (l *Loki) Run(collect poller.Collect) error {
|
func (l *Loki) Run(collect poller.Collect) error {
|
||||||
if l.Collect = collect; l.Config == nil || l.URL == "" || l.Disable {
|
l.Collect = collect
|
||||||
|
if l.Config == nil || l.URL == "" || !l.Enabled() {
|
||||||
l.Logf("Loki config missing (or disabled), Loki output disabled!")
|
l.Logf("Loki config missing (or disabled), Loki output disabled!")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ type plugin struct {
|
||||||
poller.Collect
|
poller.Collect
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ poller.OutputPlugin = &plugin{}
|
||||||
|
|
||||||
// Config represents the data that is unmarshalled from the up.conf config file for this plugins.
|
// Config represents the data that is unmarshalled from the up.conf config file for this plugins.
|
||||||
// See up.conf.example.mysql for sample input data.
|
// See up.conf.example.mysql for sample input data.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
|
@ -48,16 +50,30 @@ func init() {
|
||||||
u := &plugin{Config: &Config{}}
|
u := &plugin{Config: &Config{}}
|
||||||
|
|
||||||
poller.NewOutput(&poller.Output{
|
poller.NewOutput(&poller.Output{
|
||||||
Name: "mysql",
|
Name: "mysql",
|
||||||
Config: u, // pass in the struct *above* your config (so it can see the struct tags).
|
Config: u, // pass in the struct *above* your config (so it can see the struct tags).
|
||||||
Method: u.Run,
|
OutputPlugin: u,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *plugin) Enabled() bool {
|
||||||
|
if p == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if p.Config == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if p.Collect == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return !p.Disable
|
||||||
|
}
|
||||||
|
|
||||||
// Run gets called by poller core code. Return when the plugin stops working or has an error.
|
// Run gets called by poller core code. Return when the plugin stops working or has an error.
|
||||||
// In other words, don't run your code in a go routine, it already is.
|
// In other words, don't run your code in a go routine, it already is.
|
||||||
func (p *plugin) Run(c poller.Collect) error {
|
func (p *plugin) Run(c poller.Collect) error {
|
||||||
if p.Collect = c; c == nil || p.Config == nil || p.Disable {
|
p.Collect = c
|
||||||
|
if p.Config == nil || !p.Enabled() {
|
||||||
return nil // no config or disabled, bail out.
|
return nil // no config or disabled, bail out.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,12 +24,17 @@ type Collect interface {
|
||||||
Outputs() []string
|
Outputs() []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type OutputPlugin interface {
|
||||||
|
Run(Collect) error
|
||||||
|
Enabled() bool
|
||||||
|
}
|
||||||
|
|
||||||
// Output defines the output data for a metric exporter like influx or prometheus.
|
// Output defines the output data for a metric exporter like influx or prometheus.
|
||||||
// Output packages should call NewOutput with this struct in init().
|
// Output packages should call NewOutput with this struct in init().
|
||||||
type Output struct {
|
type Output struct {
|
||||||
Name string
|
Name string
|
||||||
Config any // Each config is passed into an unmarshaller later.
|
Config any // Each config is passed into an unmarshaller later.
|
||||||
Method func(Collect) error // Called on startup for each configured output.
|
OutputPlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewOutput should be called by each output package's init function.
|
// NewOutput should be called by each output package's init function.
|
||||||
|
|
@ -37,8 +42,8 @@ func NewOutput(o *Output) {
|
||||||
outputSync.Lock()
|
outputSync.Lock()
|
||||||
defer outputSync.Unlock()
|
defer outputSync.Unlock()
|
||||||
|
|
||||||
if o == nil || o.Method == nil {
|
if o == nil {
|
||||||
panic("nil output or method passed to poller.NewOutput")
|
panic("nil output passed to poller.NewOutput")
|
||||||
}
|
}
|
||||||
|
|
||||||
outputs = append(outputs, o)
|
outputs = append(outputs, o)
|
||||||
|
|
@ -81,9 +86,11 @@ func (u *UnifiPoller) runOutputMethods() (int, chan error) {
|
||||||
defer outputSync.RUnlock()
|
defer outputSync.RUnlock()
|
||||||
|
|
||||||
for _, o := range outputs {
|
for _, o := range outputs {
|
||||||
go func(o *Output) {
|
if o != nil && o.Enabled() {
|
||||||
err <- o.Method(u) // Run each output plugin
|
go func(o *Output) {
|
||||||
}(o)
|
err <- o.Run(u) // Run each output plugin
|
||||||
|
}(o)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return len(outputs), err
|
return len(outputs), err
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,8 @@ type promUnifi struct {
|
||||||
Collector poller.Collect
|
Collector poller.Collect
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ poller.OutputPlugin = &promUnifi{}
|
||||||
|
|
||||||
// Config is the input (config file) data used to initialize this output plugin.
|
// Config is the input (config file) data used to initialize this output plugin.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
// If non-empty, each of the collected metrics is prefixed by the
|
// If non-empty, each of the collected metrics is prefixed by the
|
||||||
|
|
@ -106,16 +108,30 @@ func init() { // nolint: gochecknoinits
|
||||||
u := &promUnifi{Config: &Config{}}
|
u := &promUnifi{Config: &Config{}}
|
||||||
|
|
||||||
poller.NewOutput(&poller.Output{
|
poller.NewOutput(&poller.Output{
|
||||||
Name: PluginName,
|
Name: PluginName,
|
||||||
Config: u,
|
Config: u,
|
||||||
Method: u.Run,
|
OutputPlugin: u,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *promUnifi) Enabled() bool {
|
||||||
|
if u == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if u.Config == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if u.Collector == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return !u.Disable
|
||||||
|
}
|
||||||
|
|
||||||
// Run creates the collectors and starts the web server up.
|
// Run creates the collectors and starts the web server up.
|
||||||
// Should be run in a Go routine. Returns nil if not configured.
|
// Should be run in a Go routine. Returns nil if not configured.
|
||||||
func (u *promUnifi) Run(c poller.Collect) error {
|
func (u *promUnifi) Run(c poller.Collect) error {
|
||||||
if u.Collector = c; u.Config == nil || u.Disable {
|
u.Collector = c
|
||||||
|
if u.Config == nil || !u.Enabled() {
|
||||||
u.Logf("Prometheus config missing (or disabled), Prometheus HTTP listener disabled!")
|
u.Logf("Prometheus config missing (or disabled), Prometheus HTTP listener disabled!")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,8 @@ type Server struct {
|
||||||
start time.Time
|
start time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ poller.OutputPlugin = &Server{}
|
||||||
|
|
||||||
// init is how this modular code is initialized by the main app.
|
// init is how this modular code is initialized by the main app.
|
||||||
// This module adds itself as an output module to the poller core.
|
// This module adds itself as an output module to the poller core.
|
||||||
func init() { // nolint: gochecknoinits
|
func init() { // nolint: gochecknoinits
|
||||||
|
|
@ -58,15 +60,29 @@ func init() { // nolint: gochecknoinits
|
||||||
plugins.Config = s.Config
|
plugins.Config = s.Config
|
||||||
|
|
||||||
poller.NewOutput(&poller.Output{
|
poller.NewOutput(&poller.Output{
|
||||||
Name: PluginName,
|
Name: PluginName,
|
||||||
Config: s,
|
Config: s,
|
||||||
Method: s.Run,
|
OutputPlugin: s,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) Enabled() bool {
|
||||||
|
if s == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if s.Config == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if s.Collect == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return s.Enable
|
||||||
|
}
|
||||||
|
|
||||||
// Run starts the server and gets things going.
|
// Run starts the server and gets things going.
|
||||||
func (s *Server) Run(c poller.Collect) error {
|
func (s *Server) Run(c poller.Collect) error {
|
||||||
if s.Collect = c; s.Config == nil || s.Port == 0 || s.HTMLPath == "" || !s.Enable {
|
s.Collect = c
|
||||||
|
if s.Config == nil || s.Port == 0 || s.HTMLPath == "" || !s.Enabled() {
|
||||||
s.Logf("Internal web server disabled!")
|
s.Logf("Internal web server disabled!")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue