From: Charles-Henri Bruyand Date: Thu, 2 Jun 2022 14:30:05 +0000 (+0200) Subject: dnsdist: also register custom metrics to prometheus X-Git-Tag: auth-4.8.0-alpha0~79^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b08586c7daa8e29aa5a022ad654f9eb4e2e9e3e9;p=thirdparty%2Fpdns.git dnsdist: also register custom metrics to prometheus --- diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index 64c06ee9b1..9ccec6a624 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -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"; diff --git a/pdns/dnsdist-web.cc b/pdns/dnsdist-web.cc index 9407c5523b..e0f11da9a4 100644 --- a/pdns/dnsdist-web.cc +++ b/pdns/dnsdist-web.cc @@ -131,9 +131,9 @@ private: }; #ifndef DISABLE_PROMETHEUS -static const MetricDefinitionStorage s_metricDefinitions; +static MetricDefinitionStorage s_metricDefinitions; -const std::map MetricDefinitionStorage::metrics{ +std::map 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 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) { diff --git a/pdns/dnsdistdist/dnsdist-prometheus.hh b/pdns/dnsdistdist/dnsdist-prometheus.hh index 43bd6b3d50..dbbfa1d011 100644 --- a/pdns/dnsdistdist/dnsdist-prometheus.hh +++ b/pdns/dnsdistdist/dnsdist-prometheus.hh @@ -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 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 metrics; + static std::map metrics; }; #endif /* DISABLE_PROMETHEUS */ diff --git a/pdns/dnsdistdist/dnsdist-web.hh b/pdns/dnsdistdist/dnsdist-web.hh index e33469a9cd..3e19b5716f 100644 --- a/pdns/dnsdistdist/dnsdist-web.hh +++ b/pdns/dnsdistdist/dnsdist-web.hh @@ -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(); diff --git a/pdns/dnsdistdist/docs/reference/custommetrics.rst b/pdns/dnsdistdist/docs/reference/custommetrics.rst index c29cfd0911..0e44c345bd 100644 --- a/pdns/dnsdistdist/docs/reference/custommetrics.rst +++ b/pdns/dnsdistdist/docs/reference/custommetrics.rst @@ -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 diff --git a/regression-tests.dnsdist/test_API.py b/regression-tests.dnsdist/test_API.py index 4b001f2edf..3f6f2ae0b7 100644 --- a/regression-tests.dnsdist/test_API.py +++ b/regression-tests.dnsdist/test_API.py @@ -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"}) """ diff --git a/regression-tests.dnsdist/test_Advanced.py b/regression-tests.dnsdist/test_Advanced.py index a01119e5d4..f79d24901e 100644 --- a/regression-tests.dnsdist/test_Advanced.py +++ b/regression-tests.dnsdist/test_Advanced.py @@ -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"}