From 449e0d7f213564c5d2e5c3c2c4a9e30e998c50cd Mon Sep 17 00:00:00 2001 From: Daniel Teunis Date: Sat, 26 Nov 2022 00:05:59 +0100 Subject: [PATCH] Add probe_dns_query_succeeded metric Currently, one may not be able to differentiate between a query refusal by the target and the target not responding to a query. These two cases can have very different ramifications. This patch adds the probe_dns_query_succeeded gauge which is 1 if and only if the DNS query was executed correctly, i.e., that the target host has sent a response, and 0 otherwise. Resolves #474 Signed-off-by: Daniel Teunis --- prober/dns.go | 6 ++++++ prober/dns_test.go | 34 ++++++++++++++++++++++------------ 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/prober/dns.go b/prober/dns.go index 8e8a1b5..6bf2e46 100644 --- a/prober/dns.go +++ b/prober/dns.go @@ -142,6 +142,10 @@ func ProbeDNS(ctx context.Context, target string, module config.Module, registry Name: "probe_dns_additional_rrs", Help: "Returns number of entries in the additional resource record list", }) + probeDNSQuerySucceeded := prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "probe_dns_query_succeeded", + Help: "Displays whether or not the query was executed successfully", + }) for _, lv := range []string{"resolve", "connect", "request"} { probeDNSDurationGaugeVec.WithLabelValues(lv) @@ -151,6 +155,7 @@ func ProbeDNS(ctx context.Context, target string, module config.Module, registry registry.MustRegister(probeDNSAnswerRRSGauge) registry.MustRegister(probeDNSAuthorityRRSGauge) registry.MustRegister(probeDNSAdditionalRRSGauge) + registry.MustRegister(probeDNSQuerySucceeded) qc := uint16(dns.ClassINET) if module.DNS.QueryClass != "" { @@ -274,6 +279,7 @@ func ProbeDNS(ctx context.Context, target string, module config.Module, registry probeDNSAnswerRRSGauge.Set(float64(len(response.Answer))) probeDNSAuthorityRRSGauge.Set(float64(len(response.Ns))) probeDNSAdditionalRRSGauge.Set(float64(len(response.Extra))) + probeDNSQuerySucceeded.Set(1) if qt == dns.TypeSOA { probeDNSSOAGauge = prometheus.NewGauge(prometheus.GaugeOpts{ diff --git a/prober/dns_test.go b/prober/dns_test.go index 73385ae..22f702c 100644 --- a/prober/dns_test.go +++ b/prober/dns_test.go @@ -179,9 +179,10 @@ func TestRecursiveDNSResponse(t *testing.T) { t.Fatal(err) } expectedResults := map[string]float64{ - "probe_dns_answer_rrs": 2, - "probe_dns_authority_rrs": 0, - "probe_dns_additional_rrs": 0, + "probe_dns_answer_rrs": 2, + "probe_dns_authority_rrs": 0, + "probe_dns_additional_rrs": 0, + "probe_dns_query_succeeded": 1, } if !test.Probe.Recursion { expectedResults["probe_dns_answer_rrs"] = 0 @@ -382,9 +383,10 @@ func TestAuthoritativeDNSResponse(t *testing.T) { t.Fatal(err) } expectedResults := map[string]float64{ - "probe_dns_answer_rrs": 1, - "probe_dns_authority_rrs": 2, - "probe_dns_additional_rrs": 3, + "probe_dns_answer_rrs": 1, + "probe_dns_authority_rrs": 2, + "probe_dns_additional_rrs": 3, + "probe_dns_query_succeeded": 1, } if test.Probe.QueryType == "SOA" { expectedResults["probe_dns_serial"] = 1000 @@ -456,10 +458,17 @@ func TestServfailDNSResponse(t *testing.T) { t.Fatal(err) } expectedResults := map[string]float64{ - "probe_dns_answer_rrs": 0, - "probe_dns_authority_rrs": 0, - "probe_dns_additional_rrs": 0, + "probe_dns_answer_rrs": 0, + "probe_dns_authority_rrs": 0, + "probe_dns_additional_rrs": 0, + "probe_dns_query_succeeded": 1, } + + // Handle case where ProbeDNS fails before executing the query because of an invalid query type + if test.Probe.QueryType == "NOT_A_VALID_QUERY_TYPE" { + expectedResults["probe_dns_query_succeeded"] = 0 + } + checkRegistryResults(expectedResults, mfs, t) } } @@ -638,9 +647,10 @@ func TestDNSMetrics(t *testing.T) { "request": {}, }, }, - "probe_dns_answer_rrs": nil, - "probe_dns_authority_rrs": nil, - "probe_dns_additional_rrs": nil, + "probe_dns_answer_rrs": nil, + "probe_dns_authority_rrs": nil, + "probe_dns_additional_rrs": nil, + "probe_dns_query_succeeded": nil, } checkMetrics(expectedMetrics, mfs, t) -- 2.25.1