github.com/netdata/go.d.plugin@v0.58.1/modules/dnsquery/collect.go (about) 1 // SPDX-License-Identifier: GPL-3.0-or-later 2 3 package dnsquery 4 5 import ( 6 "math/rand" 7 "net" 8 "strconv" 9 "sync" 10 "time" 11 12 "github.com/miekg/dns" 13 ) 14 15 func (d *DNSQuery) collect() (map[string]int64, error) { 16 if d.dnsClient == nil { 17 d.dnsClient = d.newDNSClient(d.Network, d.Timeout.Duration) 18 } 19 20 mx := make(map[string]int64) 21 domain := randomDomain(d.Domains) 22 d.Debugf("current domain : %s", domain) 23 24 var wg sync.WaitGroup 25 var mux sync.RWMutex 26 for _, srv := range d.Servers { 27 for rtypeName, rtype := range d.recordTypes { 28 wg.Add(1) 29 go func(srv, rtypeName string, rtype uint16, wg *sync.WaitGroup) { 30 defer wg.Done() 31 32 msg := new(dns.Msg) 33 msg.SetQuestion(dns.Fqdn(domain), rtype) 34 address := net.JoinHostPort(srv, strconv.Itoa(d.Port)) 35 36 resp, rtt, err := d.dnsClient.Exchange(msg, address) 37 38 mux.Lock() 39 defer mux.Unlock() 40 41 px := "server_" + srv + "_record_" + rtypeName + "_" 42 43 mx[px+"query_status_success"] = 0 44 mx[px+"query_status_network_error"] = 0 45 mx[px+"query_status_dns_error"] = 0 46 47 if err != nil { 48 d.Debugf("error on querying %s after %s query for %s : %s", srv, rtypeName, domain, err) 49 mx[px+"query_status_network_error"] = 1 50 return 51 } 52 53 if resp != nil && resp.Rcode != dns.RcodeSuccess { 54 d.Debugf("invalid answer from %s after %s query for %s (rcode %d)", srv, rtypeName, domain, resp.Rcode) 55 mx[px+"query_status_dns_error"] = 1 56 } else { 57 mx[px+"query_status_success"] = 1 58 } 59 mx["server_"+srv+"_record_"+rtypeName+"_query_time"] = rtt.Nanoseconds() 60 61 }(srv, rtypeName, rtype, &wg) 62 } 63 } 64 wg.Wait() 65 66 return mx, nil 67 } 68 69 func randomDomain(domains []string) string { 70 src := rand.NewSource(time.Now().UnixNano()) 71 r := rand.New(src) 72 return domains[r.Intn(len(domains))] 73 }