Merge pull request #458 from unpoller/output-plugin-interface
Output Plugin Interface
This commit is contained in:
commit
1c847303e4
|
|
@ -69,8 +69,8 @@
|
|||
# How often to poll UniFi and report to Datadog.
|
||||
interval = "2m"
|
||||
|
||||
# To disable this output plugin
|
||||
disable = true
|
||||
# To enable this output plugin
|
||||
enable = false
|
||||
|
||||
# Datadog Custom Options
|
||||
|
||||
|
|
@ -84,7 +84,7 @@
|
|||
# tags = [ "customer:abc_corp" ]
|
||||
|
||||
# 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
|
||||
|
|
|
|||
|
|
@ -35,6 +35,15 @@
|
|||
}
|
||||
},
|
||||
|
||||
"datadog": {
|
||||
"enable": false,
|
||||
"address": "localhost:8125",
|
||||
"namespace": "",
|
||||
"tags": [
|
||||
"customer:abcde"
|
||||
]
|
||||
}
|
||||
|
||||
"unifi": {
|
||||
"dynamic": false,
|
||||
"defaults": {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,13 @@ webserver:
|
|||
accounts:
|
||||
captain: "$2a$04$mxw6i0LKH6u46oaLK2cq5eCTAAFkfNiRpzNbz.EyvJZZWNa2FzIlS"
|
||||
|
||||
datadog:
|
||||
enable: false
|
||||
address: localhost:8125
|
||||
namespace: ""
|
||||
tags:
|
||||
- customer:abcdef
|
||||
|
||||
unifi:
|
||||
dynamic: false
|
||||
defaults:
|
||||
|
|
|
|||
|
|
@ -112,13 +112,15 @@ type DatadogUnifi struct {
|
|||
*Datadog
|
||||
}
|
||||
|
||||
var _ poller.OutputPlugin = &DatadogUnifi{}
|
||||
|
||||
func init() { // nolint: gochecknoinits
|
||||
u := &DatadogUnifi{Datadog: &Datadog{}, LastCheck: time.Now()}
|
||||
|
||||
poller.NewOutput(&poller.Output{
|
||||
Name: "datadog",
|
||||
Config: u.Datadog,
|
||||
Method: u.Run,
|
||||
Name: "datadog",
|
||||
Config: u.Datadog,
|
||||
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.
|
||||
func (u *DatadogUnifi) Run(c poller.Collect) error {
|
||||
disabled := u == nil || u.Enable == nil || !(*u.Enable) || u.Config == nil
|
||||
if disabled {
|
||||
u.LogDebugf("Datadog config is disabled, output is disabled.")
|
||||
u.Collector = c
|
||||
if !u.Enabled() {
|
||||
u.Logf("DataDog config missing (or disabled), DataDog output disabled!")
|
||||
return nil
|
||||
}
|
||||
u.Collector = c
|
||||
u.Logf("Datadog is configured.")
|
||||
u.setConfigDefaults()
|
||||
|
||||
|
|
|
|||
|
|
@ -77,6 +77,8 @@ type InfluxUnifi struct {
|
|||
*InfluxDB
|
||||
}
|
||||
|
||||
var _ poller.OutputPlugin = &InfluxUnifi{}
|
||||
|
||||
type metric struct {
|
||||
Table string
|
||||
Tags map[string]string
|
||||
|
|
@ -88,9 +90,9 @@ func init() { // nolint: gochecknoinits
|
|||
u := &InfluxUnifi{InfluxDB: &InfluxDB{}, LastCheck: time.Now()}
|
||||
|
||||
poller.NewOutput(&poller.Output{
|
||||
Name: PluginName,
|
||||
Config: u.InfluxDB,
|
||||
Method: u.Run,
|
||||
Name: PluginName,
|
||||
Config: u.InfluxDB,
|
||||
OutputPlugin: u,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -130,15 +132,29 @@ 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.
|
||||
func (u *InfluxUnifi) Run(c poller.Collect) error {
|
||||
var err error
|
||||
|
||||
if u.Collector = c; u.Config == nil || u.Disable {
|
||||
u.Collector = c
|
||||
if !u.Enabled() {
|
||||
u.Logf("InfluxDB config missing (or disabled), InfluxDB output disabled!")
|
||||
return nil
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
u.setConfigDefaults()
|
||||
|
||||
if u.IsVersion2 {
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ type Loki struct {
|
|||
last time.Time
|
||||
}
|
||||
|
||||
var _ poller.OutputPlugin = &Loki{}
|
||||
|
||||
// init is how this modular code is initialized by the main app.
|
||||
// This module adds itself as an output module to the poller core.
|
||||
func init() { // nolint: gochecknoinits
|
||||
|
|
@ -55,15 +57,26 @@ func init() { // nolint: gochecknoinits
|
|||
}}
|
||||
|
||||
poller.NewOutput(&poller.Output{
|
||||
Name: PluginName,
|
||||
Config: l,
|
||||
Method: l.Run,
|
||||
Name: PluginName,
|
||||
Config: l,
|
||||
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.
|
||||
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!")
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ type plugin struct {
|
|||
poller.Collect
|
||||
}
|
||||
|
||||
var _ poller.OutputPlugin = &plugin{}
|
||||
|
||||
// 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.
|
||||
type Config struct {
|
||||
|
|
@ -48,16 +50,30 @@ func init() {
|
|||
u := &plugin{Config: &Config{}}
|
||||
|
||||
poller.NewOutput(&poller.Output{
|
||||
Name: "mysql",
|
||||
Config: u, // pass in the struct *above* your config (so it can see the struct tags).
|
||||
Method: u.Run,
|
||||
Name: "mysql",
|
||||
Config: u, // pass in the struct *above* your config (so it can see the struct tags).
|
||||
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.
|
||||
// In other words, don't run your code in a go routine, it already is.
|
||||
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.
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,12 +24,17 @@ type Collect interface {
|
|||
Outputs() []string
|
||||
}
|
||||
|
||||
type OutputPlugin interface {
|
||||
Run(Collect) error
|
||||
Enabled() bool
|
||||
}
|
||||
|
||||
// Output defines the output data for a metric exporter like influx or prometheus.
|
||||
// Output packages should call NewOutput with this struct in init().
|
||||
type Output struct {
|
||||
Name string
|
||||
Config any // Each config is passed into an unmarshaller later.
|
||||
Method func(Collect) error // Called on startup for each configured output.
|
||||
Config any // Each config is passed into an unmarshaller later.
|
||||
OutputPlugin
|
||||
}
|
||||
|
||||
// NewOutput should be called by each output package's init function.
|
||||
|
|
@ -37,8 +42,8 @@ func NewOutput(o *Output) {
|
|||
outputSync.Lock()
|
||||
defer outputSync.Unlock()
|
||||
|
||||
if o == nil || o.Method == nil {
|
||||
panic("nil output or method passed to poller.NewOutput")
|
||||
if o == nil {
|
||||
panic("nil output passed to poller.NewOutput")
|
||||
}
|
||||
|
||||
outputs = append(outputs, o)
|
||||
|
|
@ -81,9 +86,11 @@ func (u *UnifiPoller) runOutputMethods() (int, chan error) {
|
|||
defer outputSync.RUnlock()
|
||||
|
||||
for _, o := range outputs {
|
||||
go func(o *Output) {
|
||||
err <- o.Method(u) // Run each output plugin
|
||||
}(o)
|
||||
if o != nil && o.Enabled() {
|
||||
go func(o *Output) {
|
||||
err <- o.Run(u) // Run each output plugin
|
||||
}(o)
|
||||
}
|
||||
}
|
||||
|
||||
return len(outputs), err
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ type promUnifi struct {
|
|||
Collector poller.Collect
|
||||
}
|
||||
|
||||
var _ poller.OutputPlugin = &promUnifi{}
|
||||
|
||||
// Config is the input (config file) data used to initialize this output plugin.
|
||||
type Config struct {
|
||||
// If non-empty, each of the collected metrics is prefixed by the
|
||||
|
|
@ -106,16 +108,30 @@ func init() { // nolint: gochecknoinits
|
|||
u := &promUnifi{Config: &Config{}}
|
||||
|
||||
poller.NewOutput(&poller.Output{
|
||||
Name: PluginName,
|
||||
Config: u,
|
||||
Method: u.Run,
|
||||
Name: PluginName,
|
||||
Config: u,
|
||||
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.
|
||||
// Should be run in a Go routine. Returns nil if not configured.
|
||||
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!")
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ type Server struct {
|
|||
start time.Time
|
||||
}
|
||||
|
||||
var _ poller.OutputPlugin = &Server{}
|
||||
|
||||
// init is how this modular code is initialized by the main app.
|
||||
// This module adds itself as an output module to the poller core.
|
||||
func init() { // nolint: gochecknoinits
|
||||
|
|
@ -58,15 +60,29 @@ func init() { // nolint: gochecknoinits
|
|||
plugins.Config = s.Config
|
||||
|
||||
poller.NewOutput(&poller.Output{
|
||||
Name: PluginName,
|
||||
Config: s,
|
||||
Method: s.Run,
|
||||
Name: PluginName,
|
||||
Config: s,
|
||||
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.
|
||||
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!")
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue