]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: also register custom metrics to prometheus
authorCharles-Henri Bruyand <charles-henri.bruyand@open-xchange.com>
Thu, 2 Jun 2022 14:30:05 +0000 (16:30 +0200)
committerCharles-Henri Bruyand <charles-henri.bruyand@open-xchange.com>
Thu, 2 Jun 2022 14:30:05 +0000 (16:30 +0200)
pdns/dnsdist-lua.cc
pdns/dnsdist-web.cc
pdns/dnsdistdist/dnsdist-prometheus.hh
pdns/dnsdistdist/dnsdist-web.hh
pdns/dnsdistdist/docs/reference/custommetrics.rst
regression-tests.dnsdist/test_API.py
regression-tests.dnsdist/test_Advanced.py

index 64c06ee9b1e2220e4394a7d775aedaf570c79ce1..9ccec6a624045b1ae583b7eae8a0712213f934a8 100644 (file)
@@ -2863,7 +2863,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
     newThread.detach();
   });
 
-  luaCtx.writeFunction("declareMetric", [](const std::string& name, const std::string& type) {
+  luaCtx.writeFunction("declareMetric", [](const std::string& name, const std::string& type, const std::string& description) {
     if (g_configurationDone) {
       g_outputBuffer = "declareMetric cannot be used at runtime!\n";
       return false;
@@ -2877,11 +2877,13 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
       auto itp = g_stats.customCounters.emplace(name, 0);
       if (itp.second) {
         g_stats.entries.emplace_back(name, &g_stats.customCounters[name]);
+        addMetricDefinition(name, "counter", description);
       }
     } else if (type == "gauge") {
       auto itp = g_stats.customGauges.emplace(name, 0.);
       if (itp.second) {
         g_stats.entries.emplace_back(name, &g_stats.customGauges[name]);
+        addMetricDefinition(name, "gauge", description);
       }
     } else {
       g_outputBuffer = "declareMetric unknown type '" + type + "'\n";
index 9407c5523ba75400abb7343e9c9316e1c8da333b..e0f11da9a480fad9a3ef15ae873a2913fc527465 100644 (file)
@@ -131,9 +131,9 @@ private:
 };
 
 #ifndef DISABLE_PROMETHEUS
-static const MetricDefinitionStorage s_metricDefinitions;
+static MetricDefinitionStorage s_metricDefinitions;
 
-const std::map<std::string, MetricDefinition> MetricDefinitionStorage::metrics{
+std::map<std::string, MetricDefinition> MetricDefinitionStorage::metrics{
   { "responses",                             MetricDefinition(PrometheusMetricType::counter, "Number of responses received from backends") },
   { "servfail-responses",                    MetricDefinition(PrometheusMetricType::counter, "Number of SERVFAIL answers received from backends") },
   { "queries",                               MetricDefinition(PrometheusMetricType::counter, "Number of received queries")},
@@ -198,6 +198,14 @@ const std::map<std::string, MetricDefinition> MetricDefinitionStorage::metrics{
 };
 #endif /* DISABLE_PROMETHEUS */
 
+bool addMetricDefinition(const std::string& name, const std::string type, const std::string& description) {
+#ifndef DISABLE_PROMETHEUS
+  return MetricDefinitionStorage::addMetricDefinition(name, type, description);
+#else
+  return true;
+#endif /* DISABLE_PROMETHEUS */
+}
+
 #ifndef DISABLE_WEB_CONFIG
 static bool apiWriteConfigFile(const string& filebasename, const string& content)
 {
index 43bd6b3d50e0e7d235f0a9cba49d4be6e6809104..dbbfa1d0114ee4e4de752e7b09e91b46a8a254b8 100644 (file)
@@ -54,6 +54,19 @@ struct MetricDefinitionStorage {
     return true;
   };
 
+  static bool addMetricDefinition(const std::string& name, const std::string type, const std::string& description) {
+    static const std::map<std::string, PrometheusMetricType> namesToTypes = {
+      {"counter", PrometheusMetricType::counter},
+      {"gauge",   PrometheusMetricType::gauge},
+    };
+    auto realtype = namesToTypes.find(type);
+    if (realtype == namesToTypes.end()) {
+      return false;
+    }
+    metrics.emplace(name, MetricDefinition{realtype->second, description});
+    return true;
+  }
+
   // Return string representation of Prometheus metric type
   std::string getPrometheusStringMetricType(PrometheusMetricType metricType) const {
     switch (metricType) {
@@ -69,6 +82,6 @@ struct MetricDefinitionStorage {
     }
   };
 
-  static const std::map<std::string, MetricDefinition> metrics;
+  static std::map<std::string, MetricDefinition> metrics;
 };
 #endif /* DISABLE_PROMETHEUS */
index e33469a9cd6358f5a8bf8ca60794395e6d9dd2e0..3e19b5716fdc3e0488a447e785ce20c39b6fbc8a 100644 (file)
@@ -15,4 +15,6 @@ void dnsdistWebserverThread(int sock, const ComboAddress& local);
 void registerBuiltInWebHandlers();
 void clearWebHandlers();
 
+bool addMetricDefinition(const std::string& name, const std::string type, const std::string& description);
+
 std::string getWebserverConfig();
index c29cfd091190ae9cd568f47dc577b7bf4dbd1fb7..0e44c345bd5c80f121755e34db9dfa6e5d144fe8 100644 (file)
@@ -10,7 +10,7 @@ Then you can update those at runtime using the following functions, depending on
  * manipulate counters using :func:`incMetric` and  :func:`decMetric`
  * update a gauge using :func:`setMetric`
 
-.. function:: declareMetric(name, type) -> bool
+.. function:: declareMetric(name, type, description) -> bool
 
   .. versionadded:: 1.8.0
 
@@ -18,6 +18,7 @@ Then you can update those at runtime using the following functions, depending on
 
   :param str name: The name of the metric, lowercase alphanumerical characters and dashes (-) only
   :param str type: The desired type in ``gauge`` or ``counter``
+  :param str name: The description of the metric
 
 .. function:: incMetric(name) -> int
 
index 4b001f2edf44ced8cf4a5ceb2d07669dc8442dfc..3f6f2ae0b7cc5a3c551ac8e6e1aaa299c5c7ea14 100644 (file)
@@ -780,9 +780,9 @@ class TestAPICustomStatistics(APITestsBase):
     _config_template = """
     newServer{address="127.0.0.1:%s"}
     webserver("127.0.0.1:%s")
-    declareMetric("my-custom-metric", "counter")
-    declareMetric("my-other-metric", "counter")
-    declareMetric("my-gauge", "gauge")
+    declareMetric("my-custom-metric", "counter", "Number of statistics")
+    declareMetric("my-other-metric", "counter", "Another number of statistics")
+    declareMetric("my-gauge", "gauge", "Current memory usage")
     setWebserverConfig({password="%s", apiKey="%s"})
     """
 
index a01119e5d43b730deea2ffc27c3d16f36f8557f6..f79d24901e250cbdb45572e65526022a036f213e 100644 (file)
@@ -469,14 +469,14 @@ class TestCustomMetrics(DNSDistTest):
     end
 
     function declareNewMetric(dq)
-      if declareMetric("new-runtime-metric", "counter") then
+      if declareMetric("new-runtime-metric", "counter", "Metric declaration at runtime should fail") then
         return DNSAction.Spoof, '1.2.3.4'
       end
       return DNSAction.None
     end
 
-    declareMetric("my-custom-counter", "counter")
-    declareMetric("my-custom-gauge", "gauge")
+    declareMetric("my-custom-counter", "counter", "Number of tests run")
+    declareMetric("my-custom-gauge", "gauge", "Temperature of the tests")
     addAction("declare.metric.advanced.tests.powerdns.com.", LuaAction(declareNewMetric))
     addAction("operations.metric.advanced.tests.powerdns.com.", LuaAction(custommetrics))
     newServer{address="127.0.0.1:%s"}