telegraf/plugins/inputs/exec/exec.go

95 lines
1.8 KiB
Go
Raw Normal View History

2015-08-06 00:29:27 +00:00
package exec
import (
"bytes"
"encoding/json"
"fmt"
"os/exec"
"github.com/gonuts/go-shellquote"
2016-01-20 18:57:35 +00:00
"github.com/influxdata/telegraf/internal"
"github.com/influxdata/telegraf/plugins/inputs"
2015-08-06 00:29:27 +00:00
)
const sampleConfig = `
# NOTE This plugin only reads numerical measurements, strings and booleans
# will be ignored.
# the command to run
command = "/usr/bin/mycollector --foo=bar"
2015-08-06 00:29:27 +00:00
2016-01-07 20:39:43 +00:00
# measurement name suffix (for separating different commands)
name_suffix = "_mycollector"
2015-09-23 18:21:42 +00:00
`
2015-08-06 00:29:27 +00:00
type Exec struct {
Command string
2015-08-06 00:29:27 +00:00
runner Runner
2015-08-06 00:29:27 +00:00
}
2015-09-23 18:21:42 +00:00
type Runner interface {
Run(*Exec) ([]byte, error)
2015-08-06 00:29:27 +00:00
}
2015-09-23 18:21:42 +00:00
type CommandRunner struct{}
func (c CommandRunner) Run(e *Exec) ([]byte, error) {
split_cmd, err := shellquote.Split(e.Command)
2015-09-23 18:21:42 +00:00
if err != nil || len(split_cmd) == 0 {
return nil, fmt.Errorf("exec: unable to parse command, %s", err)
}
cmd := exec.Command(split_cmd[0], split_cmd[1:]...)
2015-08-06 00:29:27 +00:00
var out bytes.Buffer
cmd.Stdout = &out
if err := cmd.Run(); err != nil {
return nil, fmt.Errorf("exec: %s for command '%s'", err, e.Command)
2015-08-06 00:29:27 +00:00
}
return out.Bytes(), nil
}
2015-09-23 18:21:42 +00:00
func NewExec() *Exec {
return &Exec{runner: CommandRunner{}}
2015-09-23 18:21:42 +00:00
}
2015-08-06 00:29:27 +00:00
func (e *Exec) SampleConfig() string {
return sampleConfig
}
func (e *Exec) Description() string {
return "Read flattened metrics from one or more commands that output JSON to stdout"
}
2016-01-07 20:39:43 +00:00
func (e *Exec) Gather(acc inputs.Accumulator) error {
out, err := e.runner.Run(e)
if err != nil {
return err
2015-08-06 00:29:27 +00:00
}
var jsonOut interface{}
err = json.Unmarshal(out, &jsonOut)
if err != nil {
return fmt.Errorf("exec: unable to parse output of '%s' as JSON, %s",
e.Command, err)
}
f := internal.JSONFlattener{}
err = f.FlattenJSON("", jsonOut)
if err != nil {
return err
}
2015-08-06 00:29:27 +00:00
2016-01-07 20:39:43 +00:00
acc.AddFields("exec", f.Fields, nil)
return nil
2015-08-06 00:29:27 +00:00
}
func init() {
2016-01-07 20:39:43 +00:00
inputs.Add("exec", func() inputs.Input {
2015-08-06 00:29:27 +00:00
return NewExec()
})
}