From b0b37121823037c4e6c443658b2cdcca88885022 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 4 May 2017 16:50:56 +0200 Subject: [PATCH] rec: Allow retrieving stats from Lua via the `getStat("name")` call --- docs/markdown/recursor/scripting.md | 12 ++++++++++++ pdns/lua-recursor4.cc | 9 +++++++++ pdns/pdns_recursor.cc | 1 + pdns/rec-carbon.cc | 2 +- pdns/rec-snmp.cc | 2 +- pdns/rec_channel.hh | 7 ++++--- pdns/rec_channel_rec.cc | 6 +++--- pdns/ws-recursor.cc | 2 +- 8 files changed, 32 insertions(+), 9 deletions(-) diff --git a/docs/markdown/recursor/scripting.md b/docs/markdown/recursor/scripting.md index ddc2f4cfb7..1bfd4239d4 100644 --- a/docs/markdown/recursor/scripting.md +++ b/docs/markdown/recursor/scripting.md @@ -375,6 +375,18 @@ Note that metrics live in the same namespace as 'system' metrics. So if you generate one that overlaps with a PowerDNS stock metric, you will get double output and weird results. +### Statistics + +You can retrieve statistics from Lua using the `getStat("name")` call. For example, +to retrieve the number of cache misses: + +``` +cacheMisses = getStat("cache-misses") +``` + +Please be aware that retrieving statistics is a relatively costly operation, and as such +should for example not be done for every query. + ### Logging To log messages with the main PowerDNS Recursor process, use `pdnslog(message)`. pdnslog can also write out to a syslog loglevel if specified. diff --git a/pdns/lua-recursor4.cc b/pdns/lua-recursor4.cc index 6445db8c6e..a28f5da8c5 100644 --- a/pdns/lua-recursor4.cc +++ b/pdns/lua-recursor4.cc @@ -518,6 +518,15 @@ RecursorLua4::RecursorLua4(const std::string& fname) d_lw->registerFunction("set", &DynMetric::set); d_lw->registerFunction("get", &DynMetric::get); + d_lw->writeFunction("getStat", [](const std::string& str) { + uint64_t result = 0; + optional value = getStatByName(str); + if (value) { + result = *value; + } + return result; + }); + d_lw->writeFunction("getRecursorThreadId", []() { return getRecursorThreadId(); }); diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index 8db2797292..75ce9e757e 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -3034,6 +3034,7 @@ try } } + registerAllStats(); if(!t_id) { t_fdm->addReadFD(s_rcc.d_fd, handleRCC); // control channel } diff --git a/pdns/rec-carbon.cc b/pdns/rec-carbon.cc index 7da9a788ee..290750930a 100644 --- a/pdns/rec-carbon.cc +++ b/pdns/rec-carbon.cc @@ -36,9 +36,9 @@ try boost::replace_all(hostname, ".", "_"); } + registerAllStats(); string msg; for(const auto& carbonServer: carbonServers) { - RecursorControlParser rcp; // inits if needed ComboAddress remote(carbonServer, 2003); Socket s(remote.sin4.sin_family, SOCK_STREAM); diff --git a/pdns/rec-snmp.cc b/pdns/rec-snmp.cc index 3e39ffd336..e2ad7e9a29 100644 --- a/pdns/rec-snmp.cc +++ b/pdns/rec-snmp.cc @@ -195,7 +195,7 @@ RecursorSNMPAgent::RecursorSNMPAgent(const std::string& name, const std::string& #ifdef HAVE_NET_SNMP /* This is done so that the statistics maps are initialized. */ - RecursorControlParser rcp; + registerAllStats(); registerCounter64Stat("questions", questionsOID, OID_LENGTH(questionsOID)); registerCounter64Stat("ipv6-questions", ipv6QuestionsOID, OID_LENGTH(ipv6QuestionsOID)); diff --git a/pdns/rec_channel.hh b/pdns/rec_channel.hh index 168f3af80f..4e2ce451ec 100644 --- a/pdns/rec_channel.hh +++ b/pdns/rec_channel.hh @@ -55,12 +55,12 @@ private: class RecursorControlParser { public: - RecursorControlParser(); + RecursorControlParser() + { + } static void nop(void){} typedef void func_t(void); std::string getAnswer(const std::string& question, func_t** func); -private: - static bool s_init; }; std::map getAllStatsMap(); @@ -74,4 +74,5 @@ std::vector* pleaseGetLargeAnswerRemotes(); DNSName getRegisteredName(const DNSName& dom); std::atomic* getDynMetric(const std::string& str); optional getStatByName(const std::string& name); +void registerAllStats(); #endif diff --git a/pdns/rec_channel_rec.cc b/pdns/rec_channel_rec.cc index 42fb89f54a..e7d1731ce0 100644 --- a/pdns/rec_channel_rec.cc +++ b/pdns/rec_channel_rec.cc @@ -78,7 +78,7 @@ std::atomic* getDynMetric(const std::string& str) return ret; } -optional get(const string& name) +static optional get(const string& name) { optional ret; @@ -770,9 +770,9 @@ uint64_t doGetMallocated() extern ResponseStats g_rs; -bool RecursorControlParser::s_init; -RecursorControlParser::RecursorControlParser() +void registerAllStats() { + static bool s_init = false; if(s_init) return; s_init=true; diff --git a/pdns/ws-recursor.cc b/pdns/ws-recursor.cc index f3b624fa6d..7b284fd89c 100644 --- a/pdns/ws-recursor.cc +++ b/pdns/ws-recursor.cc @@ -410,7 +410,7 @@ void serveStuff(HttpRequest* req, HttpResponse* resp) RecursorWebServer::RecursorWebServer(FDMultiplexer* fdm) { - RecursorControlParser rcp; // inits + registerAllStats(); d_ws = new AsyncWebServer(fdm, arg()["webserver-address"], arg().asNum("webserver-port")); d_ws->bind(); -- 2.47.2