]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Refactor prometheus output for histograms
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 9 Jan 2026 14:12:18 +0000 (15:12 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 9 Jan 2026 14:32:56 +0000 (15:32 +0100)
Signed-off-by: Remi Gacogne <remi.gacogne@powerdns.com>
pdns/dnsdistdist/dnsdist-web.cc

index 92a8a79abc003630c3cb59ee53460491a60d1428..3f90fb8e673b80ab5a0b2df63af107d6bca4fb08 100644 (file)
@@ -463,6 +463,28 @@ static void addRulesToPrometheusOutput(std::ostringstream& output, const std::ve
   }
 }
 
+template <class T>
+static void addHistogramToPrometheusOutput(std::ostringstream& output, const T& container, const std::string& metricName, const std::string& label)
+{
+  const std::string latency_label_prefix{label.empty() ? "{" : (label.substr(0, label.size() - 1) + ",")};
+  uint64_t amount = 0;
+  amount += container.latency0_1;
+  output << metricName << "_bucket" << latency_label_prefix << "le=\"1\"} " << amount << "\n";
+  amount += container.latency1_10;
+  output << metricName << "_bucket" << latency_label_prefix << "le=\"10\"} " << amount << "\n";
+  amount += container.latency10_50;
+  output << metricName << "_bucket" << latency_label_prefix << "le=\"50\"} " << amount << "\n";
+  amount += container.latency50_100;
+  output << metricName << "_bucket" << latency_label_prefix << "le=\"100\"} " << amount << "\n";
+  amount += container.latency100_1000;
+  output << metricName << "_bucket" << latency_label_prefix << "le=\"1000\"} " << amount << "\n";
+  amount += container.latencySlow;
+  output << metricName << "_bucket" << latency_label_prefix << "le=\"+Inf\"} " << amount << "\n";
+
+  output << metricName << "_sum" << label << " " << container.latencySum << "\n";
+  output << metricName << "_count" << label << " " << container.latencyCount << "\n";
+}
+
 static void handlePrometheus(const YaHTTP::Request& req, YaHTTP::Response& resp)
 {
   handleCORS(req, resp);
@@ -532,20 +554,7 @@ static void handlePrometheus(const YaHTTP::Request& req, YaHTTP::Response& resp)
   // Latency histogram buckets
   output << "# HELP dnsdist_latency Histogram of responses by latency (in milliseconds)\n";
   output << "# TYPE dnsdist_latency histogram\n";
-  uint64_t latency_amounts = dnsdist::metrics::g_stats.latency0_1;
-  output << "dnsdist_latency_bucket{le=\"1\"} " << latency_amounts << "\n";
-  latency_amounts += dnsdist::metrics::g_stats.latency1_10;
-  output << "dnsdist_latency_bucket{le=\"10\"} " << latency_amounts << "\n";
-  latency_amounts += dnsdist::metrics::g_stats.latency10_50;
-  output << "dnsdist_latency_bucket{le=\"50\"} " << latency_amounts << "\n";
-  latency_amounts += dnsdist::metrics::g_stats.latency50_100;
-  output << "dnsdist_latency_bucket{le=\"100\"} " << latency_amounts << "\n";
-  latency_amounts += dnsdist::metrics::g_stats.latency100_1000;
-  output << "dnsdist_latency_bucket{le=\"1000\"} " << latency_amounts << "\n";
-  latency_amounts += dnsdist::metrics::g_stats.latencySlow; // Should be the same as latency_count
-  output << "dnsdist_latency_bucket{le=\"+Inf\"} " << latency_amounts << "\n";
-  output << "dnsdist_latency_sum " << dnsdist::metrics::g_stats.latencySum << "\n";
-  output << "dnsdist_latency_count " << dnsdist::metrics::g_stats.latencyCount << "\n";
+  addHistogramToPrometheusOutput(output, dnsdist::metrics::g_stats, "dnsdist_latency", "");
 
   const string statesbase = "dnsdist_server_";
 
@@ -669,26 +678,7 @@ static void handlePrometheus(const YaHTTP::Request& req, YaHTTP::Response& resp)
     output << statesbase << "healthchecklatency"               << label << " " << state->d_healthCheckLatency / 1000.0   << "\n";
 
     // Health-check latency histogram
-    const std::string latency_label_prefix = boost::str(boost::format(R"({server="%1%",address="%2%")")
-                                                        % serverName % state->d_config.remote.toStringWithPort());
-    uint64_t backend_latency_amount = 0;
-    backend_latency_amount += state->d_healthCheckLatencyHisto.latency0_1;
-    output << statesbase << "healthchecklatency_histo_bucket" << latency_label_prefix << ",le=\"1\"} " << backend_latency_amount << "\n";
-    backend_latency_amount += state->d_healthCheckLatencyHisto.latency1_10;
-    output << statesbase << "healthchecklatency_histo_bucket" << latency_label_prefix << ",le=\"10\"} " << backend_latency_amount << "\n";
-    backend_latency_amount += state->d_healthCheckLatencyHisto.latency10_50;
-    output << statesbase << "healthchecklatency_histo_bucket" << latency_label_prefix << ",le=\"50\"} " << backend_latency_amount << "\n";
-    backend_latency_amount += state->d_healthCheckLatencyHisto.latency10_50;
-    output << statesbase << "healthchecklatency_histo_bucket" << latency_label_prefix << ",le=\"50\"} " << backend_latency_amount << "\n";
-    backend_latency_amount += state->d_healthCheckLatencyHisto.latency50_100;
-    output << statesbase << "healthchecklatency_histo_bucket" << latency_label_prefix << ",le=\"100\"} " << backend_latency_amount << "\n";
-    backend_latency_amount += state->d_healthCheckLatencyHisto.latency100_1000;
-    output << statesbase << "healthchecklatency_histo_bucket" << latency_label_prefix << ",le=\"1000\"} " << backend_latency_amount << "\n";
-    backend_latency_amount += state->d_healthCheckLatencyHisto.latencySlow;
-    output << statesbase << "healthchecklatency_histo_bucket" << latency_label_prefix << ",le=\"+Inf\"} " << backend_latency_amount << "\n";
-
-    output << statesbase << "healthchecklatency_histo_sum" << label << " " << state->d_healthCheckLatencyHisto.latencySum << "\n";
-    output << statesbase << "healthchecklatency_histo_count" << label << " " << state->d_healthCheckLatencyHisto.latencyCount << "\n";
+    addHistogramToPrometheusOutput(output, state->d_healthCheckLatencyHisto, statesbase + "healthchecklatency_histo", label);
   }
 
   const string frontsbase = "dnsdist_frontend_";