137 lines
4.0 KiB
Go
137 lines
4.0 KiB
Go
package example
|
|
|
|
import (
|
|
"fmt"
|
|
"math/rand"
|
|
"time"
|
|
|
|
"github.com/influxdata/telegraf"
|
|
"github.com/influxdata/telegraf/config"
|
|
"github.com/influxdata/telegraf/plugins/inputs"
|
|
)
|
|
|
|
// Example struct should be named the same as the Plugin
|
|
type Example struct {
|
|
// Example for a mandatory option to set a tag
|
|
DeviceName string `toml:"device_name"`
|
|
|
|
// Config options are converted to the correct type automatically
|
|
NumberFields int64 `toml:"number_fields"`
|
|
|
|
// We can also use booleans and have diverging names between user-configuration options and struct members
|
|
EnableRandomVariable bool `toml:"enable_random"`
|
|
|
|
// Example of passing a duration option allowing the format of e.g. "100ms", "5m" or "1h"
|
|
Timeout config.Duration `toml:"timeout"`
|
|
|
|
// Telegraf logging facility
|
|
// The exact name is important to allow automatic initialization by telegraf.
|
|
Log telegraf.Logger `toml:"-"`
|
|
|
|
// This is a non-exported internal state.
|
|
count int64
|
|
}
|
|
|
|
// Usually the default (example) configuration is contained in this constant.
|
|
// Please use '## '' to denote comments and '# ' to specify default settings and start each line with two spaces.
|
|
const sampleConfig = `
|
|
## Device name used as a tag
|
|
## This is a mandatory option that needs to be set by the user, so we do not
|
|
## comment it.
|
|
device_name = ""
|
|
|
|
## Number of fields contained in the output
|
|
## This should be greater than zero and less then ten.
|
|
## Here, two is the default, so we comment the option with the default value shown.
|
|
# number_fields = 2
|
|
|
|
## Enable setting the field(s) to random values
|
|
## By default, the field values are set to zero.
|
|
# enable_random = false
|
|
|
|
## Specify a duration allowing time-unit suffixes ('ns','ms', 's', 'm', etc.)
|
|
# timeout = "100ms"
|
|
`
|
|
|
|
// Description will appear directly above the plugin definition in the config file
|
|
func (m *Example) Description() string {
|
|
return `This is an example plugin`
|
|
}
|
|
|
|
// SampleConfig will populate the sample configuration portion of the plugin's configuration
|
|
func (m *Example) SampleConfig() string {
|
|
return sampleConfig
|
|
}
|
|
|
|
// Init can be implemented to do one-time processing stuff like initializing variables
|
|
func (m *Example) Init() error {
|
|
// Check your options according to your requirements
|
|
if m.DeviceName == "" {
|
|
return fmt.Errorf("device name cannot be empty")
|
|
}
|
|
|
|
// Set your defaults.
|
|
// Please note: In golang all fields are initialzed to their nil value, so you should not
|
|
// set these fields if the nil value is what you want (e.g. for booleans).
|
|
if m.NumberFields < 1 {
|
|
m.Log.Debugf("Setting number of fields to default from invalid value %d", m.NumberFields)
|
|
m.NumberFields = 2
|
|
}
|
|
|
|
// Initialze your internal states
|
|
m.count = 1
|
|
|
|
return nil
|
|
}
|
|
|
|
// Gather defines what data the plugin will gather.
|
|
func (m *Example) Gather(acc telegraf.Accumulator) error {
|
|
// Imagine some completely arbitrary error occuring here
|
|
if m.NumberFields > 10 {
|
|
return fmt.Errorf("too many fields")
|
|
}
|
|
|
|
// For illustration we gather three metrics in one go
|
|
for run := 0; run < 3; run++ {
|
|
// Imagine an error occurs here but you want to keep the other
|
|
// metrics, then you cannot simply return, as this would drop
|
|
// all later metrics. Simply accumulate errors in this case
|
|
// and ignore the metric.
|
|
if m.EnableRandomVariable && m.DeviceName == "flappy" && run > 1 {
|
|
acc.AddError(fmt.Errorf("too many runs for random values"))
|
|
continue
|
|
}
|
|
|
|
// Construct the fields
|
|
fields := map[string]interface{}{"count": m.count}
|
|
for i := int64(1); i < m.NumberFields; i++ {
|
|
name := fmt.Sprintf("field%d", i)
|
|
value := 0.0
|
|
if m.EnableRandomVariable {
|
|
value = rand.Float64()
|
|
}
|
|
fields[name] = value
|
|
}
|
|
|
|
// Construct the tags
|
|
tags := map[string]string{"device": m.DeviceName}
|
|
|
|
// Add the metric with the current timestamp
|
|
acc.AddFields("example", fields, tags)
|
|
|
|
m.count++
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Register the plugin
|
|
func init() {
|
|
inputs.Add("example", func() telegraf.Input {
|
|
return &Example{
|
|
// Set the default timeout here to distinguish it from the user setting it to zero
|
|
Timeout: config.Duration(100 * time.Millisecond),
|
|
}
|
|
})
|
|
}
|