Adding upstream version 1.34.4.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
e393c3af3f
commit
4978089aab
4963 changed files with 677545 additions and 0 deletions
93
plugins/inputs/dns_query/README.md
Normal file
93
plugins/inputs/dns_query/README.md
Normal file
|
@ -0,0 +1,93 @@
|
|||
# DNS Query Input Plugin
|
||||
|
||||
This plugin gathers information about DNS queries such as response time and
|
||||
result codes.
|
||||
|
||||
⭐ Telegraf v1.4.0
|
||||
🏷️ system, network
|
||||
💻 all
|
||||
|
||||
## Global configuration options <!-- @/docs/includes/plugin_config.md -->
|
||||
|
||||
In addition to the plugin-specific configuration settings, plugins support
|
||||
additional global and plugin configuration settings. These settings are used to
|
||||
modify metrics, tags, and field or create aliases and configure ordering, etc.
|
||||
See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
|
||||
|
||||
[CONFIGURATION.md]: ../../../docs/CONFIGURATION.md#plugins
|
||||
|
||||
## Configuration
|
||||
|
||||
```toml @sample.conf
|
||||
# Query given DNS server and gives statistics
|
||||
[[inputs.dns_query]]
|
||||
## servers to query
|
||||
servers = ["8.8.8.8"]
|
||||
|
||||
## Network is the network protocol name.
|
||||
# network = "udp"
|
||||
|
||||
## Domains or subdomains to query.
|
||||
# domains = ["."]
|
||||
|
||||
## Query record type.
|
||||
## Possible values: A, AAAA, CNAME, MX, NS, PTR, TXT, SOA, SPF, SRV.
|
||||
# record_type = "A"
|
||||
|
||||
## Dns server port.
|
||||
# port = 53
|
||||
|
||||
## Query timeout
|
||||
# timeout = "2s"
|
||||
|
||||
## Include the specified additional properties in the resulting metric.
|
||||
## The following values are supported:
|
||||
## "first_ip" -- return IP of the first A and AAAA answer
|
||||
## "all_ips" -- return IPs of all A and AAAA answers
|
||||
# include_fields = []
|
||||
```
|
||||
|
||||
## Metrics
|
||||
|
||||
- dns_query
|
||||
- tags:
|
||||
- server
|
||||
- domain
|
||||
- record_type
|
||||
- result
|
||||
- rcode
|
||||
- fields:
|
||||
- query_time_ms (float)
|
||||
- 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
|
||||
|
||||
```text
|
||||
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
|
||||
```
|
254
plugins/inputs/dns_query/dns_query.go
Normal file
254
plugins/inputs/dns_query/dns_query.go
Normal file
|
@ -0,0 +1,254 @@
|
|||
//go:generate ../../../tools/readme_config_includer/generator
|
||||
package dns_query
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"slices"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/config"
|
||||
"github.com/influxdata/telegraf/plugins/inputs"
|
||||
)
|
||||
|
||||
//go:embed sample.conf
|
||||
var sampleConfig string
|
||||
|
||||
var ignoredErrors = []string{
|
||||
"NXDOMAIN",
|
||||
}
|
||||
|
||||
type resultType uint64
|
||||
|
||||
const (
|
||||
successResult resultType = iota
|
||||
timeoutResult
|
||||
errorResult
|
||||
)
|
||||
|
||||
type DNSQuery struct {
|
||||
Domains []string `toml:"domains"`
|
||||
Network string `toml:"network"`
|
||||
Servers []string `toml:"servers"`
|
||||
RecordType string `toml:"record_type"`
|
||||
Port int `toml:"port"`
|
||||
Timeout config.Duration `toml:"timeout"`
|
||||
IncludeFields []string `toml:"include_fields"`
|
||||
|
||||
fieldEnabled map[string]bool
|
||||
}
|
||||
|
||||
func (*DNSQuery) SampleConfig() string {
|
||||
return sampleConfig
|
||||
}
|
||||
|
||||
func (d *DNSQuery) Init() error {
|
||||
// Convert the included fields into a lookup-table
|
||||
d.fieldEnabled = make(map[string]bool, len(d.IncludeFields))
|
||||
for _, f := range d.IncludeFields {
|
||||
switch f {
|
||||
case "first_ip", "all_ips":
|
||||
default:
|
||||
return fmt.Errorf("invalid field %q included", f)
|
||||
}
|
||||
d.fieldEnabled[f] = true
|
||||
}
|
||||
|
||||
// Set defaults
|
||||
if d.Network == "" {
|
||||
d.Network = "udp"
|
||||
}
|
||||
|
||||
if d.RecordType == "" {
|
||||
d.RecordType = "NS"
|
||||
}
|
||||
|
||||
if len(d.Domains) == 0 {
|
||||
d.Domains = []string{"."}
|
||||
d.RecordType = "NS"
|
||||
}
|
||||
|
||||
if d.Port < 1 {
|
||||
d.Port = 53
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DNSQuery) Gather(acc telegraf.Accumulator) error {
|
||||
var wg sync.WaitGroup
|
||||
|
||||
for _, domain := range d.Domains {
|
||||
for _, server := range d.Servers {
|
||||
wg.Add(1)
|
||||
go func(domain, server string) {
|
||||
defer wg.Done()
|
||||
|
||||
fields, tags, err := d.query(domain, server)
|
||||
if err != nil && !slices.Contains(ignoredErrors, tags["rcode"]) {
|
||||
var opErr *net.OpError
|
||||
if !errors.As(err, &opErr) || !opErr.Timeout() {
|
||||
acc.AddError(err)
|
||||
}
|
||||
}
|
||||
acc.AddFields("dns_query", fields, tags)
|
||||
}(domain, server)
|
||||
}
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DNSQuery) query(domain, server string) (map[string]interface{}, map[string]string, error) {
|
||||
tags := map[string]string{
|
||||
"server": server,
|
||||
"domain": domain,
|
||||
"record_type": d.RecordType,
|
||||
"result": "error",
|
||||
}
|
||||
|
||||
fields := map[string]interface{}{
|
||||
"query_time_ms": float64(0),
|
||||
"result_code": uint64(errorResult),
|
||||
}
|
||||
|
||||
c := dns.Client{
|
||||
ReadTimeout: time.Duration(d.Timeout),
|
||||
Net: d.Network,
|
||||
}
|
||||
|
||||
recordType, err := d.parseRecordType()
|
||||
if err != nil {
|
||||
return fields, tags, err
|
||||
}
|
||||
|
||||
var msg dns.Msg
|
||||
msg.SetQuestion(dns.Fqdn(domain), recordType)
|
||||
msg.RecursionDesired = true
|
||||
|
||||
addr := net.JoinHostPort(server, strconv.Itoa(d.Port))
|
||||
r, rtt, err := c.Exchange(&msg, addr)
|
||||
if err != nil {
|
||||
var opErr *net.OpError
|
||||
if errors.As(err, &opErr) && opErr.Timeout() {
|
||||
tags["result"] = "timeout"
|
||||
fields["result_code"] = uint64(timeoutResult)
|
||||
return fields, tags, err
|
||||
}
|
||||
return fields, tags, err
|
||||
}
|
||||
|
||||
// Fill valid fields
|
||||
tags["rcode"] = dns.RcodeToString[r.Rcode]
|
||||
fields["rcode_value"] = r.Rcode
|
||||
fields["query_time_ms"] = float64(rtt.Nanoseconds()) / 1e6
|
||||
|
||||
// Handle the failure case
|
||||
if r.Rcode != dns.RcodeSuccess {
|
||||
return fields, tags, fmt.Errorf("invalid answer (%s) from %s after %s query for %s", dns.RcodeToString[r.Rcode], server, d.RecordType, domain)
|
||||
}
|
||||
|
||||
// Success
|
||||
tags["result"] = "success"
|
||||
fields["result_code"] = uint64(successResult)
|
||||
|
||||
// Fill out custom fields for specific record types
|
||||
for _, record := range r.Answer {
|
||||
switch x := record.(type) {
|
||||
case *dns.A:
|
||||
fields["name"] = x.Hdr.Name
|
||||
case *dns.AAAA:
|
||||
fields["name"] = x.Hdr.Name
|
||||
case *dns.CNAME:
|
||||
fields["name"] = x.Hdr.Name
|
||||
case *dns.MX:
|
||||
fields["name"] = x.Hdr.Name
|
||||
fields["preference"] = x.Preference
|
||||
case *dns.SOA:
|
||||
fields["expire"] = x.Expire
|
||||
fields["minttl"] = x.Minttl
|
||||
fields["name"] = x.Hdr.Name
|
||||
fields["refresh"] = x.Refresh
|
||||
fields["retry"] = x.Retry
|
||||
fields["serial"] = x.Serial
|
||||
}
|
||||
}
|
||||
|
||||
if d.fieldEnabled["first_ip"] {
|
||||
for _, record := range r.Answer {
|
||||
if ip, found := extractIP(record); found {
|
||||
fields["ip"] = ip
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if d.fieldEnabled["all_ips"] {
|
||||
for i, record := range r.Answer {
|
||||
if ip, found := extractIP(record); found {
|
||||
fields["ip_"+strconv.Itoa(i)] = ip
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fields, tags, nil
|
||||
}
|
||||
|
||||
func (d *DNSQuery) parseRecordType() (uint16, error) {
|
||||
var recordType uint16
|
||||
var err error
|
||||
|
||||
switch d.RecordType {
|
||||
case "A":
|
||||
recordType = dns.TypeA
|
||||
case "AAAA":
|
||||
recordType = dns.TypeAAAA
|
||||
case "ANY":
|
||||
recordType = dns.TypeANY
|
||||
case "CNAME":
|
||||
recordType = dns.TypeCNAME
|
||||
case "MX":
|
||||
recordType = dns.TypeMX
|
||||
case "NS":
|
||||
recordType = dns.TypeNS
|
||||
case "PTR":
|
||||
recordType = dns.TypePTR
|
||||
case "SOA":
|
||||
recordType = dns.TypeSOA
|
||||
case "SPF":
|
||||
recordType = dns.TypeSPF
|
||||
case "SRV":
|
||||
recordType = dns.TypeSRV
|
||||
case "TXT":
|
||||
recordType = dns.TypeTXT
|
||||
default:
|
||||
err = fmt.Errorf("record type %s not recognized", d.RecordType)
|
||||
}
|
||||
|
||||
return recordType, err
|
||||
}
|
||||
|
||||
func extractIP(record dns.RR) (string, bool) {
|
||||
if r, ok := record.(*dns.A); ok {
|
||||
return r.A.String(), true
|
||||
}
|
||||
if r, ok := record.(*dns.AAAA); ok {
|
||||
return r.AAAA.String(), true
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
func init() {
|
||||
inputs.Add("dns_query", func() telegraf.Input {
|
||||
return &DNSQuery{
|
||||
Timeout: config.Duration(2 * time.Second),
|
||||
}
|
||||
})
|
||||
}
|
284
plugins/inputs/dns_query/dns_query_test.go
Normal file
284
plugins/inputs/dns_query/dns_query_test.go
Normal file
|
@ -0,0 +1,284 @@
|
|||
package dns_query
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/config"
|
||||
"github.com/influxdata/telegraf/metric"
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
)
|
||||
|
||||
var (
|
||||
servers = []string{"8.8.8.8"}
|
||||
domains = []string{"google.com"}
|
||||
)
|
||||
|
||||
func TestGathering(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("Skipping network-dependent test in short mode.")
|
||||
}
|
||||
|
||||
dnsConfig := DNSQuery{
|
||||
Servers: servers,
|
||||
Domains: domains,
|
||||
Timeout: config.Duration(2 * time.Second),
|
||||
}
|
||||
|
||||
var acc testutil.Accumulator
|
||||
require.NoError(t, dnsConfig.Init())
|
||||
require.NoError(t, acc.GatherError(dnsConfig.Gather))
|
||||
m, ok := acc.Get("dns_query")
|
||||
require.True(t, ok)
|
||||
queryTime, ok := m.Fields["query_time_ms"].(float64)
|
||||
require.True(t, ok)
|
||||
require.NotEqual(t, float64(0), queryTime)
|
||||
}
|
||||
|
||||
func TestGatherInvalid(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("Skipping network-dependent test in short mode.")
|
||||
}
|
||||
|
||||
dnsConfig := DNSQuery{
|
||||
Servers: servers,
|
||||
Domains: []string{"qwerty123.example.com"},
|
||||
Timeout: config.Duration(1 * time.Second),
|
||||
}
|
||||
|
||||
var acc testutil.Accumulator
|
||||
require.NoError(t, dnsConfig.Init())
|
||||
require.NoError(t, dnsConfig.Gather(&acc))
|
||||
require.Empty(t, acc.Errors)
|
||||
}
|
||||
|
||||
func TestGatheringMxRecord(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("Skipping network-dependent test in short mode.")
|
||||
}
|
||||
|
||||
dnsConfig := DNSQuery{
|
||||
Servers: servers,
|
||||
Domains: domains,
|
||||
RecordType: "MX",
|
||||
Timeout: config.Duration(2 * time.Second),
|
||||
}
|
||||
var acc testutil.Accumulator
|
||||
|
||||
require.NoError(t, dnsConfig.Init())
|
||||
require.NoError(t, acc.GatherError(dnsConfig.Gather))
|
||||
m, ok := acc.Get("dns_query")
|
||||
require.True(t, ok)
|
||||
queryTime, ok := m.Fields["query_time_ms"].(float64)
|
||||
require.True(t, ok)
|
||||
require.NotEqual(t, float64(0), queryTime)
|
||||
preference, ok := m.Fields["preference"].(uint16)
|
||||
require.True(t, ok)
|
||||
require.NotEqual(t, 0, preference)
|
||||
}
|
||||
|
||||
func TestGatheringRootDomain(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("Skipping network-dependent test in short mode.")
|
||||
}
|
||||
|
||||
dnsConfig := DNSQuery{
|
||||
Servers: servers,
|
||||
Domains: []string{"."},
|
||||
RecordType: "MX",
|
||||
Timeout: config.Duration(2 * time.Second),
|
||||
}
|
||||
require.NoError(t, dnsConfig.Init())
|
||||
|
||||
var acc testutil.Accumulator
|
||||
require.NoError(t, acc.GatherError(dnsConfig.Gather))
|
||||
|
||||
m, ok := acc.Get("dns_query")
|
||||
require.True(t, ok)
|
||||
queryTime, ok := m.Fields["query_time_ms"].(float64)
|
||||
require.True(t, ok)
|
||||
|
||||
expected := []telegraf.Metric{
|
||||
metric.New(
|
||||
"dns_query",
|
||||
map[string]string{
|
||||
"server": "8.8.8.8",
|
||||
"domain": ".",
|
||||
"record_type": "MX",
|
||||
"rcode": "NOERROR",
|
||||
"result": "success",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"rcode_value": 0,
|
||||
"result_code": uint64(0),
|
||||
"query_time_ms": queryTime,
|
||||
},
|
||||
time.Unix(0, 0),
|
||||
),
|
||||
}
|
||||
testutil.RequireMetricsEqual(t, expected, acc.GetTelegrafMetrics(), testutil.IgnoreTime())
|
||||
}
|
||||
|
||||
func TestMetricContainsServerAndDomainAndRecordTypeTags(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("Skipping network-dependent test in short mode.")
|
||||
}
|
||||
|
||||
dnsConfig := DNSQuery{
|
||||
Servers: servers,
|
||||
Domains: domains,
|
||||
Timeout: config.Duration(2 * time.Second),
|
||||
}
|
||||
require.NoError(t, dnsConfig.Init())
|
||||
|
||||
var acc testutil.Accumulator
|
||||
require.NoError(t, acc.GatherError(dnsConfig.Gather))
|
||||
|
||||
m, ok := acc.Get("dns_query")
|
||||
require.True(t, ok)
|
||||
queryTime, ok := m.Fields["query_time_ms"].(float64)
|
||||
require.True(t, ok)
|
||||
expected := []telegraf.Metric{
|
||||
metric.New(
|
||||
"dns_query",
|
||||
map[string]string{
|
||||
"server": "8.8.8.8",
|
||||
"domain": "google.com",
|
||||
"record_type": "NS",
|
||||
"rcode": "NOERROR",
|
||||
"result": "success",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"rcode_value": 0,
|
||||
"result_code": uint64(0),
|
||||
"query_time_ms": queryTime,
|
||||
},
|
||||
time.Unix(0, 0),
|
||||
),
|
||||
}
|
||||
testutil.RequireMetricsEqual(t, expected, acc.GetTelegrafMetrics(), testutil.IgnoreTime())
|
||||
}
|
||||
|
||||
func TestGatheringTimeout(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("Skipping network-dependent test in short mode.")
|
||||
}
|
||||
|
||||
dnsConfig := DNSQuery{
|
||||
Servers: servers,
|
||||
Domains: domains,
|
||||
Timeout: config.Duration(1 * time.Second),
|
||||
Port: 60054,
|
||||
}
|
||||
require.NoError(t, dnsConfig.Init())
|
||||
|
||||
var acc testutil.Accumulator
|
||||
channel := make(chan error, 1)
|
||||
go func() {
|
||||
channel <- acc.GatherError(dnsConfig.Gather)
|
||||
}()
|
||||
select {
|
||||
case err := <-channel:
|
||||
require.NoError(t, err)
|
||||
case <-time.After(time.Second * 2):
|
||||
require.Fail(t, "DNS query did not timeout")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSettingDefaultValues(t *testing.T) {
|
||||
dnsConfig := DNSQuery{
|
||||
Timeout: config.Duration(2 * time.Second),
|
||||
}
|
||||
require.NoError(t, dnsConfig.Init())
|
||||
require.Equal(t, []string{"."}, dnsConfig.Domains, "Default domain not equal \".\"")
|
||||
require.Equal(t, "NS", dnsConfig.RecordType, "Default record type not equal 'NS'")
|
||||
require.Equal(t, 53, dnsConfig.Port, "Default port number not equal 53")
|
||||
require.Equal(t, config.Duration(2*time.Second), dnsConfig.Timeout, "Default timeout not equal 2s")
|
||||
|
||||
dnsConfig = DNSQuery{
|
||||
Domains: []string{"."},
|
||||
Timeout: config.Duration(2 * time.Second),
|
||||
}
|
||||
require.NoError(t, dnsConfig.Init())
|
||||
require.Equal(t, "NS", dnsConfig.RecordType, "Default record type not equal 'NS'")
|
||||
}
|
||||
|
||||
func TestRecordTypeParser(t *testing.T) {
|
||||
tests := []struct {
|
||||
record string
|
||||
expected uint16
|
||||
}{
|
||||
{
|
||||
record: "A",
|
||||
expected: dns.TypeA,
|
||||
},
|
||||
{
|
||||
record: "AAAA",
|
||||
expected: dns.TypeAAAA,
|
||||
},
|
||||
{
|
||||
record: "ANY",
|
||||
expected: dns.TypeANY,
|
||||
},
|
||||
{
|
||||
record: "CNAME",
|
||||
expected: dns.TypeCNAME,
|
||||
},
|
||||
{
|
||||
record: "MX",
|
||||
expected: dns.TypeMX,
|
||||
},
|
||||
{
|
||||
record: "NS",
|
||||
expected: dns.TypeNS,
|
||||
},
|
||||
{
|
||||
record: "PTR",
|
||||
expected: dns.TypePTR,
|
||||
},
|
||||
{
|
||||
record: "SOA",
|
||||
expected: dns.TypeSOA,
|
||||
},
|
||||
{
|
||||
record: "SPF",
|
||||
expected: dns.TypeSPF,
|
||||
},
|
||||
{
|
||||
record: "SRV",
|
||||
expected: dns.TypeSRV,
|
||||
},
|
||||
{
|
||||
record: "TXT",
|
||||
expected: dns.TypeTXT,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.record, func(t *testing.T) {
|
||||
plugin := DNSQuery{
|
||||
Timeout: config.Duration(2 * time.Second),
|
||||
Domains: []string{"example.com"},
|
||||
RecordType: tt.record,
|
||||
}
|
||||
require.NoError(t, plugin.Init())
|
||||
recordType, err := plugin.parseRecordType()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tt.expected, recordType)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRecordTypeParserError(t *testing.T) {
|
||||
plugin := DNSQuery{
|
||||
Timeout: config.Duration(2 * time.Second),
|
||||
RecordType: "nil",
|
||||
}
|
||||
|
||||
_, err := plugin.parseRecordType()
|
||||
require.Error(t, err)
|
||||
}
|
26
plugins/inputs/dns_query/sample.conf
Normal file
26
plugins/inputs/dns_query/sample.conf
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Query given DNS server and gives statistics
|
||||
[[inputs.dns_query]]
|
||||
## servers to query
|
||||
servers = ["8.8.8.8"]
|
||||
|
||||
## Network is the network protocol name.
|
||||
# network = "udp"
|
||||
|
||||
## Domains or subdomains to query.
|
||||
# domains = ["."]
|
||||
|
||||
## Query record type.
|
||||
## Possible values: A, AAAA, CNAME, MX, NS, PTR, TXT, SOA, SPF, SRV.
|
||||
# record_type = "A"
|
||||
|
||||
## Dns server port.
|
||||
# port = 53
|
||||
|
||||
## Query timeout
|
||||
# timeout = "2s"
|
||||
|
||||
## Include the specified additional properties in the resulting metric.
|
||||
## The following values are supported:
|
||||
## "first_ip" -- return IP of the first A and AAAA answer
|
||||
## "all_ips" -- return IPs of all A and AAAA answers
|
||||
# include_fields = []
|
Loading…
Add table
Add a link
Reference in a new issue