Add server option to unbound plugin (#3713)

This commit is contained in:
Fred Cox 2018-02-21 02:06:13 +02:00 committed by Daniel Nelson
parent 20a5887a4a
commit 4a4557e371
4 changed files with 45 additions and 7 deletions

View File

@ -208,7 +208,7 @@ configuration options.
* [teamspeak](./plugins/inputs/teamspeak) * [teamspeak](./plugins/inputs/teamspeak)
* [tomcat](./plugins/inputs/tomcat) * [tomcat](./plugins/inputs/tomcat)
* [twemproxy](./plugins/inputs/twemproxy) * [twemproxy](./plugins/inputs/twemproxy)
* [unbound](./plugins/input/unbound) * [unbound](./plugins/inputs/unbound)
* [varnish](./plugins/inputs/varnish) * [varnish](./plugins/inputs/varnish)
* [zfs](./plugins/inputs/zfs) * [zfs](./plugins/inputs/zfs)
* [zookeeper](./plugins/inputs/zookeeper) * [zookeeper](./plugins/inputs/zookeeper)

View File

@ -18,6 +18,10 @@ This plugin gathers stats from [Unbound - a validating, recursive, and caching D
## Use the builtin fielddrop/fieldpass telegraf filters in order to keep only specific fields ## Use the builtin fielddrop/fieldpass telegraf filters in order to keep only specific fields
fieldpass = ["total_*", "num_*","time_up", "mem_*"] fieldpass = ["total_*", "num_*","time_up", "mem_*"]
## IP of server to connect to, read from unbound conf default, optionally ':port'
## Will lookup IP if given a hostname
server = "127.0.0.1:8953"
``` ```
### Measurements & Fields: ### Measurements & Fields:

View File

@ -3,7 +3,9 @@ package unbound
import ( import (
"bufio" "bufio"
"bytes" "bytes"
"context"
"fmt" "fmt"
"net"
"os/exec" "os/exec"
"strconv" "strconv"
"strings" "strings"
@ -15,13 +17,14 @@ import (
"github.com/influxdata/telegraf/plugins/inputs" "github.com/influxdata/telegraf/plugins/inputs"
) )
type runner func(cmdName string, Timeout internal.Duration, UseSudo bool) (*bytes.Buffer, error) type runner func(cmdName string, Timeout internal.Duration, UseSudo bool, Server string) (*bytes.Buffer, error)
// Unbound is used to store configuration values // Unbound is used to store configuration values
type Unbound struct { type Unbound struct {
Binary string Binary string
Timeout internal.Duration Timeout internal.Duration
UseSudo bool UseSudo bool
Server string
filter filter.Filter filter filter.Filter
run runner run runner
@ -42,6 +45,10 @@ var sampleConfig = `
## Use the builtin fielddrop/fieldpass telegraf filters in order to keep/remove specific fields ## Use the builtin fielddrop/fieldpass telegraf filters in order to keep/remove specific fields
fieldpass = ["total_*", "num_*","time_up", "mem_*"] fieldpass = ["total_*", "num_*","time_up", "mem_*"]
## IP of server to connect to, read from unbound conf default, optionally ':port'
## Will lookup IP if given a hostname
server = "127.0.0.1:8953"
` `
func (s *Unbound) Description() string { func (s *Unbound) Description() string {
@ -54,9 +61,35 @@ func (s *Unbound) SampleConfig() string {
} }
// Shell out to unbound_stat and return the output // Shell out to unbound_stat and return the output
func unboundRunner(cmdName string, Timeout internal.Duration, UseSudo bool) (*bytes.Buffer, error) { func unboundRunner(cmdName string, Timeout internal.Duration, UseSudo bool, Server string) (*bytes.Buffer, error) {
cmdArgs := []string{"stats_noreset"} cmdArgs := []string{"stats_noreset"}
if Server != "" {
host, port, err := net.SplitHostPort(Server)
if err != nil { // No port was specified
host = Server
port = ""
}
// Unbound control requires an IP address, and we want to be nice to the user
resolver := net.Resolver{}
ctx, lookUpCancel := context.WithTimeout(context.Background(), Timeout.Duration)
defer lookUpCancel()
serverIps, err := resolver.LookupIPAddr(ctx, host)
if err != nil {
return nil, fmt.Errorf("error looking up ip for server: %s: %s", Server, err)
}
if len(serverIps) == 0 {
return nil, fmt.Errorf("error no ip for server: %s: %s", Server, err)
}
server := serverIps[0].IP.String()
if port != "" {
server = server + "@" + port
}
cmdArgs = append(cmdArgs, "-s", server)
}
cmd := exec.Command(cmdName, cmdArgs...) cmd := exec.Command(cmdName, cmdArgs...)
if UseSudo { if UseSudo {
@ -86,7 +119,7 @@ func (s *Unbound) Gather(acc telegraf.Accumulator) error {
return err return err
} }
out, err := s.run(s.Binary, s.Timeout, s.UseSudo) out, err := s.run(s.Binary, s.Timeout, s.UseSudo, s.Server)
if err != nil { if err != nil {
return fmt.Errorf("error gathering metrics: %s", err) return fmt.Errorf("error gathering metrics: %s", err)
} }
@ -132,6 +165,7 @@ func init() {
Binary: defaultBinary, Binary: defaultBinary,
Timeout: defaultTimeout, Timeout: defaultTimeout,
UseSudo: false, UseSudo: false,
Server: "",
} }
}) })
} }

View File

@ -12,8 +12,8 @@ import (
var TestTimeout = internal.Duration{Duration: time.Second} var TestTimeout = internal.Duration{Duration: time.Second}
func UnboundControl(output string, Timeout internal.Duration, useSudo bool) func(string, internal.Duration, bool) (*bytes.Buffer, error) { func UnboundControl(output string, Timeout internal.Duration, useSudo bool, Server string) func(string, internal.Duration, bool, string) (*bytes.Buffer, error) {
return func(string, internal.Duration, bool) (*bytes.Buffer, error) { return func(string, internal.Duration, bool, string) (*bytes.Buffer, error) {
return bytes.NewBuffer([]byte(output)), nil return bytes.NewBuffer([]byte(output)), nil
} }
} }
@ -21,7 +21,7 @@ func UnboundControl(output string, Timeout internal.Duration, useSudo bool) func
func TestParseFullOutput(t *testing.T) { func TestParseFullOutput(t *testing.T) {
acc := &testutil.Accumulator{} acc := &testutil.Accumulator{}
v := &Unbound{ v := &Unbound{
run: UnboundControl(fullOutput, TestTimeout, true), run: UnboundControl(fullOutput, TestTimeout, true, ""),
} }
err := v.Gather(acc) err := v.Gather(acc)