Add probe_dns_query_succeeded metric
authorDaniel Teunis <daniel@teunis.cc>
Fri, 25 Nov 2022 23:05:59 +0000 (00:05 +0100)
committerDaniel Teunis <daniel@teunis.cc>
Sat, 26 Nov 2022 18:53:22 +0000 (19:53 +0100)
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 <daniel@teunis.cc>
prober/dns.go
prober/dns_test.go

index 8e8a1b59c8f2231ad30fcf6fcdf89bc4361e9305..6bf2e46500c5b9e300ef72afe197230ad2c57d1e 100644 (file)
@@ -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{
index 73385ae1a7fd9b39956b464a19d4ecf519593f6e..22f702cf2cb4391a047bf1c267c9eec9ba8c738b 100644 (file)
@@ -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)