Add bind input plugin (#5653)

This commit is contained in:
Daniel Fenert 2019-04-04 00:59:47 +02:00 committed by Daniel Nelson
parent 1bcbc3eea7
commit a61cb4dca5
15 changed files with 3350 additions and 0 deletions

View File

@ -139,6 +139,7 @@ For documentation on the latest development code see the [documentation index][d
* [aws cloudwatch](./plugins/inputs/cloudwatch)
* [bcache](./plugins/inputs/bcache)
* [beanstalkd](./plugins/inputs/beanstalkd)
* [bind](./plugins/inputs/bind)
* [bond](./plugins/inputs/bond)
* [burrow](./plugins/inputs/burrow)
* [cassandra](./plugins/inputs/cassandra) (deprecated, use [jolokia2](./plugins/inputs/jolokia2))

View File

@ -8,6 +8,7 @@ import (
_ "github.com/influxdata/telegraf/plugins/inputs/aurora"
_ "github.com/influxdata/telegraf/plugins/inputs/bcache"
_ "github.com/influxdata/telegraf/plugins/inputs/beanstalkd"
_ "github.com/influxdata/telegraf/plugins/inputs/bind"
_ "github.com/influxdata/telegraf/plugins/inputs/bond"
_ "github.com/influxdata/telegraf/plugins/inputs/burrow"
_ "github.com/influxdata/telegraf/plugins/inputs/cassandra"

View File

@ -0,0 +1,118 @@
# BIND 9 Nameserver Statistics Input Plugin
This plugin decodes the JSON or XML statistics provided by BIND 9 nameservers.
### XML Statistics Channel
Version 2 statistics (BIND 9.6 - 9.9) and version 3 statistics (BIND 9.9+) are supported. Note that
for BIND 9.9 to support version 3 statistics, it must be built with the `--enable-newstats` compile
flag, and it must be specifically requested via the correct URL. Version 3 statistics are the
default (and only) XML format in BIND 9.10+.
### JSON Statistics Channel
JSON statistics schema version 1 (BIND 9.10+) is supported. As of writing, some distros still do
not enable support for JSON statistics in their BIND packages.
### Configuration:
- **urls** []string: List of BIND statistics channel URLs to collect from. Do not include a
trailing slash in the URL. Default is "http://localhost:8053/xml/v3".
- **gather_memory_contexts** bool: Report per-context memory statistics.
- **gather_views** bool: Report per-view query statistics.
The following table summarizes the URL formats which should be used, depending on your BIND
version and configured statistics channel.
| BIND Version | Statistics Format | Example URL |
| ------------ | ----------------- | ----------------------------- |
| 9.6 - 9.8 | XML v2 | http://localhost:8053 |
| 9.9 | XML v2 | http://localhost:8053/xml/v2 |
| 9.9+ | XML v3 | http://localhost:8053/xml/v3 |
| 9.10+ | JSON v1 | http://localhost:8053/json/v1 |
#### Configuration of BIND Daemon
Add the following to your named.conf if running Telegraf on the same host as the BIND daemon:
```
statistics-channels {
inet 127.0.0.1 port 8053;
};
```
Alternatively, specify a wildcard address (e.g., 0.0.0.0) or specific IP address of an interface to
configure the BIND daemon to listen on that address. Note that you should secure the statistics
channel with an ACL if it is publicly reachable. Consult the BIND Administrator Reference Manual
for more information.
### Measurements & Fields:
- bind_counter
- name=value (multiple)
- bind_memory
- total_use
- in_use
- block_size
- context_size
- lost
- bind_memory_context
- total
- in_use
### Tags:
- All measurements
- url
- source
- port
- bind_counter
- type
- view (optional)
- bind_memory_context
- id
- name
### Sample Queries:
These are some useful queries (to generate dashboards or other) to run against data from this
plugin:
```
SELECT non_negative_derivative(mean(/^A$|^PTR$/), 5m) FROM bind_counter \
WHERE "url" = 'localhost:8053' AND "type" = 'qtype' AND time > now() - 1h \
GROUP BY time(5m), "type"
```
```
name: bind_counter
tags: type=qtype
time non_negative_derivative_A non_negative_derivative_PTR
---- ------------------------- ---------------------------
1553862000000000000 254.99444444430992 1388.311111111194
1553862300000000000 354 2135.716666666791
1553862600000000000 316.8666666666977 2130.133333333768
1553862900000000000 309.05000000004657 2126.75
1553863200000000000 315.64999999990687 2128.483333332464
1553863500000000000 308.9166666667443 2132.350000000559
1553863800000000000 302.64999999990687 2131.1833333335817
1553864100000000000 310.85000000009313 2132.449999999255
1553864400000000000 314.3666666666977 2136.216666666791
1553864700000000000 303.2333333331626 2133.8166666673496
1553865000000000000 304.93333333334886 2127.333333333023
1553865300000000000 317.93333333334886 2130.3166666664183
1553865600000000000 280.6666666667443 1807.9071428570896
```
### Example Output
Here is example output of this plugin:
```
bind_memory,host=LAP,port=8053,source=localhost,url=localhost:8053 block_size=12058624i,context_size=4575056i,in_use=4113717i,lost=0i,total_use=16663252i 1554276619000000000
bind_counter,host=LAP,port=8053,source=localhost,type=opcode,url=localhost:8053 IQUERY=0i,NOTIFY=0i,QUERY=9i,STATUS=0i,UPDATE=0i 1554276619000000000
bind_counter,host=LAP,port=8053,source=localhost,type=rcode,url=localhost:8053 17=0i,18=0i,19=0i,20=0i,21=0i,22=0i,BADCOOKIE=0i,BADVERS=0i,FORMERR=0i,NOERROR=7i,NOTAUTH=0i,NOTIMP=0i,NOTZONE=0i,NXDOMAIN=0i,NXRRSET=0i,REFUSED=0i,RESERVED11=0i,RESERVED12=0i,RESERVED13=0i,RESERVED14=0i,RESERVED15=0i,SERVFAIL=2i,YXDOMAIN=0i,YXRRSET=0i 1554276619000000000
bind_counter,host=LAP,port=8053,source=localhost,type=qtype,url=localhost:8053 A=1i,ANY=1i,NS=1i,PTR=5i,SOA=1i 1554276619000000000
bind_counter,host=LAP,port=8053,source=localhost,type=nsstat,url=localhost:8053 AuthQryRej=0i,CookieBadSize=0i,CookieBadTime=0i,CookieIn=9i,CookieMatch=0i,CookieNew=9i,CookieNoMatch=0i,DNS64=0i,ECSOpt=0i,ExpireOpt=0i,KeyTagOpt=0i,NSIDOpt=0i,OtherOpt=0i,QryAuthAns=7i,QryBADCOOKIE=0i,QryDropped=0i,QryDuplicate=0i,QryFORMERR=0i,QryFailure=0i,QryNXDOMAIN=0i,QryNXRedir=0i,QryNXRedirRLookup=0i,QryNoauthAns=0i,QryNxrrset=1i,QryRecursion=2i,QryReferral=0i,QrySERVFAIL=2i,QrySuccess=6i,QryTCP=1i,QryUDP=8i,RPZRewrites=0i,RateDropped=0i,RateSlipped=0i,RecQryRej=0i,RecursClients=0i,ReqBadEDNSVer=0i,ReqBadSIG=0i,ReqEdns0=9i,ReqSIG0=0i,ReqTCP=1i,ReqTSIG=0i,Requestv4=9i,Requestv6=0i,RespEDNS0=9i,RespSIG0=0i,RespTSIG=0i,Response=9i,TruncatedResp=0i,UpdateBadPrereq=0i,UpdateDone=0i,UpdateFail=0i,UpdateFwdFail=0i,UpdateRej=0i,UpdateReqFwd=0i,UpdateRespFwd=0i,XfrRej=0i,XfrReqDone=0i 1554276619000000000
bind_counter,host=LAP,port=8053,source=localhost,type=zonestat,url=localhost:8053 AXFRReqv4=0i,AXFRReqv6=0i,IXFRReqv4=0i,IXFRReqv6=0i,NotifyInv4=0i,NotifyInv6=0i,NotifyOutv4=0i,NotifyOutv6=0i,NotifyRej=0i,SOAOutv4=0i,SOAOutv6=0i,XfrFail=0i,XfrSuccess=0i 1554276619000000000
bind_counter,host=LAP,port=8053,source=localhost,type=sockstat,url=localhost:8053 FDWatchClose=0i,FDwatchConn=0i,FDwatchConnFail=0i,FDwatchRecvErr=0i,FDwatchSendErr=0i,FdwatchBindFail=0i,RawActive=1i,RawClose=0i,RawOpen=1i,RawOpenFail=0i,RawRecvErr=0i,TCP4Accept=6i,TCP4AcceptFail=0i,TCP4Active=9i,TCP4BindFail=0i,TCP4Close=5i,TCP4Conn=0i,TCP4ConnFail=0i,TCP4Open=8i,TCP4OpenFail=0i,TCP4RecvErr=0i,TCP4SendErr=0i,TCP6Accept=0i,TCP6AcceptFail=0i,TCP6Active=2i,TCP6BindFail=0i,TCP6Close=0i,TCP6Conn=0i,TCP6ConnFail=0i,TCP6Open=2i,TCP6OpenFail=0i,TCP6RecvErr=0i,TCP6SendErr=0i,UDP4Active=18i,UDP4BindFail=14i,UDP4Close=14i,UDP4Conn=0i,UDP4ConnFail=0i,UDP4Open=32i,UDP4OpenFail=0i,UDP4RecvErr=0i,UDP4SendErr=0i,UDP6Active=3i,UDP6BindFail=0i,UDP6Close=6i,UDP6Conn=0i,UDP6ConnFail=6i,UDP6Open=9i,UDP6OpenFail=0i,UDP6RecvErr=0i,UDP6SendErr=0i,UnixAccept=0i,UnixAcceptFail=0i,UnixActive=0i,UnixBindFail=0i,UnixClose=0i,UnixConn=0i,UnixConnFail=0i,UnixOpen=0i,UnixOpenFail=0i,UnixRecvErr=0i,UnixSendErr=0i 1554276619000000000
```

View File

@ -0,0 +1,87 @@
package bind
import (
"fmt"
"net/http"
"net/url"
"sync"
"time"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/plugins/inputs"
)
type Bind struct {
Urls []string
GatherMemoryContexts bool
GatherViews bool
}
var sampleConfig = `
## An array of BIND XML statistics URI to gather stats.
## Default is "http://localhost:8053/xml/v3".
# urls = ["http://localhost:8053/xml/v3"]
# gather_memory_contexts = false
# gather_views = false
`
var client = &http.Client{
Timeout: time.Duration(4 * time.Second),
}
func (b *Bind) Description() string {
return "Read BIND nameserver XML statistics"
}
func (b *Bind) SampleConfig() string {
return sampleConfig
}
func (b *Bind) Gather(acc telegraf.Accumulator) error {
var wg sync.WaitGroup
if len(b.Urls) == 0 {
b.Urls = []string{"http://localhost:8053/xml/v3"}
}
for _, u := range b.Urls {
addr, err := url.Parse(u)
if err != nil {
acc.AddError(fmt.Errorf("Unable to parse address '%s': %s", u, err))
continue
}
wg.Add(1)
go func(addr *url.URL) {
defer wg.Done()
acc.AddError(b.gatherUrl(addr, acc))
}(addr)
}
wg.Wait()
return nil
}
func (b *Bind) gatherUrl(addr *url.URL, acc telegraf.Accumulator) error {
switch addr.Path {
case "":
// BIND 9.6 - 9.8
return b.readStatsXMLv2(addr, acc)
case "/json/v1":
// BIND 9.10+
return b.readStatsJSON(addr, acc)
case "/xml/v2":
// BIND 9.9
return b.readStatsXMLv2(addr, acc)
case "/xml/v3":
// BIND 9.9+
return b.readStatsXMLv3(addr, acc)
default:
return fmt.Errorf("URL %s is ambiguous. Please check plugin documentation for supported URL formats.",
addr)
}
}
func init() {
inputs.Add("bind", func() telegraf.Input { return &Bind{} })
}

View File

@ -0,0 +1,581 @@
package bind
import (
"net"
"net/http"
"net/http/httptest"
"testing"
"github.com/influxdata/telegraf/testutil"
"github.com/stretchr/testify/assert"
)
func TestBindJsonStats(t *testing.T) {
ts := httptest.NewServer(http.FileServer(http.Dir("testdata")))
url := ts.Listener.Addr().String()
host, port, _ := net.SplitHostPort(url)
defer ts.Close()
b := Bind{
Urls: []string{ts.URL + "/json/v1"},
GatherMemoryContexts: true,
GatherViews: true,
}
var acc testutil.Accumulator
err := acc.GatherError(b.Gather)
assert.Nil(t, err)
// Use subtests for counters, since they are similar structure
type fieldSet struct {
fieldKey string
fieldValue int64
}
testCases := []struct {
counterType string
values []fieldSet
}{
{
"opcode",
[]fieldSet{
{"NOTIFY", 0},
{"UPDATE", 0},
{"IQUERY", 0},
{"QUERY", 13},
{"STATUS", 0},
},
},
{
"qtype",
[]fieldSet{
{"A", 2},
{"AAAA", 2},
{"PTR", 7},
{"SRV", 2},
},
},
{
"nsstat",
[]fieldSet{
{"QrySuccess", 6},
{"QryRecursion", 12},
{"Requestv4", 13},
{"QryNXDOMAIN", 4},
{"QryAuthAns", 1},
{"QryNxrrset", 1},
{"QryNoauthAns", 10},
{"QryUDP", 13},
{"QryDuplicate", 1},
{"QrySERVFAIL", 1},
{"Response", 12},
},
},
{
"sockstat",
[]fieldSet{
{"TCP4Open", 118},
{"UDP6Close", 112},
{"UDP4Close", 333},
{"TCP4Close", 119},
{"TCP6Active", 2},
{"UDP4Active", 2},
{"UDP4RecvErr", 1},
{"UDP4Open", 335},
{"TCP4Active", 10},
{"RawActive", 1},
{"UDP6ConnFail", 112},
{"TCP4Conn", 114},
{"UDP6Active", 1},
{"UDP6Open", 113},
{"UDP4Conn", 333},
{"UDP6SendErr", 112},
{"RawOpen", 1},
{"TCP4Accept", 6},
{"TCP6Open", 2},
},
},
}
for _, tc := range testCases {
t.Run(tc.counterType, func(t *testing.T) {
tags := map[string]string{
"url": url,
"type": tc.counterType,
"source": host,
"port": port,
}
fields := map[string]interface{}{}
for _, val := range tc.values {
fields[val.fieldKey] = val.fieldValue
}
acc.AssertContainsTaggedFields(t, "bind_counter", fields, tags)
})
}
// Subtest for memory stats
t.Run("memory", func(t *testing.T) {
tags := map[string]string{
"url": url,
"source": host,
"port": port,
}
fields := map[string]interface{}{
"block_size": 13893632,
"context_size": 3685480,
"in_use": 3064368,
"lost": 0,
"total_use": 18206566,
}
acc.AssertContainsTaggedFields(t, "bind_memory", fields, tags)
})
// Subtest for per-context memory stats
t.Run("memory_context", func(t *testing.T) {
assert.True(t, acc.HasIntField("bind_memory_context", "total"))
assert.True(t, acc.HasIntField("bind_memory_context", "in_use"))
})
}
func TestBindXmlStatsV2(t *testing.T) {
ts := httptest.NewServer(http.FileServer(http.Dir("testdata")))
url := ts.Listener.Addr().String()
host, port, _ := net.SplitHostPort(url)
defer ts.Close()
b := Bind{
Urls: []string{ts.URL + "/xml/v2"},
GatherMemoryContexts: true,
GatherViews: true,
}
var acc testutil.Accumulator
err := acc.GatherError(b.Gather)
assert.Nil(t, err)
// Use subtests for counters, since they are similar structure
type fieldSet struct {
fieldKey string
fieldValue int64
}
testCases := []struct {
counterType string
values []fieldSet
}{
{
"opcode",
[]fieldSet{
{"UPDATE", 238},
{"QUERY", 102312374},
},
},
{
"qtype",
[]fieldSet{
{"ANY", 7},
{"DNSKEY", 452},
{"SSHFP", 2987},
{"SOA", 100415},
{"AAAA", 37786321},
{"MX", 441155},
{"IXFR", 157},
{"CNAME", 531},
{"NS", 1999},
{"TXT", 34628},
{"A", 58951432},
{"SRV", 741082},
{"PTR", 4211487},
{"NAPTR", 39137},
{"DS", 584},
},
},
{
"nsstat",
[]fieldSet{
{"XfrReqDone", 157},
{"ReqEdns0", 441758},
{"ReqTSIG", 0},
{"UpdateRespFwd", 0},
{"RespEDNS0", 441748},
{"QryDropped", 16},
{"RPZRewrites", 0},
{"XfrRej", 0},
{"RecQryRej", 0},
{"QryNxrrset", 24423133},
{"QryFORMERR", 0},
{"ReqTCP", 1548156},
{"UpdateDone", 0},
{"QrySERVFAIL", 14422},
{"QryRecursion", 2104239},
{"Requestv4", 102312611},
{"UpdateFwdFail", 0},
{"QryReferral", 3},
{"Response", 102301560},
{"RespTSIG", 0},
{"QrySuccess", 63811668},
{"QryFailure", 0},
{"RespSIG0", 0},
{"ReqSIG0", 0},
{"UpdateRej", 238},
{"QryAuthAns", 72180718},
{"UpdateFail", 0},
{"QryDuplicate", 10879},
{"RateDropped", 0},
{"QryNoauthAns", 30106182},
{"QryNXDOMAIN", 14052096},
{"ReqBadSIG", 0},
{"UpdateReqFwd", 0},
{"RateSlipped", 0},
{"TruncatedResp", 3787},
{"Requestv6", 1},
{"UpdateBadPrereq", 0},
{"AuthQryRej", 0},
{"ReqBadEDNSVer", 0},
},
},
{
"sockstat",
[]fieldSet{
{"FdwatchBindFail", 0},
{"UDP6Open", 238269},
{"UDP6SendErr", 238250},
{"TCP4ConnFail", 0},
{"TCP4Conn", 590},
{"TCP6AcceptFail", 0},
{"UDP4SendErr", 0},
{"FDwatchConn", 0},
{"TCP4RecvErr", 1},
{"TCP4OpenFail", 0},
{"UDP4OpenFail", 0},
{"UDP6OpenFail", 0},
{"TCP4Close", 1548268},
{"TCP6BindFail", 0},
{"TCP4AcceptFail", 0},
{"UnixConn", 0},
{"UDP4Open", 3765532},
{"TCP6Close", 0},
{"FDwatchRecvErr", 0},
{"UDP4Conn", 3764828},
{"UnixConnFail", 0},
{"TCP6Conn", 0},
{"TCP6OpenFail", 0},
{"TCP6SendErr", 0},
{"TCP6RecvErr", 0},
{"FDwatchSendErr", 0},
{"UDP4RecvErr", 1650},
{"UDP4ConnFail", 0},
{"UDP6Close", 238267},
{"FDWatchClose", 0},
{"TCP4Accept", 1547672},
{"UnixAccept", 0},
{"TCP4Open", 602},
{"UDP4BindFail", 219},
{"UDP6ConnFail", 238250},
{"UnixClose", 0},
{"TCP4BindFail", 0},
{"UnixOpenFail", 0},
{"UDP6BindFail", 16},
{"UnixOpen", 0},
{"UnixAcceptFail", 0},
{"UnixRecvErr", 0},
{"UDP6RecvErr", 0},
{"TCP6ConnFail", 0},
{"FDwatchConnFail", 0},
{"TCP4SendErr", 0},
{"UDP4Close", 3765528},
{"UnixSendErr", 0},
{"TCP6Open", 2},
{"UDP6Conn", 1},
{"TCP6Accept", 0},
{"UnixBindFail", 0},
},
},
}
for _, tc := range testCases {
t.Run(tc.counterType, func(t *testing.T) {
tags := map[string]string{
"url": url,
"type": tc.counterType,
"source": host,
"port": port,
}
fields := map[string]interface{}{}
for _, val := range tc.values {
fields[val.fieldKey] = val.fieldValue
}
acc.AssertContainsTaggedFields(t, "bind_counter", fields, tags)
})
}
// Subtest for memory stats
t.Run("memory", func(t *testing.T) {
tags := map[string]string{
"url": url,
"source": host,
"port": port,
}
fields := map[string]interface{}{
"block_size": 77070336,
"context_size": 6663840,
"in_use": 20772579,
"lost": 0,
"total_use": 81804609,
}
acc.AssertContainsTaggedFields(t, "bind_memory", fields, tags)
})
// Subtest for per-context memory stats
t.Run("memory_context", func(t *testing.T) {
assert.True(t, acc.HasIntField("bind_memory_context", "total"))
assert.True(t, acc.HasIntField("bind_memory_context", "in_use"))
})
}
func TestBindXmlStatsV3(t *testing.T) {
ts := httptest.NewServer(http.FileServer(http.Dir("testdata")))
url := ts.Listener.Addr().String()
host, port, _ := net.SplitHostPort(url)
defer ts.Close()
b := Bind{
Urls: []string{ts.URL + "/xml/v3"},
GatherMemoryContexts: true,
GatherViews: true,
}
var acc testutil.Accumulator
err := acc.GatherError(b.Gather)
assert.Nil(t, err)
// Use subtests for counters, since they are similar structure
type fieldSet struct {
fieldKey string
fieldValue int64
}
testCases := []struct {
counterType string
values []fieldSet
}{
{
"opcode",
[]fieldSet{
{"NOTIFY", 0},
{"UPDATE", 0},
{"IQUERY", 0},
{"QUERY", 74941},
{"STATUS", 0},
},
},
{
"qtype",
[]fieldSet{
{"ANY", 22},
{"SOA", 18},
{"AAAA", 5735},
{"MX", 618},
{"NS", 373},
{"TXT", 970},
{"A", 63672},
{"SRV", 139},
{"PTR", 3393},
{"RRSIG", 1},
},
},
{
"nsstat",
[]fieldSet{
{"DNS64", 0},
{"ExpireOpt", 0},
{"NSIDOpt", 0},
{"OtherOpt", 59},
{"XfrReqDone", 0},
{"ReqEdns0", 9250},
{"ReqTSIG", 0},
{"UpdateRespFwd", 0},
{"RespEDNS0", 9250},
{"QryDropped", 11},
{"RPZRewrites", 0},
{"XfrRej", 0},
{"RecQryRej", 35},
{"QryNxrrset", 2452},
{"QryFORMERR", 0},
{"ReqTCP", 260},
{"QryTCP", 258},
{"QryUDP", 74648},
{"UpdateDone", 0},
{"QrySERVFAIL", 122},
{"QryRecursion", 53750},
{"RecursClients", 0},
{"Requestv4", 74942},
{"UpdateFwdFail", 0},
{"QryReferral", 0},
{"Response", 63264},
{"RespTSIG", 0},
{"QrySuccess", 49044},
{"QryFailure", 35},
{"RespSIG0", 0},
{"ReqSIG0", 0},
{"UpdateRej", 0},
{"QryAuthAns", 2752},
{"UpdateFail", 0},
{"QryDuplicate", 11667},
{"RateDropped", 0},
{"QryNoauthAns", 60354},
{"QryNXDOMAIN", 11610},
{"ReqBadSIG", 0},
{"UpdateReqFwd", 0},
{"RateSlipped", 0},
{"TruncatedResp", 365},
{"Requestv6", 0},
{"UpdateBadPrereq", 0},
{"AuthQryRej", 0},
{"ReqBadEDNSVer", 0},
{"SitBadSize", 0},
{"SitBadTime", 0},
{"SitMatch", 0},
{"SitNew", 0},
{"SitNoMatch", 0},
{"SitOpt", 0},
{"TruncatedResp", 365},
},
},
{
"sockstat",
[]fieldSet{
{"FDwatchConnFail", 0},
{"UnixClose", 0},
{"TCP6OpenFail", 0},
{"TCP6Active", 0},
{"UDP4RecvErr", 14},
{"TCP6Conn", 0},
{"FDWatchClose", 0},
{"TCP4ConnFail", 0},
{"UnixConn", 0},
{"UnixSendErr", 0},
{"UDP6Close", 0},
{"UnixOpen", 0},
{"UDP4Conn", 92535},
{"TCP4Close", 336},
{"UnixAcceptFail", 0},
{"UnixAccept", 0},
{"TCP6AcceptFail", 0},
{"UDP6Open", 0},
{"UDP6BindFail", 0},
{"UDP6RecvErr", 0},
{"RawOpenFail", 0},
{"TCP4Accept", 293},
{"UDP6SendErr", 0},
{"UDP6Conn", 0},
{"TCP4SendErr", 0},
{"UDP4BindFail", 1},
{"UDP4Active", 4},
{"TCP4Active", 297},
{"UnixConnFail", 0},
{"UnixOpenFail", 0},
{"UDP6ConnFail", 0},
{"TCP6Accept", 0},
{"UnixRecvErr", 0},
{"RawActive", 1},
{"UDP6OpenFail", 0},
{"RawClose", 0},
{"UnixBindFail", 0},
{"UnixActive", 0},
{"FdwatchBindFail", 0},
{"UDP4SendErr", 0},
{"RawRecvErr", 0},
{"TCP6Close", 0},
{"FDwatchRecvErr", 0},
{"TCP4BindFail", 0},
{"TCP4AcceptFail", 0},
{"TCP4OpenFail", 0},
{"UDP4Open", 92542},
{"UDP4ConnFail", 0},
{"TCP4Conn", 44},
{"TCP6ConnFail", 0},
{"FDwatchConn", 0},
{"UDP6Active", 0},
{"RawOpen", 1},
{"TCP6BindFail", 0},
{"UDP4Close", 92538},
{"TCP6Open", 0},
{"TCP6SendErr", 0},
{"TCP4Open", 48},
{"FDwatchSendErr", 0},
{"TCP6RecvErr", 0},
{"UDP4OpenFail", 0},
{"TCP4RecvErr", 0},
},
},
}
for _, tc := range testCases {
t.Run(tc.counterType, func(t *testing.T) {
tags := map[string]string{
"url": url,
"type": tc.counterType,
"source": host,
"port": port,
}
fields := map[string]interface{}{}
for _, val := range tc.values {
fields[val.fieldKey] = val.fieldValue
}
acc.AssertContainsTaggedFields(t, "bind_counter", fields, tags)
})
}
// Subtest for memory stats
t.Run("memory", func(t *testing.T) {
tags := map[string]string{
"url": url,
"source": host,
"port": port,
}
fields := map[string]interface{}{
"block_size": 45875200,
"context_size": 10037400,
"in_use": 6000232,
"lost": 0,
"total_use": 777821909,
}
acc.AssertContainsTaggedFields(t, "bind_memory", fields, tags)
})
// Subtest for per-context memory stats
t.Run("memory_context", func(t *testing.T) {
assert.True(t, acc.HasIntField("bind_memory_context", "total"))
assert.True(t, acc.HasIntField("bind_memory_context", "in_use"))
})
}
func TestBindUnparseableURL(t *testing.T) {
b := Bind{
Urls: []string{"://example.com"},
}
var acc testutil.Accumulator
err := acc.GatherError(b.Gather)
assert.Contains(t, err.Error(), "Unable to parse address")
}

View File

@ -0,0 +1,166 @@
package bind
import (
"encoding/json"
"fmt"
"net"
"net/http"
"net/url"
"strings"
"time"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/metric"
)
type jsonStats struct {
OpCodes map[string]int
QTypes map[string]int
NSStats map[string]int
SockStats map[string]int
Views map[string]jsonView
Memory jsonMemory
}
type jsonMemory struct {
TotalUse int
InUse int
BlockSize int
ContextSize int
Lost int
Contexts []struct {
Id string
Name string
Total int
InUse int
}
}
type jsonView struct {
Resolver map[string]map[string]int
}
// addJSONCounter adds a counter array to a Telegraf Accumulator, with the specified tags.
func addJSONCounter(acc telegraf.Accumulator, commonTags map[string]string, stats map[string]int) {
grouper := metric.NewSeriesGrouper()
ts := time.Now()
for name, value := range stats {
if commonTags["type"] == "opcode" && strings.HasPrefix(name, "RESERVED") {
continue
}
tags := make(map[string]string)
// Create local copy of tags since maps are reference types
for k, v := range commonTags {
tags[k] = v
}
grouper.Add("bind_counter", tags, ts, name, value)
}
//Add grouped metrics
for _, metric := range grouper.Metrics() {
acc.AddMetric(metric)
}
}
// addStatsJson walks a jsonStats struct and adds the values to the telegraf.Accumulator.
func (b *Bind) addStatsJSON(stats jsonStats, acc telegraf.Accumulator, urlTag string) {
grouper := metric.NewSeriesGrouper()
ts := time.Now()
tags := map[string]string{"url": urlTag}
host, port, _ := net.SplitHostPort(urlTag)
tags["source"] = host
tags["port"] = port
// Opcodes
tags["type"] = "opcode"
addJSONCounter(acc, tags, stats.OpCodes)
// Query RDATA types
tags["type"] = "qtype"
addJSONCounter(acc, tags, stats.QTypes)
// Nameserver stats
tags["type"] = "nsstat"
addJSONCounter(acc, tags, stats.NSStats)
// Socket statistics
tags["type"] = "sockstat"
addJSONCounter(acc, tags, stats.SockStats)
// Memory stats
fields := map[string]interface{}{
"total_use": stats.Memory.TotalUse,
"in_use": stats.Memory.InUse,
"block_size": stats.Memory.BlockSize,
"context_size": stats.Memory.ContextSize,
"lost": stats.Memory.Lost,
}
acc.AddGauge("bind_memory", fields, map[string]string{"url": urlTag, "source": host, "port": port})
// Detailed, per-context memory stats
if b.GatherMemoryContexts {
for _, c := range stats.Memory.Contexts {
tags := map[string]string{"url": urlTag, "id": c.Id, "name": c.Name, "source": host, "port": port}
fields := map[string]interface{}{"total": c.Total, "in_use": c.InUse}
acc.AddGauge("bind_memory_context", fields, tags)
}
}
// Detailed, per-view stats
if b.GatherViews {
for vName, view := range stats.Views {
for cntrType, counters := range view.Resolver {
for cntrName, value := range counters {
tags := map[string]string{
"url": urlTag,
"source": host,
"port": port,
"view": vName,
"type": cntrType,
}
grouper.Add("bind_counter", tags, ts, cntrName, value)
}
}
}
}
//Add grouped metrics
for _, metric := range grouper.Metrics() {
acc.AddMetric(metric)
}
}
// readStatsJSON takes a base URL to probe, and requests the individual statistics blobs that we
// are interested in. These individual blobs have a combined size which is significantly smaller
// than if we requested everything at once (e.g. taskmgr and socketmgr can be omitted).
func (b *Bind) readStatsJSON(addr *url.URL, acc telegraf.Accumulator) error {
var stats jsonStats
// Progressively build up full jsonStats struct by parsing the individual HTTP responses
for _, suffix := range [...]string{"/server", "/net", "/mem"} {
scrapeUrl := addr.String() + suffix
resp, err := client.Get(scrapeUrl)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("%s returned HTTP status: %s", scrapeUrl, resp.Status)
}
if err := json.NewDecoder(resp.Body).Decode(&stats); err != nil {
return fmt.Errorf("Unable to decode JSON blob: %s", err)
}
}
b.addStatsJSON(stats, acc, addr.Host)
return nil
}

133
plugins/inputs/bind/testdata/json/v1/mem vendored Normal file
View File

@ -0,0 +1,133 @@
{
"json-stats-version":"1.2",
"boot-time":"2017-07-28T13:24:53Z",
"config-time":"2017-07-28T13:24:53Z",
"current-time":"2017-07-28T15:33:07Z",
"memory":{
"TotalUse":18206566,
"InUse":3064368,
"BlockSize":13893632,
"ContextSize":3685480,
"Lost":0,
"contexts":[
{
"id":"0x55fb2e042de0",
"name":"main",
"references":202,
"total":2693003,
"inuse":1454904,
"maxinuse":1508072,
"blocksize":786432,
"pools":40,
"hiwater":0,
"lowater":0
},
{
"id":"0x55fb2e0507e0",
"name":"dst",
"references":1,
"total":387478,
"inuse":91776,
"maxinuse":97208,
"pools":0,
"hiwater":0,
"lowater":0
},
{
"id":"0x55fb2e0938e0",
"name":"zonemgr-pool",
"references":113,
"total":742986,
"inuse":143776,
"maxinuse":313961,
"blocksize":262144,
"pools":0,
"hiwater":0,
"lowater":0
},
{
"id":"0x7f19d00017d0",
"name":"threadkey",
"references":1,
"total":0,
"inuse":0,
"maxinuse":0,
"pools":0,
"hiwater":0,
"lowater":0
},
{
"id":"0x7f19d00475f0",
"name":"client",
"references":3,
"total":267800,
"inuse":8760,
"maxinuse":8760,
"blocksize":262144,
"pools":2,
"hiwater":0,
"lowater":0
},
{
"id":"0x7f19d00dfca0",
"name":"cache",
"references":8,
"total":288938,
"inuse":83650,
"maxinuse":83842,
"blocksize":262144,
"pools":0,
"hiwater":0,
"lowater":0
},
{
"id":"0x7f19d00eaa30",
"name":"cache_heap",
"references":18,
"total":393216,
"inuse":132096,
"maxinuse":132096,
"blocksize":262144,
"pools":0,
"hiwater":0,
"lowater":0
},
{
"id":"0x7f19d01094e0",
"name":"res0",
"references":1,
"total":262144,
"inuse":0,
"maxinuse":22048,
"blocksize":262144,
"pools":0,
"hiwater":0,
"lowater":0
},
{
"id":"0x7f19d0114270",
"name":"res1",
"references":1,
"total":0,
"inuse":0,
"maxinuse":0,
"blocksize":0,
"pools":0,
"hiwater":0,
"lowater":0
},
{
"id":"0x7f19d011f000",
"name":"res2",
"references":1,
"total":0,
"inuse":0,
"maxinuse":0,
"blocksize":0,
"pools":0,
"hiwater":0,
"lowater":0
}
]
}
}

241
plugins/inputs/bind/testdata/json/v1/net vendored Normal file
View File

@ -0,0 +1,241 @@
{
"json-stats-version":"1.2",
"boot-time":"2017-07-28T13:24:53Z",
"config-time":"2017-07-28T13:24:53Z",
"current-time":"2017-07-28T15:33:07Z",
"sockstats":{
"UDP4Open":335,
"UDP6Open":113,
"TCP4Open":118,
"TCP6Open":2,
"RawOpen":1,
"UDP4Close":333,
"UDP6Close":112,
"TCP4Close":119,
"UDP6ConnFail":112,
"UDP4Conn":333,
"TCP4Conn":114,
"TCP4Accept":6,
"UDP6SendErr":112,
"UDP4RecvErr":1,
"UDP4Active":2,
"UDP6Active":1,
"TCP4Active":10,
"TCP6Active":2,
"RawActive":1
},
"socketmgr":{
"sockets":[
{
"id":"0x7f19dd849010",
"references":1,
"type":"not-initialized",
"local-address":"<unknown address, family 16>",
"states":[
"bound"
]
},
{
"id":"0x7f19dd849268",
"references":1,
"type":"tcp",
"local-address":"0.0.0.0#8053",
"states":[
"listener",
"bound"
]
},
{
"id":"0x7f19dd849718",
"references":2,
"type":"udp",
"local-address":"::#53",
"states":[
"bound"
]
},
{
"id":"0x7f19dd849970",
"references":2,
"type":"tcp",
"local-address":"::#53",
"states":[
"listener",
"bound"
]
},
{
"id":"0x7f19dd849bc8",
"references":2,
"type":"udp",
"local-address":"127.0.0.1#53",
"states":[
"bound"
]
},
{
"id":"0x7f19dd6f4010",
"references":2,
"type":"tcp",
"local-address":"127.0.0.1#53",
"states":[
"listener",
"bound"
]
},
{
"id":"0x7f19dd6f4718",
"references":1,
"type":"tcp",
"local-address":"127.0.0.1#953",
"states":[
"listener",
"bound"
]
},
{
"id":"0x7f19dd6f4bc8",
"references":1,
"type":"tcp",
"local-address":"::1#953",
"states":[
"listener",
"bound"
]
},
{
"id":"0x7f19d4fb7970",
"references":1,
"type":"udp",
"states":[
]
},
{
"id":"0x7f19d4fb7bc8",
"references":1,
"type":"udp",
"states":[
]
},
{
"id":"0x7f19d4fc7010",
"references":1,
"type":"udp",
"states":[
]
},
{
"id":"0x7f19d4fc74c0",
"references":1,
"type":"udp",
"states":[
]
},
{
"id":"0x7f19d4fc7718",
"references":1,
"type":"udp",
"states":[
]
},
{
"id":"0x7f19d4fc7bc8",
"references":1,
"type":"udp",
"states":[
]
},
{
"id":"0x7f19d4fd1010",
"references":1,
"type":"udp",
"states":[
]
},
{
"id":"0x7f19d4fd1268",
"references":1,
"type":"udp",
"states":[
]
},
{
"id":"0x7f19d4fd14c0",
"references":1,
"type":"udp",
"states":[
]
},
{
"id":"0x7f19d4fd1718",
"references":1,
"type":"udp",
"states":[
]
},
{
"id":"0x7f19d4fd1970",
"references":1,
"type":"udp",
"states":[
]
},
{
"id":"0x7f19d4fd1bc8",
"references":1,
"type":"udp",
"states":[
]
},
{
"id":"0x7f19d4fd9010",
"references":1,
"type":"udp",
"states":[
]
},
{
"id":"0x7f19d4fda4c0",
"references":1,
"type":"udp",
"states":[
]
},
{
"id":"0x7f19d4fd9bc8",
"references":1,
"type":"udp",
"states":[
]
},
{
"id":"0x7f19d4fda268",
"references":1,
"type":"udp",
"states":[
]
},
{
"id":"0x7f19d4fd9970",
"references":1,
"type":"udp",
"states":[
]
},
{
"id":"0x7f19d4fda010",
"references":1,
"type":"udp",
"states":[
]
},
{
"id":"0x7f19d4fd9718",
"references":1,
"type":"udp",
"states":[
]
}
]
}
}

View File

@ -0,0 +1,141 @@
{
"json-stats-version":"1.2",
"boot-time":"2017-07-28T13:24:53Z",
"config-time":"2017-07-28T13:24:53Z",
"current-time":"2017-07-28T15:33:07Z",
"opcodes":{
"QUERY":13,
"IQUERY":0,
"STATUS":0,
"RESERVED3":0,
"NOTIFY":0,
"UPDATE":0,
"RESERVED6":0,
"RESERVED7":0,
"RESERVED8":0,
"RESERVED9":0,
"RESERVED10":0,
"RESERVED11":0,
"RESERVED12":0,
"RESERVED13":0,
"RESERVED14":0,
"RESERVED15":0
},
"qtypes":{
"A":2,
"PTR":7,
"AAAA":2,
"SRV":2
},
"nsstats":{
"Requestv4":13,
"Response":12,
"QrySuccess":6,
"QryAuthAns":1,
"QryNoauthAns":10,
"QryNxrrset":1,
"QrySERVFAIL":1,
"QryNXDOMAIN":4,
"QryRecursion":12,
"QryDuplicate":1,
"QryUDP":13
},
"views":{
"_default":{
"resolver":{
"stats":{
"Queryv4":447,
"Queryv6":112,
"Responsev4":444,
"NXDOMAIN":3,
"Truncated":114,
"Retry":242,
"QueryTimeout":3,
"GlueFetchv4":61,
"GlueFetchv6":68,
"GlueFetchv6Fail":24,
"ValAttempt":36,
"ValOk":27,
"ValNegOk":9,
"QryRTT100":287,
"QryRTT500":152,
"QryRTT800":4,
"BucketSize":31
},
"qtypes":{
"A":220,
"NS":19,
"PTR":22,
"AAAA":233,
"SRV":14,
"DS":27,
"DNSKEY":24
},
"cache":{
"A":150,
"NS":44,
"PTR":3,
"AAAA":104,
"DS":23,
"RRSIG":94,
"NSEC":8,
"DNSKEY":7,
"!AAAA":23,
"!DS":5,
"NXDOMAIN":1
},
"cachestats":{
"CacheHits":1675,
"CacheMisses":44,
"QueryHits":17,
"QueryMisses":12,
"DeleteLRU":0,
"DeleteTTL":16,
"CacheNodes":219,
"CacheBuckets":129,
"TreeMemTotal":551082,
"TreeMemInUse":150704,
"HeapMemMax":132096,
"HeapMemTotal":393216,
"HeapMemInUse":132096
},
"adb":{
"nentries":1021,
"entriescnt":254,
"nnames":1021,
"namescnt":195
}
}
},
"_bind":{
"resolver":{
"stats":{
"BucketSize":31
},
"qtypes":{
},
"cache":{
},
"cachestats":{
"CacheHits":0,
"CacheMisses":0,
"QueryHits":0,
"QueryMisses":0,
"DeleteLRU":0,
"DeleteTTL":0,
"CacheNodes":0,
"CacheBuckets":64,
"TreeMemTotal":287392,
"TreeMemInUse":29608,
"HeapMemMax":1024,
"HeapMemTotal":262144,
"HeapMemInUse":1024
},
"adb":{
"nentries":1021,
"nnames":1021
}
}
}
}
}

926
plugins/inputs/bind/testdata/xml/v2 vendored Normal file
View File

@ -0,0 +1,926 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/bind9.xsl"?>
<isc version="1.0">
<bind>
<statistics version="2.2">
<views>
<view>
<name>_default</name>
<rdtype>
<name>A</name>
<counter>2936881</counter>
</rdtype>
<rdtype>
<name>NS</name>
<counter>28994</counter>
</rdtype>
<rdtype>
<name>CNAME</name>
<counter>26</counter>
</rdtype>
<rdtype>
<name>SOA</name>
<counter>15131</counter>
</rdtype>
<rdtype>
<name>PTR</name>
<counter>47924</counter>
</rdtype>
<rdtype>
<name>MX</name>
<counter>1884</counter>
</rdtype>
<rdtype>
<name>TXT</name>
<counter>6486</counter>
</rdtype>
<rdtype>
<name>AAAA</name>
<counter>949781</counter>
</rdtype>
<rdtype>
<name>SRV</name>
<counter>14740</counter>
</rdtype>
<rdtype>
<name>NAPTR</name>
<counter>1606</counter>
</rdtype>
<rdtype>
<name>DS</name>
<counter>25</counter>
</rdtype>
<rdtype>
<name>SSHFP</name>
<counter>185</counter>
</rdtype>
<rdtype>
<name>DNSKEY</name>
<counter>13</counter>
</rdtype>
<rdtype>
<name>ANY</name>
<counter>1</counter>
</rdtype>
<resstat>
<name>Queryv4</name>
<counter>3765426</counter>
</resstat>
<resstat>
<name>Queryv6</name>
<counter>238251</counter>
</resstat>
<resstat>
<name>Responsev4</name>
<counter>3716142</counter>
</resstat>
<resstat>
<name>Responsev6</name>
<counter>1</counter>
</resstat>
<resstat>
<name>NXDOMAIN</name>
<counter>100052</counter>
</resstat>
<resstat>
<name>SERVFAIL</name>
<counter>5894</counter>
</resstat>
<resstat>
<name>FORMERR</name>
<counter>2041</counter>
</resstat>
<resstat>
<name>OtherError</name>
<counter>14801</counter>
</resstat>
<resstat>
<name>EDNS0Fail</name>
<counter>2615</counter>
</resstat>
<resstat>
<name>Mismatch</name>
<counter>0</counter>
</resstat>
<resstat>
<name>Truncated</name>
<counter>598</counter>
</resstat>
<resstat>
<name>Lame</name>
<counter>117</counter>
</resstat>
<resstat>
<name>Retry</name>
<counter>383343</counter>
</resstat>
<resstat>
<name>QueryAbort</name>
<counter>0</counter>
</resstat>
<resstat>
<name>QuerySockFail</name>
<counter>0</counter>
</resstat>
<resstat>
<name>QueryTimeout</name>
<counter>50874</counter>
</resstat>
<resstat>
<name>GlueFetchv4</name>
<counter>260749</counter>
</resstat>
<resstat>
<name>GlueFetchv6</name>
<counter>225310</counter>
</resstat>
<resstat>
<name>GlueFetchv4Fail</name>
<counter>5756</counter>
</resstat>
<resstat>
<name>GlueFetchv6Fail</name>
<counter>141500</counter>
</resstat>
<resstat>
<name>ValAttempt</name>
<counter>0</counter>
</resstat>
<resstat>
<name>ValOk</name>
<counter>0</counter>
</resstat>
<resstat>
<name>ValNegOk</name>
<counter>0</counter>
</resstat>
<resstat>
<name>ValFail</name>
<counter>0</counter>
</resstat>
<resstat>
<name>QryRTT10</name>
<counter>458176</counter>
</resstat>
<resstat>
<name>QryRTT100</name>
<counter>3010133</counter>
</resstat>
<resstat>
<name>QryRTT500</name>
<counter>244312</counter>
</resstat>
<resstat>
<name>QryRTT800</name>
<counter>1275</counter>
</resstat>
<resstat>
<name>QryRTT1600</name>
<counter>361</counter>
</resstat>
<resstat>
<name>QryRTT1600+</name>
<counter>236</counter>
</resstat>
<cache name="_default">
<rrset>
<name>A</name>
<counter>2700</counter>
</rrset>
<rrset>
<name>NS</name>
<counter>759</counter>
</rrset>
<rrset>
<name>CNAME</name>
<counter>486</counter>
</rrset>
<rrset>
<name>SOA</name>
<counter>2</counter>
</rrset>
<rrset>
<name>PTR</name>
<counter>6</counter>
</rrset>
<rrset>
<name>TXT</name>
<counter>2</counter>
</rrset>
<rrset>
<name>AAAA</name>
<counter>629</counter>
</rrset>
<rrset>
<name>SRV</name>
<counter>1</counter>
</rrset>
<rrset>
<name>DS</name>
<counter>48</counter>
</rrset>
<rrset>
<name>RRSIG</name>
<counter>203</counter>
</rrset>
<rrset>
<name>NSEC</name>
<counter>22</counter>
</rrset>
<rrset>
<name>DNSKEY</name>
<counter>1</counter>
</rrset>
<rrset>
<name>!A</name>
<counter>6</counter>
</rrset>
<rrset>
<name>!SOA</name>
<counter>26</counter>
</rrset>
<rrset>
<name>!AAAA</name>
<counter>84</counter>
</rrset>
<rrset>
<name>!NAPTR</name>
<counter>3</counter>
</rrset>
<rrset>
<name>NXDOMAIN</name>
<counter>143</counter>
</rrset>
</cache>
</view>
<view>
<name>_bind</name>
<resstat>
<name>Queryv4</name>
<counter>0</counter>
</resstat>
<resstat>
<name>Queryv6</name>
<counter>0</counter>
</resstat>
<resstat>
<name>Responsev4</name>
<counter>0</counter>
</resstat>
<resstat>
<name>Responsev6</name>
<counter>0</counter>
</resstat>
<resstat>
<name>NXDOMAIN</name>
<counter>0</counter>
</resstat>
<resstat>
<name>SERVFAIL</name>
<counter>0</counter>
</resstat>
<resstat>
<name>FORMERR</name>
<counter>0</counter>
</resstat>
<resstat>
<name>OtherError</name>
<counter>0</counter>
</resstat>
<resstat>
<name>EDNS0Fail</name>
<counter>0</counter>
</resstat>
<resstat>
<name>Mismatch</name>
<counter>0</counter>
</resstat>
<resstat>
<name>Truncated</name>
<counter>0</counter>
</resstat>
<resstat>
<name>Lame</name>
<counter>0</counter>
</resstat>
<resstat>
<name>Retry</name>
<counter>0</counter>
</resstat>
<resstat>
<name>QueryAbort</name>
<counter>0</counter>
</resstat>
<resstat>
<name>QuerySockFail</name>
<counter>0</counter>
</resstat>
<resstat>
<name>QueryTimeout</name>
<counter>0</counter>
</resstat>
<resstat>
<name>GlueFetchv4</name>
<counter>0</counter>
</resstat>
<resstat>
<name>GlueFetchv6</name>
<counter>0</counter>
</resstat>
<resstat>
<name>GlueFetchv4Fail</name>
<counter>0</counter>
</resstat>
<resstat>
<name>GlueFetchv6Fail</name>
<counter>0</counter>
</resstat>
<resstat>
<name>ValAttempt</name>
<counter>0</counter>
</resstat>
<resstat>
<name>ValOk</name>
<counter>0</counter>
</resstat>
<resstat>
<name>ValNegOk</name>
<counter>0</counter>
</resstat>
<resstat>
<name>ValFail</name>
<counter>0</counter>
</resstat>
<resstat>
<name>QryRTT10</name>
<counter>0</counter>
</resstat>
<resstat>
<name>QryRTT100</name>
<counter>0</counter>
</resstat>
<resstat>
<name>QryRTT500</name>
<counter>0</counter>
</resstat>
<resstat>
<name>QryRTT800</name>
<counter>0</counter>
</resstat>
<resstat>
<name>QryRTT1600</name>
<counter>0</counter>
</resstat>
<resstat>
<name>QryRTT1600+</name>
<counter>0</counter>
</resstat>
<cache name="_bind"/>
</view>
</views>
<server>
<boot-time>2016-10-02T18:45:00Z</boot-time>
<current-time>2016-10-23T19:27:48Z</current-time>
<requests>
<opcode>
<name>QUERY</name>
<counter>102312374</counter>
</opcode>
<opcode>
<name>UPDATE</name>
<counter>238</counter>
</opcode>
</requests>
<queries-in>
<rdtype>
<name>A</name>
<counter>58951432</counter>
</rdtype>
<rdtype>
<name>NS</name>
<counter>1999</counter>
</rdtype>
<rdtype>
<name>CNAME</name>
<counter>531</counter>
</rdtype>
<rdtype>
<name>SOA</name>
<counter>100415</counter>
</rdtype>
<rdtype>
<name>PTR</name>
<counter>4211487</counter>
</rdtype>
<rdtype>
<name>MX</name>
<counter>441155</counter>
</rdtype>
<rdtype>
<name>TXT</name>
<counter>34628</counter>
</rdtype>
<rdtype>
<name>AAAA</name>
<counter>37786321</counter>
</rdtype>
<rdtype>
<name>SRV</name>
<counter>741082</counter>
</rdtype>
<rdtype>
<name>NAPTR</name>
<counter>39137</counter>
</rdtype>
<rdtype>
<name>DS</name>
<counter>584</counter>
</rdtype>
<rdtype>
<name>SSHFP</name>
<counter>2987</counter>
</rdtype>
<rdtype>
<name>DNSKEY</name>
<counter>452</counter>
</rdtype>
<rdtype>
<name>IXFR</name>
<counter>157</counter>
</rdtype>
<rdtype>
<name>ANY</name>
<counter>7</counter>
</rdtype>
</queries-in>
<nsstat>
<name>Requestv4</name>
<counter>102312611</counter>
</nsstat>
<nsstat>
<name>Requestv6</name>
<counter>1</counter>
</nsstat>
<nsstat>
<name>ReqEdns0</name>
<counter>441758</counter>
</nsstat>
<nsstat>
<name>ReqBadEDNSVer</name>
<counter>0</counter>
</nsstat>
<nsstat>
<name>ReqTSIG</name>
<counter>0</counter>
</nsstat>
<nsstat>
<name>ReqSIG0</name>
<counter>0</counter>
</nsstat>
<nsstat>
<name>ReqBadSIG</name>
<counter>0</counter>
</nsstat>
<nsstat>
<name>ReqTCP</name>
<counter>1548156</counter>
</nsstat>
<nsstat>
<name>AuthQryRej</name>
<counter>0</counter>
</nsstat>
<nsstat>
<name>RecQryRej</name>
<counter>0</counter>
</nsstat>
<nsstat>
<name>XfrRej</name>
<counter>0</counter>
</nsstat>
<nsstat>
<name>UpdateRej</name>
<counter>238</counter>
</nsstat>
<nsstat>
<name>Response</name>
<counter>102301560</counter>
</nsstat>
<nsstat>
<name>TruncatedResp</name>
<counter>3787</counter>
</nsstat>
<nsstat>
<name>RespEDNS0</name>
<counter>441748</counter>
</nsstat>
<nsstat>
<name>RespTSIG</name>
<counter>0</counter>
</nsstat>
<nsstat>
<name>RespSIG0</name>
<counter>0</counter>
</nsstat>
<nsstat>
<name>QrySuccess</name>
<counter>63811668</counter>
</nsstat>
<nsstat>
<name>QryAuthAns</name>
<counter>72180718</counter>
</nsstat>
<nsstat>
<name>QryNoauthAns</name>
<counter>30106182</counter>
</nsstat>
<nsstat>
<name>QryReferral</name>
<counter>3</counter>
</nsstat>
<nsstat>
<name>QryNxrrset</name>
<counter>24423133</counter>
</nsstat>
<nsstat>
<name>QrySERVFAIL</name>
<counter>14422</counter>
</nsstat>
<nsstat>
<name>QryFORMERR</name>
<counter>0</counter>
</nsstat>
<nsstat>
<name>QryNXDOMAIN</name>
<counter>14052096</counter>
</nsstat>
<nsstat>
<name>QryRecursion</name>
<counter>2104239</counter>
</nsstat>
<nsstat>
<name>QryDuplicate</name>
<counter>10879</counter>
</nsstat>
<nsstat>
<name>QryDropped</name>
<counter>16</counter>
</nsstat>
<nsstat>
<name>QryFailure</name>
<counter>0</counter>
</nsstat>
<nsstat>
<name>XfrReqDone</name>
<counter>157</counter>
</nsstat>
<nsstat>
<name>UpdateReqFwd</name>
<counter>0</counter>
</nsstat>
<nsstat>
<name>UpdateRespFwd</name>
<counter>0</counter>
</nsstat>
<nsstat>
<name>UpdateFwdFail</name>
<counter>0</counter>
</nsstat>
<nsstat>
<name>UpdateDone</name>
<counter>0</counter>
</nsstat>
<nsstat>
<name>UpdateFail</name>
<counter>0</counter>
</nsstat>
<nsstat>
<name>UpdateBadPrereq</name>
<counter>0</counter>
</nsstat>
<nsstat>
<name>RPZRewrites</name>
<counter>0</counter>
</nsstat>
<nsstat>
<name>RateDropped</name>
<counter>0</counter>
</nsstat>
<nsstat>
<name>RateSlipped</name>
<counter>0</counter>
</nsstat>
<zonestat>
<name>NotifyOutv4</name>
<counter>663</counter>
</zonestat>
<zonestat>
<name>NotifyOutv6</name>
<counter>0</counter>
</zonestat>
<zonestat>
<name>NotifyInv4</name>
<counter>0</counter>
</zonestat>
<zonestat>
<name>NotifyInv6</name>
<counter>0</counter>
</zonestat>
<zonestat>
<name>NotifyRej</name>
<counter>0</counter>
</zonestat>
<zonestat>
<name>SOAOutv4</name>
<counter>386</counter>
</zonestat>
<zonestat>
<name>SOAOutv6</name>
<counter>0</counter>
</zonestat>
<zonestat>
<name>AXFRReqv4</name>
<counter>0</counter>
</zonestat>
<zonestat>
<name>AXFRReqv6</name>
<counter>0</counter>
</zonestat>
<zonestat>
<name>IXFRReqv4</name>
<counter>0</counter>
</zonestat>
<zonestat>
<name>IXFRReqv6</name>
<counter>0</counter>
</zonestat>
<zonestat>
<name>XfrSuccess</name>
<counter>0</counter>
</zonestat>
<zonestat>
<name>XfrFail</name>
<counter>0</counter>
</zonestat>
<resstat>
<name>Mismatch</name>
<counter>2</counter>
</resstat>
<sockstat>
<name>UDP4Open</name>
<counter>3765532</counter>
</sockstat>
<sockstat>
<name>UDP6Open</name>
<counter>238269</counter>
</sockstat>
<sockstat>
<name>TCP4Open</name>
<counter>602</counter>
</sockstat>
<sockstat>
<name>TCP6Open</name>
<counter>2</counter>
</sockstat>
<sockstat>
<name>UnixOpen</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>UDP4OpenFail</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>UDP6OpenFail</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>TCP4OpenFail</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>TCP6OpenFail</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>UnixOpenFail</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>UDP4Close</name>
<counter>3765528</counter>
</sockstat>
<sockstat>
<name>UDP6Close</name>
<counter>238267</counter>
</sockstat>
<sockstat>
<name>TCP4Close</name>
<counter>1548268</counter>
</sockstat>
<sockstat>
<name>TCP6Close</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>UnixClose</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>FDWatchClose</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>UDP4BindFail</name>
<counter>219</counter>
</sockstat>
<sockstat>
<name>UDP6BindFail</name>
<counter>16</counter>
</sockstat>
<sockstat>
<name>TCP4BindFail</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>TCP6BindFail</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>UnixBindFail</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>FdwatchBindFail</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>UDP4ConnFail</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>UDP6ConnFail</name>
<counter>238250</counter>
</sockstat>
<sockstat>
<name>TCP4ConnFail</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>TCP6ConnFail</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>UnixConnFail</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>FDwatchConnFail</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>UDP4Conn</name>
<counter>3764828</counter>
</sockstat>
<sockstat>
<name>UDP6Conn</name>
<counter>1</counter>
</sockstat>
<sockstat>
<name>TCP4Conn</name>
<counter>590</counter>
</sockstat>
<sockstat>
<name>TCP6Conn</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>UnixConn</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>FDwatchConn</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>TCP4AcceptFail</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>TCP6AcceptFail</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>UnixAcceptFail</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>TCP4Accept</name>
<counter>1547672</counter>
</sockstat>
<sockstat>
<name>TCP6Accept</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>UnixAccept</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>UDP4SendErr</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>UDP6SendErr</name>
<counter>238250</counter>
</sockstat>
<sockstat>
<name>TCP4SendErr</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>TCP6SendErr</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>UnixSendErr</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>FDwatchSendErr</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>UDP4RecvErr</name>
<counter>1650</counter>
</sockstat>
<sockstat>
<name>UDP6RecvErr</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>TCP4RecvErr</name>
<counter>1</counter>
</sockstat>
<sockstat>
<name>TCP6RecvErr</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>UnixRecvErr</name>
<counter>0</counter>
</sockstat>
<sockstat>
<name>FDwatchRecvErr</name>
<counter>0</counter>
</sockstat>
</server>
<memory>
<contexts>
<context>
<id>0x7f8a94e061d0</id>
<name>main</name>
<references>229</references>
<total>5002528</total>
<inuse>3662792</inuse>
<maxinuse>4848264</maxinuse>
<blocksize>2359296</blocksize>
<pools>75</pools>
<hiwater>0</hiwater>
<lowater>0</lowater>
</context>
<context>
<id>0x7f8a94e13830</id>
<name>dst</name>
<references>1</references>
<total>133486</total>
<inuse>96456</inuse>
<maxinuse>102346</maxinuse>
<blocksize>-</blocksize>
<pools>0</pools>
<hiwater>0</hiwater>
<lowater>0</lowater>
</context>
<context>
<id>0x7f8a94e401c0</id>
<name>zonemgr-pool</name>
<references>501</references>
<total>6339848</total>
<inuse>4384240</inuse>
<maxinuse>5734049</maxinuse>
<blocksize>6029312</blocksize>
<pools>0</pools>
<hiwater>0</hiwater>
<lowater>0</lowater>
</context>
</contexts>
<summary>
<TotalUse>81804609</TotalUse>
<InUse>20772579</InUse>
<BlockSize>77070336</BlockSize>
<ContextSize>6663840</ContextSize>
<Lost>0</Lost>
</summary>
</memory>
</statistics>
</bind>
</isc>

142
plugins/inputs/bind/testdata/xml/v3/mem vendored Normal file
View File

@ -0,0 +1,142 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/bind9.xsl"?>
<statistics version="3.6">
<server>
<boot-time>2017-07-21T11:53:28Z</boot-time>
<config-time>2017-07-21T11:53:28Z</config-time>
<current-time>2017-07-25T23:47:08Z</current-time>
</server>
<views>
</views>
<memory>
<contexts>
<context>
<id>0x55fb2e042de0</id>
<name>main</name>
<references>202</references>
<total>2706043</total>
<inuse>1454904</inuse>
<maxinuse>1508072</maxinuse>
<blocksize>786432</blocksize>
<pools>40</pools>
<hiwater>0</hiwater>
<lowater>0</lowater>
</context>
<context>
<id>0x55fb2e0507e0</id>
<name>dst</name>
<references>1</references>
<total>387478</total>
<inuse>91776</inuse>
<maxinuse>97208</maxinuse>
<blocksize>-</blocksize>
<pools>0</pools>
<hiwater>0</hiwater>
<lowater>0</lowater>
</context>
<context>
<id>0x55fb2e0938e0</id>
<name>zonemgr-pool</name>
<references>113</references>
<total>742986</total>
<inuse>143776</inuse>
<maxinuse>313961</maxinuse>
<blocksize>262144</blocksize>
<pools>0</pools>
<hiwater>0</hiwater>
<lowater>0</lowater>
</context>
<context>
<id>0x7f19d00017d0</id>
<name>threadkey</name>
<references>1</references>
<total>0</total>
<inuse>0</inuse>
<maxinuse>0</maxinuse>
<blocksize>-</blocksize>
<pools>0</pools>
<hiwater>0</hiwater>
<lowater>0</lowater>
</context>
<context>
<id>0x7f19d00475f0</id>
<name>client</name>
<references>3</references>
<total>267800</total>
<inuse>8760</inuse>
<maxinuse>8760</maxinuse>
<blocksize>262144</blocksize>
<pools>2</pools>
<hiwater>0</hiwater>
<lowater>0</lowater>
</context>
<context>
<id>0x7f19d00dfca0</id>
<name>cache</name>
<references>8</references>
<total>288938</total>
<inuse>83650</inuse>
<maxinuse>83842</maxinuse>
<blocksize>262144</blocksize>
<pools>0</pools>
<hiwater>0</hiwater>
<lowater>0</lowater>
</context>
<context>
<id>0x7f19d00eaa30</id>
<name>cache_heap</name>
<references>18</references>
<total>393216</total>
<inuse>132096</inuse>
<maxinuse>132096</maxinuse>
<blocksize>262144</blocksize>
<pools>0</pools>
<hiwater>0</hiwater>
<lowater>0</lowater>
</context>
<context>
<id>0x7f19d01094e0</id>
<name>res0</name>
<references>1</references>
<total>262144</total>
<inuse>0</inuse>
<maxinuse>22048</maxinuse>
<blocksize>262144</blocksize>
<pools>0</pools>
<hiwater>0</hiwater>
<lowater>0</lowater>
</context>
<context>
<id>0x7f19d0114270</id>
<name>res1</name>
<references>1</references>
<total>0</total>
<inuse>0</inuse>
<maxinuse>0</maxinuse>
<blocksize>0</blocksize>
<pools>0</pools>
<hiwater>0</hiwater>
<lowater>0</lowater>
</context>
<context>
<id>0x7f19d011f000</id>
<name>res2</name>
<references>1</references>
<total>0</total>
<inuse>0</inuse>
<maxinuse>0</maxinuse>
<blocksize>0</blocksize>
<pools>0</pools>
<hiwater>0</hiwater>
<lowater>0</lowater>
</context>
</contexts>
<summary>
<TotalUse>777821909</TotalUse>
<InUse>6000232</InUse>
<BlockSize>45875200</BlockSize>
<ContextSize>10037400</ContextSize>
<Lost>0</Lost>
</summary>
</memory>
</statistics>

156
plugins/inputs/bind/testdata/xml/v3/net vendored Normal file
View File

@ -0,0 +1,156 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/bind9.xsl"?>
<statistics version="3.6">
<server>
<boot-time>2017-07-21T11:53:28Z</boot-time>
<config-time>2017-07-21T11:53:28Z</config-time>
<current-time>2017-07-25T23:47:08Z</current-time>
<counters type="sockstat">
<counter name="UDP4Open">92542</counter>
<counter name="UDP6Open">0</counter>
<counter name="TCP4Open">48</counter>
<counter name="TCP6Open">0</counter>
<counter name="UnixOpen">0</counter>
<counter name="RawOpen">1</counter>
<counter name="UDP4OpenFail">0</counter>
<counter name="UDP6OpenFail">0</counter>
<counter name="TCP4OpenFail">0</counter>
<counter name="TCP6OpenFail">0</counter>
<counter name="UnixOpenFail">0</counter>
<counter name="RawOpenFail">0</counter>
<counter name="UDP4Close">92538</counter>
<counter name="UDP6Close">0</counter>
<counter name="TCP4Close">336</counter>
<counter name="TCP6Close">0</counter>
<counter name="UnixClose">0</counter>
<counter name="FDWatchClose">0</counter>
<counter name="RawClose">0</counter>
<counter name="UDP4BindFail">1</counter>
<counter name="UDP6BindFail">0</counter>
<counter name="TCP4BindFail">0</counter>
<counter name="TCP6BindFail">0</counter>
<counter name="UnixBindFail">0</counter>
<counter name="FdwatchBindFail">0</counter>
<counter name="UDP4ConnFail">0</counter>
<counter name="UDP6ConnFail">0</counter>
<counter name="TCP4ConnFail">0</counter>
<counter name="TCP6ConnFail">0</counter>
<counter name="UnixConnFail">0</counter>
<counter name="FDwatchConnFail">0</counter>
<counter name="UDP4Conn">92535</counter>
<counter name="UDP6Conn">0</counter>
<counter name="TCP4Conn">44</counter>
<counter name="TCP6Conn">0</counter>
<counter name="UnixConn">0</counter>
<counter name="FDwatchConn">0</counter>
<counter name="TCP4AcceptFail">0</counter>
<counter name="TCP6AcceptFail">0</counter>
<counter name="UnixAcceptFail">0</counter>
<counter name="TCP4Accept">293</counter>
<counter name="TCP6Accept">0</counter>
<counter name="UnixAccept">0</counter>
<counter name="UDP4SendErr">0</counter>
<counter name="UDP6SendErr">0</counter>
<counter name="TCP4SendErr">0</counter>
<counter name="TCP6SendErr">0</counter>
<counter name="UnixSendErr">0</counter>
<counter name="FDwatchSendErr">0</counter>
<counter name="UDP4RecvErr">14</counter>
<counter name="UDP6RecvErr">0</counter>
<counter name="TCP4RecvErr">0</counter>
<counter name="TCP6RecvErr">0</counter>
<counter name="UnixRecvErr">0</counter>
<counter name="FDwatchRecvErr">0</counter>
<counter name="RawRecvErr">0</counter>
<counter name="UDP4Active">4</counter>
<counter name="UDP6Active">0</counter>
<counter name="TCP4Active">297</counter>
<counter name="TCP6Active">0</counter>
<counter name="UnixActive">0</counter>
<counter name="RawActive">1</counter>
</counters>
</server>
<views>
</views>
<socketmgr>
<sockets>
<socket>
<id>0x7f19dd849010</id>
<references>1</references>
<type>not-initialized</type>
<local-address>&lt;unknown address, family 16&gt;</local-address>
<states>
<state>bound</state>
</states>
</socket>
<socket>
<id>0x7f19dd849268</id>
<references>1</references>
<type>tcp</type>
<local-address>0.0.0.0#8053</local-address>
<states>
<state>listener</state>
<state>bound</state>
</states>
</socket>
<socket>
<id>0x7f19dd849718</id>
<references>2</references>
<type>udp</type>
<local-address>::#53</local-address>
<states>
<state>bound</state>
</states>
</socket>
<socket>
<id>0x7f19dd849970</id>
<references>2</references>
<type>tcp</type>
<local-address>::#53</local-address>
<states>
<state>listener</state>
<state>bound</state>
</states>
</socket>
<socket>
<id>0x7f19dd849bc8</id>
<references>2</references>
<type>udp</type>
<local-address>127.0.0.1#53</local-address>
<states>
<state>bound</state>
</states>
</socket>
<socket>
<id>0x7f19dd6f4010</id>
<references>2</references>
<type>tcp</type>
<local-address>127.0.0.1#53</local-address>
<states>
<state>listener</state>
<state>bound</state>
</states>
</socket>
<socket>
<id>0x7f19dd6f4718</id>
<references>1</references>
<type>tcp</type>
<local-address>127.0.0.1#953</local-address>
<states>
<state>listener</state>
<state>bound</state>
</states>
</socket>
<socket>
<id>0x7f19dd6f4bc8</id>
<references>1</references>
<type>tcp</type>
<local-address>::1#953</local-address>
<states>
<state>listener</state>
<state>bound</state>
</states>
</socket>
</sockets>
</socketmgr>
</statistics>

View File

@ -0,0 +1,328 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/bind9.xsl"?>
<statistics version="3.6">
<server>
<boot-time>2017-07-21T11:53:28Z</boot-time>
<config-time>2017-07-21T11:53:28Z</config-time>
<current-time>2017-07-25T23:47:08Z</current-time>
<counters type="opcode">
<counter name="QUERY">74941</counter>
<counter name="IQUERY">0</counter>
<counter name="STATUS">0</counter>
<counter name="RESERVED3">0</counter>
<counter name="NOTIFY">0</counter>
<counter name="UPDATE">0</counter>
<counter name="RESERVED6">0</counter>
<counter name="RESERVED7">0</counter>
<counter name="RESERVED8">0</counter>
<counter name="RESERVED9">0</counter>
<counter name="RESERVED10">0</counter>
<counter name="RESERVED11">0</counter>
<counter name="RESERVED12">0</counter>
<counter name="RESERVED13">0</counter>
<counter name="RESERVED14">0</counter>
<counter name="RESERVED15">0</counter>
</counters>
<counters type="qtype">
<counter name="A">63672</counter>
<counter name="NS">373</counter>
<counter name="SOA">18</counter>
<counter name="PTR">3393</counter>
<counter name="MX">618</counter>
<counter name="TXT">970</counter>
<counter name="AAAA">5735</counter>
<counter name="SRV">139</counter>
<counter name="RRSIG">1</counter>
<counter name="ANY">22</counter>
</counters>
<counters type="nsstat">
<counter name="Requestv4">74942</counter>
<counter name="Requestv6">0</counter>
<counter name="ReqEdns0">9250</counter>
<counter name="ReqBadEDNSVer">0</counter>
<counter name="ReqTSIG">0</counter>
<counter name="ReqSIG0">0</counter>
<counter name="ReqBadSIG">0</counter>
<counter name="ReqTCP">260</counter>
<counter name="AuthQryRej">0</counter>
<counter name="RecQryRej">35</counter>
<counter name="XfrRej">0</counter>
<counter name="UpdateRej">0</counter>
<counter name="Response">63264</counter>
<counter name="TruncatedResp">365</counter>
<counter name="RespEDNS0">9250</counter>
<counter name="RespTSIG">0</counter>
<counter name="RespSIG0">0</counter>
<counter name="QrySuccess">49044</counter>
<counter name="QryAuthAns">2752</counter>
<counter name="QryNoauthAns">60354</counter>
<counter name="QryReferral">0</counter>
<counter name="QryNxrrset">2452</counter>
<counter name="QrySERVFAIL">122</counter>
<counter name="QryFORMERR">0</counter>
<counter name="QryNXDOMAIN">11610</counter>
<counter name="QryRecursion">53750</counter>
<counter name="QryDuplicate">11667</counter>
<counter name="QryDropped">11</counter>
<counter name="QryFailure">35</counter>
<counter name="XfrReqDone">0</counter>
<counter name="UpdateReqFwd">0</counter>
<counter name="UpdateRespFwd">0</counter>
<counter name="UpdateFwdFail">0</counter>
<counter name="UpdateDone">0</counter>
<counter name="UpdateFail">0</counter>
<counter name="UpdateBadPrereq">0</counter>
<counter name="RecursClients">0</counter>
<counter name="DNS64">0</counter>
<counter name="RateDropped">0</counter>
<counter name="RateSlipped">0</counter>
<counter name="RPZRewrites">0</counter>
<counter name="QryUDP">74648</counter>
<counter name="QryTCP">258</counter>
<counter name="NSIDOpt">0</counter>
<counter name="ExpireOpt">0</counter>
<counter name="OtherOpt">59</counter>
<counter name="SitOpt">0</counter>
<counter name="SitNew">0</counter>
<counter name="SitBadSize">0</counter>
<counter name="SitBadTime">0</counter>
<counter name="SitNoMatch">0</counter>
<counter name="SitMatch">0</counter>
</counters>
<counters type="zonestat">
<counter name="NotifyOutv4">2</counter>
<counter name="NotifyOutv6">0</counter>
<counter name="NotifyInv4">0</counter>
<counter name="NotifyInv6">0</counter>
<counter name="NotifyRej">0</counter>
<counter name="SOAOutv4">0</counter>
<counter name="SOAOutv6">0</counter>
<counter name="AXFRReqv4">0</counter>
<counter name="AXFRReqv6">0</counter>
<counter name="IXFRReqv4">0</counter>
<counter name="IXFRReqv6">0</counter>
<counter name="XfrSuccess">0</counter>
<counter name="XfrFail">0</counter>
</counters>
<counters type="resstat"/>
</server>
<views>
<view name="_default">
<counters type="resqtype">
<counter name="A">61568</counter>
<counter name="NS">9126</counter>
<counter name="PTR">1249</counter>
<counter name="MX">286</counter>
<counter name="TXT">942</counter>
<counter name="AAAA">3933</counter>
<counter name="SRV">21</counter>
<counter name="DS">13749</counter>
<counter name="DNSKEY">1699</counter>
</counters>
<counters type="resstats">
<counter name="Queryv4">92573</counter>
<counter name="Queryv6">0</counter>
<counter name="Responsev4">92135</counter>
<counter name="Responsev6">0</counter>
<counter name="NXDOMAIN">8182</counter>
<counter name="SERVFAIL">318</counter>
<counter name="FORMERR">0</counter>
<counter name="OtherError">0</counter>
<counter name="EDNS0Fail">0</counter>
<counter name="Mismatch">0</counter>
<counter name="Truncated">42</counter>
<counter name="Lame">12</counter>
<counter name="Retry">800</counter>
<counter name="QueryAbort">0</counter>
<counter name="QuerySockFail">0</counter>
<counter name="QueryCurUDP">0</counter>
<counter name="QueryCurTCP">0</counter>
<counter name="QueryTimeout">490</counter>
<counter name="GlueFetchv4">1398</counter>
<counter name="GlueFetchv6">0</counter>
<counter name="GlueFetchv4Fail">3</counter>
<counter name="GlueFetchv6Fail">0</counter>
<counter name="ValAttempt">90256</counter>
<counter name="ValOk">67322</counter>
<counter name="ValNegOk">22850</counter>
<counter name="ValFail">6</counter>
<counter name="QryRTT10">0</counter>
<counter name="QryRTT100">45760</counter>
<counter name="QryRTT500">45543</counter>
<counter name="QryRTT800">743</counter>
<counter name="QryRTT1600">75</counter>
<counter name="QryRTT1600+">0</counter>
<counter name="NumFetch">0</counter>
<counter name="BucketSize">31</counter>
<counter name="REFUSED">34</counter>
<counter name="SitClientOut">0</counter>
<counter name="SitOut">0</counter>
<counter name="SitIn">0</counter>
<counter name="SitClientOk">0</counter>
<counter name="BadEDNSVersion">0</counter>
<counter name="ZoneQuota">0</counter>
<counter name="ServerQuota">0</counter>
</counters>
<cache name="internal">
<rrset>
<name>A</name>
<counter>195</counter>
</rrset>
<rrset>
<name>NS</name>
<counter>42</counter>
</rrset>
<rrset>
<name>CNAME</name>
<counter>7</counter>
</rrset>
<rrset>
<name>PTR</name>
<counter>48</counter>
</rrset>
<rrset>
<name>MX</name>
<counter>7</counter>
</rrset>
<rrset>
<name>TXT</name>
<counter>6</counter>
</rrset>
<rrset>
<name>AAAA</name>
<counter>4</counter>
</rrset>
<rrset>
<name>DS</name>
<counter>97</counter>
</rrset>
<rrset>
<name>RRSIG</name>
<counter>258</counter>
</rrset>
<rrset>
<name>NSEC</name>
<counter>89</counter>
</rrset>
<rrset>
<name>DNSKEY</name>
<counter>60</counter>
</rrset>
<rrset>
<name>!DS</name>
<counter>29</counter>
</rrset>
<rrset>
<name>NXDOMAIN</name>
<counter>25</counter>
</rrset>
</cache>
<counters type="adbstat">
<counter name="nentries">1021</counter>
<counter name="entriescnt">314</counter>
<counter name="nnames">1021</counter>
<counter name="namescnt">316</counter>
</counters>
<counters type="cachestats">
<counter name="CacheHits">1904593</counter>
<counter name="CacheMisses">96</counter>
<counter name="QueryHits">336094</counter>
<counter name="QueryMisses">369336</counter>
<counter name="DeleteLRU">0</counter>
<counter name="DeleteTTL">47518</counter>
<counter name="CacheNodes">769</counter>
<counter name="CacheBuckets">519</counter>
<counter name="TreeMemTotal">1464363</counter>
<counter name="TreeMemInUse">392128</counter>
<counter name="TreeMemMax">828966</counter>
<counter name="HeapMemTotal">393216</counter>
<counter name="HeapMemInUse">132096</counter>
<counter name="HeapMemMax">132096</counter>
</counters>
</view>
<view name="_bind">
<zones>
<zone name="authors.bind" rdataclass="CH">
<serial>0</serial>
</zone>
<zone name="hostname.bind" rdataclass="CH">
<serial>0</serial>
</zone>
<zone name="version.bind" rdataclass="CH">
<serial>0</serial>
</zone>
<zone name="id.server" rdataclass="CH">
<serial>0</serial>
</zone>
</zones>
<counters type="resqtype"/>
<counters type="resstats">
<counter name="Queryv4">0</counter>
<counter name="Queryv6">0</counter>
<counter name="Responsev4">0</counter>
<counter name="Responsev6">0</counter>
<counter name="NXDOMAIN">0</counter>
<counter name="SERVFAIL">0</counter>
<counter name="FORMERR">0</counter>
<counter name="OtherError">0</counter>
<counter name="EDNS0Fail">0</counter>
<counter name="Mismatch">0</counter>
<counter name="Truncated">0</counter>
<counter name="Lame">0</counter>
<counter name="Retry">0</counter>
<counter name="QueryAbort">0</counter>
<counter name="QuerySockFail">0</counter>
<counter name="QueryCurUDP">0</counter>
<counter name="QueryCurTCP">0</counter>
<counter name="QueryTimeout">0</counter>
<counter name="GlueFetchv4">0</counter>
<counter name="GlueFetchv6">0</counter>
<counter name="GlueFetchv4Fail">0</counter>
<counter name="GlueFetchv6Fail">0</counter>
<counter name="ValAttempt">0</counter>
<counter name="ValOk">0</counter>
<counter name="ValNegOk">0</counter>
<counter name="ValFail">0</counter>
<counter name="QryRTT10">0</counter>
<counter name="QryRTT100">0</counter>
<counter name="QryRTT500">0</counter>
<counter name="QryRTT800">0</counter>
<counter name="QryRTT1600">0</counter>
<counter name="QryRTT1600+">0</counter>
<counter name="NumFetch">0</counter>
<counter name="BucketSize">31</counter>
<counter name="REFUSED">0</counter>
<counter name="SitClientOut">0</counter>
<counter name="SitOut">0</counter>
<counter name="SitIn">0</counter>
<counter name="SitClientOk">0</counter>
<counter name="BadEDNSVersion">0</counter>
<counter name="ZoneQuota">0</counter>
<counter name="ServerQuota">0</counter>
</counters>
<cache name="_bind"/>
<counters type="adbstat">
<counter name="nentries">1021</counter>
<counter name="entriescnt">0</counter>
<counter name="nnames">1021</counter>
<counter name="namescnt">0</counter>
</counters>
<counters type="cachestats">
<counter name="CacheHits">0</counter>
<counter name="CacheMisses">0</counter>
<counter name="QueryHits">0</counter>
<counter name="QueryMisses">0</counter>
<counter name="DeleteLRU">0</counter>
<counter name="DeleteTTL">0</counter>
<counter name="CacheNodes">0</counter>
<counter name="CacheBuckets">64</counter>
<counter name="TreeMemTotal">287392</counter>
<counter name="TreeMemInUse">29608</counter>
<counter name="TreeMemMax">29608</counter>
<counter name="HeapMemTotal">262144</counter>
<counter name="HeapMemInUse">1024</counter>
<counter name="HeapMemMax">1024</counter>
</counters>
</view>
</views>
</statistics>

View File

@ -0,0 +1,168 @@
package bind
import (
"encoding/xml"
"fmt"
"net"
"net/http"
"net/url"
"time"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/metric"
)
type v2Root struct {
XMLName xml.Name
Version string `xml:"version,attr"`
Statistics v2Statistics `xml:"bind>statistics"`
}
// Omitted branches: socketmgr, taskmgr
type v2Statistics struct {
Version string `xml:"version,attr"`
Views []struct {
// Omitted branches: zones
Name string `xml:"name"`
RdTypes []v2Counter `xml:"rdtype"`
ResStats []v2Counter `xml:"resstat"`
Caches []struct {
Name string `xml:"name,attr"`
RRSets []v2Counter `xml:"rrset"`
} `xml:"cache"`
} `xml:"views>view"`
Server struct {
OpCodes []v2Counter `xml:"requests>opcode"`
RdTypes []v2Counter `xml:"queries-in>rdtype"`
NSStats []v2Counter `xml:"nsstat"`
ZoneStats []v2Counter `xml:"zonestat"`
ResStats []v2Counter `xml:"resstat"`
SockStats []v2Counter `xml:"sockstat"`
} `xml:"server"`
Memory struct {
Contexts []struct {
// Omitted nodes: references, maxinuse, blocksize, pools, hiwater, lowater
Id string `xml:"id"`
Name string `xml:"name"`
Total int `xml:"total"`
InUse int `xml:"inuse"`
} `xml:"contexts>context"`
Summary struct {
TotalUse int
InUse int
BlockSize int
ContextSize int
Lost int
} `xml:"summary"`
} `xml:"memory"`
}
// BIND statistics v2 counter struct used throughout
type v2Counter struct {
Name string `xml:"name"`
Value int `xml:"counter"`
}
// addXMLv2Counter adds a v2Counter array to a Telegraf Accumulator, with the specified tags
func addXMLv2Counter(acc telegraf.Accumulator, commonTags map[string]string, stats []v2Counter) {
grouper := metric.NewSeriesGrouper()
ts := time.Now()
for _, c := range stats {
tags := make(map[string]string)
// Create local copy of tags since maps are reference types
for k, v := range commonTags {
tags[k] = v
}
grouper.Add("bind_counter", tags, ts, c.Name, c.Value)
}
//Add grouped metrics
for _, metric := range grouper.Metrics() {
acc.AddMetric(metric)
}
}
// readStatsXMLv2 decodes a BIND9 XML statistics version 2 document. Unlike the XML v3 statistics
// format, the v2 format does not support broken-out subsets.
func (b *Bind) readStatsXMLv2(addr *url.URL, acc telegraf.Accumulator) error {
var stats v2Root
resp, err := client.Get(addr.String())
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("%s returned HTTP status: %s", addr, resp.Status)
}
if err := xml.NewDecoder(resp.Body).Decode(&stats); err != nil {
return fmt.Errorf("Unable to decode XML document: %s", err)
}
tags := map[string]string{"url": addr.Host}
host, port, _ := net.SplitHostPort(addr.Host)
tags["source"] = host
tags["port"] = port
// Opcodes
tags["type"] = "opcode"
addXMLv2Counter(acc, tags, stats.Statistics.Server.OpCodes)
// Query RDATA types
tags["type"] = "qtype"
addXMLv2Counter(acc, tags, stats.Statistics.Server.RdTypes)
// Nameserver stats
tags["type"] = "nsstat"
addXMLv2Counter(acc, tags, stats.Statistics.Server.NSStats)
// Zone stats
tags["type"] = "zonestat"
addXMLv2Counter(acc, tags, stats.Statistics.Server.ZoneStats)
// Socket statistics
tags["type"] = "sockstat"
addXMLv2Counter(acc, tags, stats.Statistics.Server.SockStats)
// Memory stats
fields := map[string]interface{}{
"total_use": stats.Statistics.Memory.Summary.TotalUse,
"in_use": stats.Statistics.Memory.Summary.InUse,
"block_size": stats.Statistics.Memory.Summary.BlockSize,
"context_size": stats.Statistics.Memory.Summary.ContextSize,
"lost": stats.Statistics.Memory.Summary.Lost,
}
acc.AddGauge("bind_memory", fields, map[string]string{"url": addr.Host, "source": host, "port": port})
// Detailed, per-context memory stats
if b.GatherMemoryContexts {
for _, c := range stats.Statistics.Memory.Contexts {
tags := map[string]string{"url": addr.Host, "id": c.Id, "name": c.Name, "source": host, "port": port}
fields := map[string]interface{}{"total": c.Total, "in_use": c.InUse}
acc.AddGauge("bind_memory_context", fields, tags)
}
}
// Detailed, per-view stats
if b.GatherViews {
for _, v := range stats.Statistics.Views {
tags := map[string]string{"url": addr.Host, "view": v.Name}
// Query RDATA types
tags["type"] = "qtype"
addXMLv2Counter(acc, tags, v.RdTypes)
// Resolver stats
tags["type"] = "resstats"
addXMLv2Counter(acc, tags, v.ResStats)
}
}
return nil
}

View File

@ -0,0 +1,161 @@
package bind
import (
"encoding/xml"
"fmt"
"net"
"net/http"
"net/url"
"strings"
"time"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/metric"
)
// XML path: //statistics
// Omitted branches: socketmgr, taskmgr
type v3Stats struct {
Server v3Server `xml:"server"`
Views []v3View `xml:"views>view"`
Memory v3Memory `xml:"memory"`
}
// XML path: //statistics/memory
type v3Memory struct {
Contexts []struct {
// Omitted nodes: references, maxinuse, blocksize, pools, hiwater, lowater
Id string `xml:"id"`
Name string `xml:"name"`
Total int `xml:"total"`
InUse int `xml:"inuse"`
} `xml:"contexts>context"`
Summary struct {
TotalUse int
InUse int
BlockSize int
ContextSize int
Lost int
} `xml:"summary"`
}
// XML path: //statistics/server
type v3Server struct {
CounterGroups []v3CounterGroup `xml:"counters"`
}
// XML path: //statistics/views/view
type v3View struct {
// Omitted branches: zones
Name string `xml:"name,attr"`
CounterGroups []v3CounterGroup `xml:"counters"`
Caches []struct {
Name string `xml:"name,attr"`
RRSets []struct {
Name string `xml:"name"`
Value int `xml:"counter"`
} `xml:"rrset"`
} `xml:"cache"`
}
// Generic XML v3 doc fragment used in multiple places
type v3CounterGroup struct {
Type string `xml:"type,attr"`
Counters []struct {
Name string `xml:"name,attr"`
Value int `xml:",chardata"`
} `xml:"counter"`
}
// addStatsXMLv3 walks a v3Stats struct and adds the values to the telegraf.Accumulator.
func (b *Bind) addStatsXMLv3(stats v3Stats, acc telegraf.Accumulator, hostPort string) {
grouper := metric.NewSeriesGrouper()
ts := time.Now()
host, port, _ := net.SplitHostPort(hostPort)
// Counter groups
for _, cg := range stats.Server.CounterGroups {
for _, c := range cg.Counters {
if cg.Type == "opcode" && strings.HasPrefix(c.Name, "RESERVED") {
continue
}
tags := map[string]string{"url": hostPort, "source": host, "port": port, "type": cg.Type}
grouper.Add("bind_counter", tags, ts, c.Name, c.Value)
}
}
// Memory stats
fields := map[string]interface{}{
"total_use": stats.Memory.Summary.TotalUse,
"in_use": stats.Memory.Summary.InUse,
"block_size": stats.Memory.Summary.BlockSize,
"context_size": stats.Memory.Summary.ContextSize,
"lost": stats.Memory.Summary.Lost,
}
acc.AddGauge("bind_memory", fields, map[string]string{"url": hostPort, "source": host, "port": port})
// Detailed, per-context memory stats
if b.GatherMemoryContexts {
for _, c := range stats.Memory.Contexts {
tags := map[string]string{"url": hostPort, "source": host, "port": port, "id": c.Id, "name": c.Name}
fields := map[string]interface{}{"total": c.Total, "in_use": c.InUse}
acc.AddGauge("bind_memory_context", fields, tags)
}
}
// Detailed, per-view stats
if b.GatherViews {
for _, v := range stats.Views {
for _, cg := range v.CounterGroups {
for _, c := range cg.Counters {
tags := map[string]string{
"url": hostPort,
"source": host,
"port": port,
"view": v.Name,
"type": cg.Type,
}
grouper.Add("bind_counter", tags, ts, c.Name, c.Value)
}
}
}
}
//Add grouped metrics
for _, metric := range grouper.Metrics() {
acc.AddMetric(metric)
}
}
// readStatsXMLv3 takes a base URL to probe, and requests the individual statistics documents that
// we are interested in. These individual documents have a combined size which is significantly
// smaller than if we requested everything at once (e.g. taskmgr and socketmgr can be omitted).
func (b *Bind) readStatsXMLv3(addr *url.URL, acc telegraf.Accumulator) error {
var stats v3Stats
// Progressively build up full v3Stats struct by parsing the individual HTTP responses
for _, suffix := range [...]string{"/server", "/net", "/mem"} {
scrapeUrl := addr.String() + suffix
resp, err := client.Get(scrapeUrl)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("%s returned HTTP status: %s", scrapeUrl, resp.Status)
}
if err := xml.NewDecoder(resp.Body).Decode(&stats); err != nil {
return fmt.Errorf("Unable to decode XML document: %s", err)
}
}
b.addStatsXMLv3(stats, acc, addr.Host)
return nil
}