-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add unbound input plugin #3434
Merged
Merged
Add unbound input plugin #3434
Changes from 9 commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
3f14a43
add unbound input plugin
25f2027
set to unbound
9ef60ac
set to unbound
fd7b457
go fmt
e1f6302
unbound for windows
3bbbc20
remove unecessary file
b707914
Try to include previous pull request comments
9d28bad
update telegraf.conf
b4153e6
Timeout is now an internal.Duration object
1798d8c
Use fieldpass builtin telegraf filter
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
# 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" | ||
|
||
## By default, telegraf gather stats for 4 metric points. | ||
## Setting stats will override the defaults shown below. | ||
## Glob matching can be used, ie, stats = ["total.*"] | ||
## stats may also be set to ["*"], which will collect all stats | ||
## except histogram.* statistics that will never be collected. | ||
stats = ["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,161 @@ | ||
// +build !windows | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you remove this build flag, and also in the test file. |
||
|
||
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 { | ||
Stats []string | ||
Binary string | ||
Timeout internal.Duration | ||
UseSudo bool | ||
|
||
filter filter.Filter | ||
run runner | ||
} | ||
|
||
var defaultStats = []string{"total.*", "num.*", "time.up", "mem.*"} | ||
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" | ||
|
||
## By default, telegraf gather stats for 4 metric points. | ||
## Setting stats will override the defaults shown below. | ||
## Glob matching can be used, ie, stats = ["total.*"] | ||
## stats may also be set to ["*"], which will collect all stats | ||
## except histogram.* statistics that will never be collected. | ||
stats = ["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 the configured 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 { | ||
if s.filter == nil { | ||
var err error | ||
if len(s.Stats) == 0 { | ||
s.filter, err = filter.Compile(defaultStats) | ||
} else { | ||
// change "all" -> "*": | ||
if s.Stats[0] == "all" { | ||
s.Stats[0] = "*" | ||
} | ||
s.filter, err = filter.Compile(s.Stats) | ||
} | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
// 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] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could panic if somehow there are not two fields, make sure to guard against this. |
||
|
||
// Filter value | ||
if s.filter != nil && (!s.filter.Match(stat) || 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, | ||
Stats: defaultStats, | ||
Binary: defaultBinary, | ||
Timeout: defaultTimeout, | ||
UseSudo: false, | ||
} | ||
}) | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should remove this filter, users can simply use the builtin fielddrop/fieldpass filters to get the same behavior.