-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
51ec55f
commit f89c774
Showing
6 changed files
with
493 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
# Unbound Input Plugin | ||
|
||
This plugin gathers stats from [Unbound - a validating, recursive, and caching DNS resolver](https://www.unbound.net/) | ||
|
||
### Configuration: | ||
|
||
```toml | ||
# A plugin to collect stats from Unbound - a validating, recursive, and caching DNS resolver | ||
[[inputs.unbound]] | ||
## If running as a restricted user you can prepend sudo for additional access: | ||
#use_sudo = false | ||
|
||
## The default location of the unbound-control binary can be overridden with: | ||
binary = "/usr/sbin/unbound-control" | ||
|
||
## The default timeout of 1s can be overriden with: | ||
#timeout = "1s" | ||
|
||
## Use the builtin fielddrop/fieldpass telegraf filters in order to keep only specific fields | ||
fieldpass = ["total_*", "num_*","time_up", "mem_*"] | ||
``` | ||
|
||
### Measurements & Fields: | ||
|
||
This is the full list of stats provided by unbound-control and potentially collected by telegram | ||
depending of your unbound configuration. Histogram related statistics will never be collected, | ||
extended statistics can also be imported ("extended-statistics: yes" in unbound configuration). | ||
In the output, the dots in the unbound-control stat name are replaced by underscores(see | ||
https://www.unbound.net/documentation/unbound-control.html for details). | ||
|
||
- unbound | ||
thread0_num_queries | ||
thread0_num_cachehits | ||
thread0_num_cachemiss | ||
thread0_num_prefetch | ||
thread0_num_recursivereplies | ||
thread0_requestlist_avg | ||
thread0_requestlist_max | ||
thread0_requestlist_overwritten | ||
thread0_requestlist_exceeded | ||
thread0_requestlist_current_all | ||
thread0_requestlist_current_user | ||
thread0_recursion_time_avg | ||
thread0_recursion_time_median | ||
total_num_queries | ||
total_num_cachehits | ||
total_num_cachemiss | ||
total_num_prefetch | ||
total_num_recursivereplies | ||
total_requestlist_avg | ||
total_requestlist_max | ||
total_requestlist_overwritten | ||
total_requestlist_exceeded | ||
total_requestlist_current_all | ||
total_requestlist_current_user | ||
total_recursion_time_avg | ||
total_recursion_time_median | ||
time_now | ||
time_up | ||
time_elapsed | ||
mem_total_sbrk | ||
mem_cache_rrset | ||
mem_cache_message | ||
mem_mod_iterator | ||
mem_mod_validator | ||
num_query_type_A | ||
num_query_type_PTR | ||
num_query_type_TXT | ||
num_query_type_AAAA | ||
num_query_type_SRV | ||
num_query_type_ANY | ||
num_query_class_IN | ||
num_query_opcode_QUERY | ||
num_query_tcp | ||
num_query_ipv6 | ||
num_query_flags_QR | ||
num_query_flags_AA | ||
num_query_flags_TC | ||
num_query_flags_RD | ||
num_query_flags_RA | ||
num_query_flags_Z | ||
num_query_flags_AD | ||
num_query_flags_CD | ||
num_query_edns_present | ||
num_query_edns_DO | ||
num_answer_rcode_NOERROR | ||
num_answer_rcode_SERVFAIL | ||
num_answer_rcode_NXDOMAIN | ||
num_answer_rcode_nodata | ||
num_answer_secure | ||
num_answer_bogus | ||
num_rrset_bogus | ||
unwanted_queries | ||
unwanted_replies | ||
|
||
### Permissions: | ||
|
||
It's important to note that this plugin references unbound-control, which may require additional permissions to execute successfully. | ||
Depending on the user/group permissions of the telegraf user executing this plugin, you may need to alter the group membership, set facls, or use sudo. | ||
|
||
**Group membership (Recommended)**: | ||
```bash | ||
$ groups telegraf | ||
telegraf : telegraf | ||
|
||
$ usermod -a -G unbound telegraf | ||
|
||
$ groups telegraf | ||
telegraf : telegraf unbound | ||
``` | ||
|
||
**Sudo privileges**: | ||
If you use this method, you will need the following in your telegraf config: | ||
```toml | ||
[[inputs.unbound]] | ||
use_sudo = true | ||
``` | ||
|
||
You will also need to update your sudoers file: | ||
```bash | ||
$ visudo | ||
# Add the following line: | ||
telegraf ALL=(ALL) NOPASSWD: /usr/sbin/unbound-control | ||
``` | ||
|
||
Please use the solution you see as most appropriate. | ||
|
||
### Example Output: | ||
|
||
``` | ||
telegraf --config etc/telegraf.conf --input-filter unbound --test | ||
* Plugin: inputs.unbound, Collection 1 | ||
> unbound,host=localhost total_num_cachehits=0,total_num_prefetch=0,total_requestlist_avg=0,total_requestlist_max=0,total_recursion_time_median=0,total_num_queries=0,total_requestlist_overwritten=0,total_requestlist_current_all=0,time_up=159185.583967,total_num_recursivereplies=0,total_requestlist_exceeded=0,total_requestlist_current_user=0,total_recursion_time_avg=0,total_tcpusage=0,total_num_cachemiss=0 1510130793000000000 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
package unbound | ||
|
||
import ( | ||
"bufio" | ||
"bytes" | ||
"fmt" | ||
"os/exec" | ||
"strconv" | ||
"strings" | ||
"time" | ||
|
||
"github.com/influxdata/telegraf" | ||
"github.com/influxdata/telegraf/filter" | ||
"github.com/influxdata/telegraf/internal" | ||
"github.com/influxdata/telegraf/plugins/inputs" | ||
) | ||
|
||
type runner func(cmdName string, Timeout internal.Duration, UseSudo bool) (*bytes.Buffer, error) | ||
|
||
// Unbound is used to store configuration values | ||
type Unbound struct { | ||
Binary string | ||
Timeout internal.Duration | ||
UseSudo bool | ||
|
||
filter filter.Filter | ||
run runner | ||
} | ||
|
||
var defaultBinary = "/usr/sbin/unbound-control" | ||
var defaultTimeout = internal.Duration{Duration: time.Second} | ||
|
||
var sampleConfig = ` | ||
## If running as a restricted user you can prepend sudo for additional access: | ||
#use_sudo = false | ||
## The default location of the unbound-control binary can be overridden with: | ||
binary = "/usr/sbin/unbound-control" | ||
## The default timeout of 1s can be overriden with: | ||
timeout = "1s" | ||
## Use the builtin fielddrop/fieldpass telegraf filters in order to keep/remove specific fields | ||
fieldpass = ["total_*", "num_*","time_up", "mem_*"] | ||
` | ||
|
||
func (s *Unbound) Description() string { | ||
return "A plugin to collect stats from Unbound - a validating, recursive, and caching DNS resolver " | ||
} | ||
|
||
// SampleConfig displays configuration instructions | ||
func (s *Unbound) SampleConfig() string { | ||
return sampleConfig | ||
} | ||
|
||
// Shell out to unbound_stat and return the output | ||
func unboundRunner(cmdName string, Timeout internal.Duration, UseSudo bool) (*bytes.Buffer, error) { | ||
cmdArgs := []string{"stats_noreset"} | ||
|
||
cmd := exec.Command(cmdName, cmdArgs...) | ||
|
||
if UseSudo { | ||
cmdArgs = append([]string{cmdName}, cmdArgs...) | ||
cmd = exec.Command("sudo", cmdArgs...) | ||
} | ||
|
||
var out bytes.Buffer | ||
cmd.Stdout = &out | ||
err := internal.RunTimeout(cmd, Timeout.Duration) | ||
if err != nil { | ||
return &out, fmt.Errorf("error running unbound-control: %s", err) | ||
} | ||
|
||
return &out, nil | ||
} | ||
|
||
// Gather collects stats from unbound-control and adds them to the Accumulator | ||
// | ||
// All the dots in stat name will replaced by underscores. Histogram statistics will not be collected. | ||
func (s *Unbound) Gather(acc telegraf.Accumulator) error { | ||
|
||
// Always exclude histrogram statistics | ||
stat_excluded := []string{"histogram.*"} | ||
filter_excluded, err := filter.Compile(stat_excluded) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
out, err := s.run(s.Binary, s.Timeout, s.UseSudo) | ||
if err != nil { | ||
return fmt.Errorf("error gathering metrics: %s", err) | ||
} | ||
|
||
// Process values | ||
fields := make(map[string]interface{}) | ||
scanner := bufio.NewScanner(out) | ||
for scanner.Scan() { | ||
|
||
cols := strings.Split(scanner.Text(), "=") | ||
|
||
// Check split correctness | ||
if len(cols) != 2 { | ||
continue | ||
} | ||
|
||
stat := cols[0] | ||
value := cols[1] | ||
|
||
// Filter value | ||
if filter_excluded.Match(stat) { | ||
continue | ||
} | ||
|
||
field := strings.Replace(stat, ".", "_", -1) | ||
|
||
fields[field], err = strconv.ParseFloat(value, 64) | ||
if err != nil { | ||
acc.AddError(fmt.Errorf("Expected a numerical value for %s = %v\n", | ||
stat, value)) | ||
} | ||
} | ||
|
||
acc.AddFields("unbound", fields, nil) | ||
|
||
return nil | ||
} | ||
|
||
func init() { | ||
inputs.Add("unbound", func() telegraf.Input { | ||
return &Unbound{ | ||
run: unboundRunner, | ||
Binary: defaultBinary, | ||
Timeout: defaultTimeout, | ||
UseSudo: false, | ||
} | ||
}) | ||
} |
Oops, something went wrong.