Add server option to unbound plugin (#3713)
This commit is contained in:
parent
20a5887a4a
commit
4a4557e371
|
@ -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)
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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: "",
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue