Add rcode tag and field to dns_query input (#5417)

This commit is contained in:
Greg 2019-02-12 18:57:20 -07:00 committed by Daniel Nelson
parent f001303189
commit 3e9703a573
2 changed files with 39 additions and 7 deletions

View File

@ -34,12 +34,40 @@ The DNS plugin gathers dns query times in miliseconds - like [Dig](https://en.wi
- domain - domain
- record_type - record_type
- result - result
- rcode
- fields: - fields:
- query_time_ms (float) - query_time_ms (float)
- result_code (int, success = 0, timeout = 1, error = 2) - result_code (int, success = 0, timeout = 1, error = 2)
- rcode_value (int)
### Rcode Descriptions
|rcode_value|rcode|Description|
|---|-----------|-----------------------------------|
|0 | NoError | No Error |
|1 | FormErr | Format Error |
|2 | ServFail | Server Failure |
|3 | NXDomain | Non-Existent Domain |
|4 | NotImp | Not Implemented |
|5 | Refused | Query Refused |
|6 | YXDomain | Name Exists when it should not |
|7 | YXRRSet | RR Set Exists when it should not |
|8 | NXRRSet | RR Set that should exist does not |
|9 | NotAuth | Server Not Authoritative for zone |
|10 | NotZone | Name not contained in zone |
|16 | BADSIG | TSIG Signature Failure |
|16 | BADVERS | Bad OPT Version |
|17 | BADKEY | Key not recognized |
|18 | BADTIME | Signature out of time window |
|19 | BADMODE | Bad TKEY Mode |
|20 | BADNAME | Duplicate key name |
|21 | BADALG | Algorithm not supported |
|22 | BADTRUNC | Bad Truncation |
|23 | BADCOOKIE | Bad/missing Server Cookie |
### Example Output: ### Example Output:
``` ```
dns_query,domain=mjasion.pl,record_type=A,server=8.8.8.8 query_time_ms=67.189842 1456082743585760680 dns_query,domain=google.com,rcode=NOERROR,record_type=A,result=success,server=127.0.0.1 rcode_value=0i,result_code=0i,query_time_ms=0.13746 1550020750001000000
``` ```

View File

@ -85,7 +85,11 @@ func (d *DnsQuery) Gather(acc telegraf.Accumulator) error {
"record_type": d.RecordType, "record_type": d.RecordType,
} }
dnsQueryTime, err := d.getDnsQueryTime(domain, server) dnsQueryTime, rcode, err := d.getDnsQueryTime(domain, server)
if rcode >= 0 {
tags["rcode"] = dns.RcodeToString[rcode]
fields["rcode_value"] = rcode
}
if err == nil { if err == nil {
setResult(Success, fields, tags) setResult(Success, fields, tags)
fields["query_time_ms"] = dnsQueryTime fields["query_time_ms"] = dnsQueryTime
@ -130,7 +134,7 @@ func (d *DnsQuery) setDefaultValues() {
} }
} }
func (d *DnsQuery) getDnsQueryTime(domain string, server string) (float64, error) { func (d *DnsQuery) getDnsQueryTime(domain string, server string) (float64, int, error) {
dnsQueryTime := float64(0) dnsQueryTime := float64(0)
c := new(dns.Client) c := new(dns.Client)
@ -140,20 +144,20 @@ func (d *DnsQuery) getDnsQueryTime(domain string, server string) (float64, error
m := new(dns.Msg) m := new(dns.Msg)
recordType, err := d.parseRecordType() recordType, err := d.parseRecordType()
if err != nil { if err != nil {
return dnsQueryTime, err return dnsQueryTime, -1, err
} }
m.SetQuestion(dns.Fqdn(domain), recordType) m.SetQuestion(dns.Fqdn(domain), recordType)
m.RecursionDesired = true m.RecursionDesired = true
r, rtt, err := c.Exchange(m, net.JoinHostPort(server, strconv.Itoa(d.Port))) r, rtt, err := c.Exchange(m, net.JoinHostPort(server, strconv.Itoa(d.Port)))
if err != nil { if err != nil {
return dnsQueryTime, err return dnsQueryTime, -1, err
} }
if r.Rcode != dns.RcodeSuccess { if r.Rcode != dns.RcodeSuccess {
return dnsQueryTime, errors.New(fmt.Sprintf("Invalid answer name %s after %s query for %s\n", domain, d.RecordType, domain)) return dnsQueryTime, r.Rcode, fmt.Errorf("Invalid answer (%s) from %s after %s query for %s", dns.RcodeToString[r.Rcode], server, d.RecordType, domain)
} }
dnsQueryTime = float64(rtt.Nanoseconds()) / 1e6 dnsQueryTime = float64(rtt.Nanoseconds()) / 1e6
return dnsQueryTime, nil return dnsQueryTime, r.Rcode, nil
} }
func (d *DnsQuery) parseRecordType() (uint16, error) { func (d *DnsQuery) parseRecordType() (uint16, error) {