From a1beb07ee0f587819cd2444cc2ab9bba9625c778 Mon Sep 17 00:00:00 2001 From: Daniel Santos Date: Wed, 2 Oct 2024 16:24:29 -0600 Subject: [PATCH] feat(metrics): Add URL to metrics labels --- metrics/metrics.go | 27 +++++++++++++++----------- metrics/metrics_test.go | 42 ++++++++++++++++++++--------------------- 2 files changed, 37 insertions(+), 32 deletions(-) diff --git a/metrics/metrics.go b/metrics/metrics.go index 42600c4b..5b91fccf 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -25,27 +25,27 @@ func initializePrometheusMetrics() { Namespace: namespace, Name: "results_total", Help: "Number of results per endpoint", - }, []string{"key", "group", "name", "type", "success"}) + }, []string{"key", "group", "name", "type", "success", "url"}) resultDurationSeconds = promauto.NewGaugeVec(prometheus.GaugeOpts{ Namespace: namespace, Name: "results_duration_seconds", Help: "Duration of the request in seconds", - }, []string{"key", "group", "name", "type"}) + }, []string{"key", "group", "name", "type", "url"}) resultConnectedTotal = promauto.NewCounterVec(prometheus.CounterOpts{ Namespace: namespace, Name: "results_connected_total", Help: "Total number of results in which a connection was successfully established", - }, []string{"key", "group", "name", "type"}) + }, []string{"key", "group", "name", "type", "url"}) resultCodeTotal = promauto.NewCounterVec(prometheus.CounterOpts{ Namespace: namespace, Name: "results_code_total", Help: "Total number of results by code", - }, []string{"key", "group", "name", "type", "code"}) + }, []string{"key", "group", "name", "type", "code", "url"}) resultCertificateExpirationSeconds = promauto.NewGaugeVec(prometheus.GaugeOpts{ Namespace: namespace, Name: "results_certificate_expiration_seconds", Help: "Number of seconds until the certificate expires", - }, []string{"key", "group", "name", "type"}) + }, []string{"key", "group", "name", "type", "url"}) } // PublishMetricsForEndpoint publishes metrics for the given endpoint and its result. @@ -56,18 +56,23 @@ func PublishMetricsForEndpoint(ep *endpoint.Endpoint, result *endpoint.Result) { initializedMetrics = true } endpointType := ep.Type() - resultTotal.WithLabelValues(ep.Key(), ep.Group, ep.Name, string(endpointType), strconv.FormatBool(result.Success)).Inc() - resultDurationSeconds.WithLabelValues(ep.Key(), ep.Group, ep.Name, string(endpointType)).Set(result.Duration.Seconds()) + resultTotal.WithLabelValues(ep.Key(), ep.Group, ep.Name, string(endpointType), strconv.FormatBool(result.Success), ep.URL).Inc() + resultDurationSeconds.WithLabelValues(ep.Key(), ep.Group, ep.Name, string(endpointType), ep.URL).Set(result.Duration.Seconds()) if result.Connected { - resultConnectedTotal.WithLabelValues(ep.Key(), ep.Group, ep.Name, string(endpointType)).Inc() + switch endpointType { + case endpoint.TypeDNS: + resultConnectedTotal.WithLabelValues(ep.Key(), ep.Group, ep.Name, string(endpointType), ep.DNSConfig.QueryName).Inc() + default: + resultConnectedTotal.WithLabelValues(ep.Key(), ep.Group, ep.Name, string(endpointType), ep.URL).Inc() + } } if result.DNSRCode != "" { - resultCodeTotal.WithLabelValues(ep.Key(), ep.Group, ep.Name, string(endpointType), result.DNSRCode).Inc() + resultCodeTotal.WithLabelValues(ep.Key(), ep.Group, ep.Name, string(endpointType), result.DNSRCode, ep.DNSConfig.QueryName).Inc() } if result.HTTPStatus != 0 { - resultCodeTotal.WithLabelValues(ep.Key(), ep.Group, ep.Name, string(endpointType), strconv.Itoa(result.HTTPStatus)).Inc() + resultCodeTotal.WithLabelValues(ep.Key(), ep.Group, ep.Name, string(endpointType), strconv.Itoa(result.HTTPStatus), ep.URL).Inc() } if result.CertificateExpiration != 0 { - resultCertificateExpirationSeconds.WithLabelValues(ep.Key(), ep.Group, ep.Name, string(endpointType)).Set(result.CertificateExpiration.Seconds()) + resultCertificateExpirationSeconds.WithLabelValues(ep.Key(), ep.Group, ep.Name, string(endpointType), ep.URL).Set(result.CertificateExpiration.Seconds()) } } diff --git a/metrics/metrics_test.go b/metrics/metrics_test.go index ecc1602a..04367cb9 100644 --- a/metrics/metrics_test.go +++ b/metrics/metrics_test.go @@ -27,19 +27,19 @@ func TestPublishMetricsForEndpoint(t *testing.T) { err := testutil.GatherAndCompare(prometheus.Gatherers{prometheus.DefaultGatherer}, bytes.NewBufferString(` # HELP gatus_results_certificate_expiration_seconds Number of seconds until the certificate expires # TYPE gatus_results_certificate_expiration_seconds gauge -gatus_results_certificate_expiration_seconds{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",type="HTTP"} 176400 +gatus_results_certificate_expiration_seconds{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",type="HTTP",url="https://example.org"} 176400 # HELP gatus_results_code_total Total number of results by code # TYPE gatus_results_code_total counter -gatus_results_code_total{code="200",group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",type="HTTP"} 1 +gatus_results_code_total{code="200",group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",type="HTTP",url="https://example.org"} 1 # HELP gatus_results_connected_total Total number of results in which a connection was successfully established # TYPE gatus_results_connected_total counter -gatus_results_connected_total{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",type="HTTP"} 1 +gatus_results_connected_total{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",type="HTTP",url="https://example.org"} 1 # HELP gatus_results_duration_seconds Duration of the request in seconds # TYPE gatus_results_duration_seconds gauge -gatus_results_duration_seconds{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",type="HTTP"} 0.123 +gatus_results_duration_seconds{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",type="HTTP",url="https://example.org"} 0.123 # HELP gatus_results_total Number of results per endpoint # TYPE gatus_results_total counter -gatus_results_total{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",success="true",type="HTTP"} 1 +gatus_results_total{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",success="true",type="HTTP",url="https://example.org"} 1 `), "gatus_results_code_total", "gatus_results_connected_total", "gatus_results_duration_seconds", "gatus_results_total", "gatus_results_certificate_expiration_seconds") if err != nil { t.Errorf("Expected no errors but got: %v", err) @@ -58,20 +58,20 @@ gatus_results_total{group="http-ep-group",key="http-ep-group_http-ep-name",name= err = testutil.GatherAndCompare(prometheus.Gatherers{prometheus.DefaultGatherer}, bytes.NewBufferString(` # HELP gatus_results_certificate_expiration_seconds Number of seconds until the certificate expires # TYPE gatus_results_certificate_expiration_seconds gauge -gatus_results_certificate_expiration_seconds{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",type="HTTP"} 169200 +gatus_results_certificate_expiration_seconds{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",type="HTTP",url="https://example.org"} 169200 # HELP gatus_results_code_total Total number of results by code # TYPE gatus_results_code_total counter -gatus_results_code_total{code="200",group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",type="HTTP"} 2 +gatus_results_code_total{code="200",group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",type="HTTP",url="https://example.org"} 2 # HELP gatus_results_connected_total Total number of results in which a connection was successfully established # TYPE gatus_results_connected_total counter -gatus_results_connected_total{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",type="HTTP"} 2 +gatus_results_connected_total{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",type="HTTP",url="https://example.org"} 2 # HELP gatus_results_duration_seconds Duration of the request in seconds # TYPE gatus_results_duration_seconds gauge -gatus_results_duration_seconds{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",type="HTTP"} 0.125 +gatus_results_duration_seconds{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",type="HTTP",url="https://example.org"} 0.125 # HELP gatus_results_total Number of results per endpoint # TYPE gatus_results_total counter -gatus_results_total{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",success="false",type="HTTP"} 1 -gatus_results_total{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",success="true",type="HTTP"} 1 +gatus_results_total{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",success="false",type="HTTP",url="https://example.org"} 1 +gatus_results_total{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",success="true",type="HTTP",url="https://example.org"} 1 `), "gatus_results_code_total", "gatus_results_connected_total", "gatus_results_duration_seconds", "gatus_results_total", "gatus_results_certificate_expiration_seconds") if err != nil { t.Errorf("Expected no errors but got: %v", err) @@ -92,24 +92,24 @@ gatus_results_total{group="http-ep-group",key="http-ep-group_http-ep-name",name= err = testutil.GatherAndCompare(prometheus.Gatherers{prometheus.DefaultGatherer}, bytes.NewBufferString(` # HELP gatus_results_certificate_expiration_seconds Number of seconds until the certificate expires # TYPE gatus_results_certificate_expiration_seconds gauge -gatus_results_certificate_expiration_seconds{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",type="HTTP"} 169200 +gatus_results_certificate_expiration_seconds{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",type="HTTP",url="https://example.org"} 169200 # HELP gatus_results_code_total Total number of results by code # TYPE gatus_results_code_total counter -gatus_results_code_total{code="200",group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",type="HTTP"} 2 -gatus_results_code_total{code="NOERROR",group="dns-ep-group",key="dns-ep-group_dns-ep-name",name="dns-ep-name",type="DNS"} 1 +gatus_results_code_total{code="200",group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",type="HTTP",url="https://example.org"} 2 +gatus_results_code_total{code="NOERROR",group="dns-ep-group",key="dns-ep-group_dns-ep-name",name="dns-ep-name",type="DNS",url="example.com."} 1 # HELP gatus_results_connected_total Total number of results in which a connection was successfully established # TYPE gatus_results_connected_total counter -gatus_results_connected_total{group="dns-ep-group",key="dns-ep-group_dns-ep-name",name="dns-ep-name",type="DNS"} 1 -gatus_results_connected_total{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",type="HTTP"} 2 +gatus_results_connected_total{group="dns-ep-group",key="dns-ep-group_dns-ep-name",name="dns-ep-name",type="DNS",url="example.com."} 1 +gatus_results_connected_total{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",type="HTTP",url="https://example.org"} 2 # HELP gatus_results_duration_seconds Duration of the request in seconds # TYPE gatus_results_duration_seconds gauge -gatus_results_duration_seconds{group="dns-ep-group",key="dns-ep-group_dns-ep-name",name="dns-ep-name",type="DNS"} 0.05 -gatus_results_duration_seconds{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",type="HTTP"} 0.125 +gatus_results_duration_seconds{group="dns-ep-group",key="dns-ep-group_dns-ep-name",name="dns-ep-name",type="DNS",url="8.8.8.8"} 0.05 +gatus_results_duration_seconds{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",type="HTTP",url="https://example.org"} 0.125 # HELP gatus_results_total Number of results per endpoint # TYPE gatus_results_total counter -gatus_results_total{group="dns-ep-group",key="dns-ep-group_dns-ep-name",name="dns-ep-name",success="true",type="DNS"} 1 -gatus_results_total{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",success="false",type="HTTP"} 1 -gatus_results_total{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",success="true",type="HTTP"} 1 +gatus_results_total{group="dns-ep-group",key="dns-ep-group_dns-ep-name",name="dns-ep-name",success="true",type="DNS",url="8.8.8.8"} 1 +gatus_results_total{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",success="false",type="HTTP",url="https://example.org"} 1 +gatus_results_total{group="http-ep-group",key="http-ep-group_http-ep-name",name="http-ep-name",success="true",type="HTTP",url="https://example.org"} 1 `), "gatus_results_code_total", "gatus_results_connected_total", "gatus_results_duration_seconds", "gatus_results_total", "gatus_results_certificate_expiration_seconds") if err != nil { t.Errorf("Expected no errors but got: %v", err)