]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Move metrics to dnsdist-metrics.{cc,hh}
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 16 Jun 2023 13:00:07 +0000 (15:00 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 27 Jun 2023 14:13:16 +0000 (16:13 +0200)
This makes it possible to get more parts of the code out of the
dnsdist.hh header, which ideally should go.

19 files changed:
pdns/dnsdist-carbon.cc
pdns/dnsdist-dnscrypt.cc
pdns/dnsdist-lua-inspection.cc
pdns/dnsdist-lua.cc
pdns/dnsdist-snmp.cc
pdns/dnsdist-tcp.cc
pdns/dnsdist-web.cc
pdns/dnsdist.cc
pdns/dnsdist.hh
pdns/dnsdistdist/dnsdist-backend.cc
pdns/dnsdistdist/dnsdist-dynblocks.cc
pdns/dnsdistdist/dnsdist-metrics.cc
pdns/dnsdistdist/dnsdist-metrics.hh
pdns/dnsdistdist/dnsdist-nghttp2.cc
pdns/dnsdistdist/dnsdist-proxy-protocol.cc
pdns/dnsdistdist/dnsdist-secpoll.cc
pdns/dnsdistdist/dnsdist-tcp.hh
pdns/dnsdistdist/doh.cc
pdns/dnsdistdist/test-dnsdisttcp_cc.cc

index 4280f05f31212a0ade3101669f67bbac14d6e198..65f739721e87216451b310f6e4884b29e4558c66 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "dnsdist-carbon.hh"
 #include "dnsdist.hh"
+#include "dnsdist-metrics.hh"
 
 #ifndef DISABLE_CARBON
 #include "dolog.hh"
@@ -52,19 +53,19 @@ static bool doOneCarbonExport(const Carbon::Endpoint& endpoint)
     const time_t now = time(nullptr);
 
     {
-      auto entries = g_stats.entries.read_lock();
+      auto entries = dnsdist::metrics::g_stats.entries.read_lock();
       for (const auto& entry : *entries) {
         str << namespace_name << "." << hostname << "." << instance_name << "." << entry.d_name << ' ';
-        if (const auto& val = boost::get<pdns::stat_t*>(&entry.d_value)) {
+        if (const auto& val = std::get_if<pdns::stat_t*>(&entry.d_value)) {
           str << (*val)->load();
         }
-        else if (const auto& adval = boost::get<pdns::stat_t_trait<double>*>(&entry.d_value)) {
+        else if (const auto& adval = std::get_if<pdns::stat_t_trait<double>*>(&entry.d_value)) {
           str << (*adval)->load();
         }
-        else if (const auto& dval = boost::get<double*>(&entry.d_value)) {
+        else if (const auto& dval = std::get_if<double*>(&entry.d_value)) {
           str << **dval;
         }
-        else if (const auto& func = boost::get<DNSDistStats::statfunction_t>(&entry.d_value)) {
+        else if (const auto& func = std::get_if<dnsdist::metrics::Stats::statfunction_t>(&entry.d_value)) {
           str << (*func)(entry.d_name);
         }
         str << ' ' << now << "\r\n";
index 99301445c3f7aeec73ede31710433d1af15a0d7e..8f02910aaa8a8ff5f15626ff2a65f939803bf577 100644 (file)
@@ -21,6 +21,7 @@
  */
 #include "dolog.hh"
 #include "dnsdist.hh"
+#include "dnsdist-metrics.hh"
 #include "dnscrypt.hh"
 
 #ifdef HAVE_DNSCRYPT
@@ -40,7 +41,7 @@ int handleDNSCryptQuery(PacketBuffer& packet, DNSCryptQuery& query, bool tcp, ti
   }
 
   if (packet.size() < static_cast<uint16_t>(sizeof(struct dnsheader))) {
-    ++g_stats.nonCompliantQueries;
+    ++dnsdist::metrics::g_stats.nonCompliantQueries;
     return false;
   }
 
index 27628c33eaa0c4922f4f0e7b32f3b2297ba8ffca..66200df0eaa5e82e3785964f580aeabb69a92014 100644 (file)
@@ -737,7 +737,7 @@ void setupLuaInspection(LuaContext& luaCtx)
 
       boost::format fmt("%-35s\t%+11s");
       g_outputBuffer.clear();
-      auto entries = *g_stats.entries.read_lock();
+      auto entries = *dnsdist::metrics::g_stats.entries.read_lock();
       sort(entries.begin(), entries.end(),
            [](const decltype(entries)::value_type& a, const decltype(entries)::value_type& b) {
              return a.d_name < b.d_name;
@@ -745,16 +745,16 @@ void setupLuaInspection(LuaContext& luaCtx)
       boost::format flt("    %9.1f");
       for (const auto& entry : entries) {
         string second;
-        if (const auto& val = boost::get<pdns::stat_t*>(&entry.d_value)) {
+        if (const auto& val = std::get_if<pdns::stat_t*>(&entry.d_value)) {
           second = std::to_string((*val)->load());
         }
-        else if (const auto& adval = boost::get<pdns::stat_t_trait<double>*>(&entry.d_value)) {
+        else if (const auto& adval = std::get_if<pdns::stat_t_trait<double>*>(&entry.d_value)) {
           second = (flt % (*adval)->load()).str();
         }
-        else if (const auto& dval = boost::get<double*>(&entry.d_value)) {
+        else if (const auto& dval = std::get_if<double*>(&entry.d_value)) {
           second = (flt % (**dval)).str();
         }
-        else if (const auto& func = boost::get<DNSDistStats::statfunction_t>(&entry.d_value)) {
+        else if (const auto& func = std::get_if<dnsdist::metrics::Stats::statfunction_t>(&entry.d_value)) {
           second = std::to_string((*func)(entry.d_name));
         }
 
index aea5a1b66e40bc96c46263e7fdc9cc6704cfd008..dcd7a5c3f5c4151b2781cbaf9bc2410ee2ce6dc7 100644 (file)
@@ -1830,10 +1830,10 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
     setLuaNoSideEffect();
     std::unordered_map<string, uint64_t> res;
     {
-      auto entries = g_stats.entries.read_lock();
+      auto entries = dnsdist::metrics::g_stats.entries.read_lock();
       res.reserve(entries->size());
       for (const auto& entry : *entries) {
-        if (const auto& val = boost::get<pdns::stat_t*>(&entry.d_value)) {
+        if (const auto& val = std::get_if<pdns::stat_t*>(&entry.d_value)) {
           res[entry.d_name] = (*val)->load();
         }
       }
@@ -2221,7 +2221,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
 #ifndef DISABLE_SECPOLL
   luaCtx.writeFunction("showSecurityStatus", []() {
     setLuaNoSideEffect();
-    g_outputBuffer = std::to_string(g_stats.securityStatus) + "\n";
+    g_outputBuffer = std::to_string(dnsdist::metrics::g_stats.securityStatus) + "\n";
   });
 
   luaCtx.writeFunction("setSecurityPollSuffix", [](const std::string& suffix) {
index 149acbc511bbddec41e7e7db3fde1e40098c698b..181561a39c72e3847797f00a8c2e2bf9895282aa 100644 (file)
@@ -1,5 +1,6 @@
 
 #include "dnsdist-snmp.hh"
+#include "dnsdist-metrics.hh"
 #include "dolog.hh"
 
 bool g_snmpEnabled{false};
@@ -55,7 +56,7 @@ static const oid securityStatusOID[] = { DNSDIST_STATS_OID, 38 };
 static const oid specialMemoryUsageOID[] = { DNSDIST_STATS_OID, 39 };
 static const oid ruleTruncatedOID[] = { DNSDIST_STATS_OID, 40 };
 
-static std::unordered_map<oid, DNSDistStats::entry_t> s_statsMap;
+static std::unordered_map<oid, dnsdist::metrics::Stats::entry_t> s_statsMap;
 
 /* We are never called for a GETNEXT if it's registered as a
    "instance", as it's "magically" handled for us.  */
@@ -80,7 +81,7 @@ static int handleCounter64Stats(netsnmp_mib_handler* handler,
     return SNMP_ERR_GENERR;
   }
 
-  if (const auto& val = boost::get<pdns::stat_t*>(&it->second)) {
+  if (const auto& val = std::get_if<pdns::stat_t*>(&it->second)) {
     return DNSDistSNMPAgent::setCounter64Value(requests, (*val)->load());
   }
 
@@ -125,7 +126,7 @@ static int handleFloatStats(netsnmp_mib_handler* handler,
     return SNMP_ERR_GENERR;
   }
 
-  if (const auto& val = boost::get<double*>(&it->second)) {
+  if (const auto& val = std::get_if<double*>(&it->second)) {
     std::string str(std::to_string(**val));
     snmp_set_var_typed_value(requests->requestvb,
                              ASN_OCTET_STR,
@@ -176,11 +177,11 @@ static int handleGauge64Stats(netsnmp_mib_handler* handler,
   }
 
   std::string str;
-  uint64_t value = (*boost::get<DNSDistStats::statfunction_t>(&it->second))(str);
+  uint64_t value = (*std::get_if<dnsdist::metrics::Stats::statfunction_t>(&it->second))(str);
   return DNSDistSNMPAgent::setCounter64Value(requests, value);
 }
 
-static void registerGauge64Stat(const char* name, const oid statOID[], size_t statOIDLength, DNSDistStats::statfunction_t ptr)
+static void registerGauge64Stat(const char* name, const oid statOID[], size_t statOIDLength, dnsdist::metrics::Stats::statfunction_t ptr)
 {
   if (statOIDLength != OID_LENGTH(queriesOID)) {
     errlog("Invalid OID for SNMP Gauge64 statistic %s", name);
@@ -552,44 +553,44 @@ DNSDistSNMPAgent::DNSDistSNMPAgent(const std::string& name, const std::string& d
 {
 #ifdef HAVE_NET_SNMP
 
-  registerCounter64Stat("queries", queriesOID, OID_LENGTH(queriesOID), &g_stats.queries);
-  registerCounter64Stat("responses", responsesOID, OID_LENGTH(responsesOID), &g_stats.responses);
-  registerCounter64Stat("servfailResponses", servfailResponsesOID, OID_LENGTH(servfailResponsesOID), &g_stats.servfailResponses);
-  registerCounter64Stat("aclDrops", aclDropsOID, OID_LENGTH(aclDropsOID), &g_stats.aclDrops);
-  registerCounter64Stat("ruleDrop", ruleDropOID, OID_LENGTH(ruleDropOID), &g_stats.ruleDrop);
-  registerCounter64Stat("ruleNXDomain", ruleNXDomainOID, OID_LENGTH(ruleNXDomainOID), &g_stats.ruleNXDomain);
-  registerCounter64Stat("ruleRefused", ruleRefusedOID, OID_LENGTH(ruleRefusedOID), &g_stats.ruleRefused);
-  registerCounter64Stat("ruleServFail", ruleServFailOID, OID_LENGTH(ruleServFailOID), &g_stats.ruleServFail);
-  registerCounter64Stat("ruleTruncated", ruleTruncatedOID, OID_LENGTH(ruleTruncatedOID), &g_stats.ruleTruncated);
-  registerCounter64Stat("selfAnswered", selfAnsweredOID, OID_LENGTH(selfAnsweredOID), &g_stats.selfAnswered);
-  registerCounter64Stat("downstreamTimeouts", downstreamTimeoutsOID, OID_LENGTH(downstreamTimeoutsOID), &g_stats.downstreamTimeouts);
-  registerCounter64Stat("downstreamSendErrors", downstreamSendErrorsOID, OID_LENGTH(downstreamSendErrorsOID), &g_stats.downstreamSendErrors);
-  registerCounter64Stat("truncFail", truncFailOID, OID_LENGTH(truncFailOID), &g_stats.truncFail);
-  registerCounter64Stat("noPolicy", noPolicyOID, OID_LENGTH(noPolicyOID), &g_stats.noPolicy);
-  registerCounter64Stat("latency0_1", latency0_1OID, OID_LENGTH(latency0_1OID), &g_stats.latency0_1);
-  registerCounter64Stat("latency1_10", latency1_10OID, OID_LENGTH(latency1_10OID), &g_stats.latency1_10);
-  registerCounter64Stat("latency10_50", latency10_50OID, OID_LENGTH(latency10_50OID), &g_stats.latency10_50);
-  registerCounter64Stat("latency50_100", latency50_100OID, OID_LENGTH(latency50_100OID), &g_stats.latency50_100);
-  registerCounter64Stat("latency100_1000", latency100_1000OID, OID_LENGTH(latency100_1000OID), &g_stats.latency100_1000);
-  registerCounter64Stat("latencySlow", latencySlowOID, OID_LENGTH(latencySlowOID), &g_stats.latencySlow);
-  registerCounter64Stat("nonCompliantQueries", nonCompliantQueriesOID, OID_LENGTH(nonCompliantQueriesOID), &g_stats.nonCompliantQueries);
-  registerCounter64Stat("nonCompliantResponses", nonCompliantResponsesOID, OID_LENGTH(nonCompliantResponsesOID), &g_stats.nonCompliantResponses);
-  registerCounter64Stat("rdQueries", rdQueriesOID, OID_LENGTH(rdQueriesOID), &g_stats.rdQueries);
-  registerCounter64Stat("emptyQueries", emptyQueriesOID, OID_LENGTH(emptyQueriesOID), &g_stats.emptyQueries);
-  registerCounter64Stat("cacheHits", cacheHitsOID, OID_LENGTH(cacheHitsOID), &g_stats.cacheHits);
-  registerCounter64Stat("cacheMisses", cacheMissesOID, OID_LENGTH(cacheMissesOID), &g_stats.cacheMisses);
-  registerCounter64Stat("dynBlocked", dynBlockedOID, OID_LENGTH(dynBlockedOID), &g_stats.dynBlocked);
-  registerFloatStat("latencyAvg100", latencyAvg100OID, OID_LENGTH(latencyAvg100OID), &g_stats.latencyAvg100);
-  registerFloatStat("latencyAvg1000", latencyAvg1000OID, OID_LENGTH(latencyAvg1000OID), &g_stats.latencyAvg1000);
-  registerFloatStat("latencyAvg10000", latencyAvg10000OID, OID_LENGTH(latencyAvg10000OID), &g_stats.latencyAvg10000);
-  registerFloatStat("latencyAvg1000000", latencyAvg1000000OID, OID_LENGTH(latencyAvg1000000OID), &g_stats.latencyAvg1000000);
+  registerCounter64Stat("queries", queriesOID, OID_LENGTH(queriesOID), &dnsdist::metrics::g_stats.queries);
+  registerCounter64Stat("responses", responsesOID, OID_LENGTH(responsesOID), &dnsdist::metrics::g_stats.responses);
+  registerCounter64Stat("servfailResponses", servfailResponsesOID, OID_LENGTH(servfailResponsesOID), &dnsdist::metrics::g_stats.servfailResponses);
+  registerCounter64Stat("aclDrops", aclDropsOID, OID_LENGTH(aclDropsOID), &dnsdist::metrics::g_stats.aclDrops);
+  registerCounter64Stat("ruleDrop", ruleDropOID, OID_LENGTH(ruleDropOID), &dnsdist::metrics::g_stats.ruleDrop);
+  registerCounter64Stat("ruleNXDomain", ruleNXDomainOID, OID_LENGTH(ruleNXDomainOID), &dnsdist::metrics::g_stats.ruleNXDomain);
+  registerCounter64Stat("ruleRefused", ruleRefusedOID, OID_LENGTH(ruleRefusedOID), &dnsdist::metrics::g_stats.ruleRefused);
+  registerCounter64Stat("ruleServFail", ruleServFailOID, OID_LENGTH(ruleServFailOID), &dnsdist::metrics::g_stats.ruleServFail);
+  registerCounter64Stat("ruleTruncated", ruleTruncatedOID, OID_LENGTH(ruleTruncatedOID), &dnsdist::metrics::g_stats.ruleTruncated);
+  registerCounter64Stat("selfAnswered", selfAnsweredOID, OID_LENGTH(selfAnsweredOID), &dnsdist::metrics::g_stats.selfAnswered);
+  registerCounter64Stat("downstreamTimeouts", downstreamTimeoutsOID, OID_LENGTH(downstreamTimeoutsOID), &dnsdist::metrics::g_stats.downstreamTimeouts);
+  registerCounter64Stat("downstreamSendErrors", downstreamSendErrorsOID, OID_LENGTH(downstreamSendErrorsOID), &dnsdist::metrics::g_stats.downstreamSendErrors);
+  registerCounter64Stat("truncFail", truncFailOID, OID_LENGTH(truncFailOID), &dnsdist::metrics::g_stats.truncFail);
+  registerCounter64Stat("noPolicy", noPolicyOID, OID_LENGTH(noPolicyOID), &dnsdist::metrics::g_stats.noPolicy);
+  registerCounter64Stat("latency0_1", latency0_1OID, OID_LENGTH(latency0_1OID), &dnsdist::metrics::g_stats.latency0_1);
+  registerCounter64Stat("latency1_10", latency1_10OID, OID_LENGTH(latency1_10OID), &dnsdist::metrics::g_stats.latency1_10);
+  registerCounter64Stat("latency10_50", latency10_50OID, OID_LENGTH(latency10_50OID), &dnsdist::metrics::g_stats.latency10_50);
+  registerCounter64Stat("latency50_100", latency50_100OID, OID_LENGTH(latency50_100OID), &dnsdist::metrics::g_stats.latency50_100);
+  registerCounter64Stat("latency100_1000", latency100_1000OID, OID_LENGTH(latency100_1000OID), &dnsdist::metrics::g_stats.latency100_1000);
+  registerCounter64Stat("latencySlow", latencySlowOID, OID_LENGTH(latencySlowOID), &dnsdist::metrics::g_stats.latencySlow);
+  registerCounter64Stat("nonCompliantQueries", nonCompliantQueriesOID, OID_LENGTH(nonCompliantQueriesOID), &dnsdist::metrics::g_stats.nonCompliantQueries);
+  registerCounter64Stat("nonCompliantResponses", nonCompliantResponsesOID, OID_LENGTH(nonCompliantResponsesOID), &dnsdist::metrics::g_stats.nonCompliantResponses);
+  registerCounter64Stat("rdQueries", rdQueriesOID, OID_LENGTH(rdQueriesOID), &dnsdist::metrics::g_stats.rdQueries);
+  registerCounter64Stat("emptyQueries", emptyQueriesOID, OID_LENGTH(emptyQueriesOID), &dnsdist::metrics::g_stats.emptyQueries);
+  registerCounter64Stat("cacheHits", cacheHitsOID, OID_LENGTH(cacheHitsOID), &dnsdist::metrics::g_stats.cacheHits);
+  registerCounter64Stat("cacheMisses", cacheMissesOID, OID_LENGTH(cacheMissesOID), &dnsdist::metrics::g_stats.cacheMisses);
+  registerCounter64Stat("dynBlocked", dynBlockedOID, OID_LENGTH(dynBlockedOID), &dnsdist::metrics::g_stats.dynBlocked);
+  registerFloatStat("latencyAvg100", latencyAvg100OID, OID_LENGTH(latencyAvg100OID), &dnsdist::metrics::g_stats.latencyAvg100);
+  registerFloatStat("latencyAvg1000", latencyAvg1000OID, OID_LENGTH(latencyAvg1000OID), &dnsdist::metrics::g_stats.latencyAvg1000);
+  registerFloatStat("latencyAvg10000", latencyAvg10000OID, OID_LENGTH(latencyAvg10000OID), &dnsdist::metrics::g_stats.latencyAvg10000);
+  registerFloatStat("latencyAvg1000000", latencyAvg1000000OID, OID_LENGTH(latencyAvg1000000OID), &dnsdist::metrics::g_stats.latencyAvg1000000);
   registerGauge64Stat("uptime", uptimeOID, OID_LENGTH(uptimeOID), &uptimeOfProcess);
   registerGauge64Stat("specialMemoryUsage", specialMemoryUsageOID, OID_LENGTH(specialMemoryUsageOID), &getSpecialMemoryUsage);
   registerGauge64Stat("cpuUserMSec", cpuUserMSecOID, OID_LENGTH(cpuUserMSecOID), &getCPUTimeUser);
   registerGauge64Stat("cpuSysMSec", cpuSysMSecOID, OID_LENGTH(cpuSysMSecOID), &getCPUTimeSystem);
   registerGauge64Stat("fdUsage", fdUsageOID, OID_LENGTH(fdUsageOID), &getOpenFileDescriptors);
   registerGauge64Stat("dynBlockedNMGSize", dynBlockedNMGSizeOID, OID_LENGTH(dynBlockedNMGSizeOID), [](const std::string&) { return g_dynblockNMG.getLocal()->size(); });
-  registerGauge64Stat("securityStatus", securityStatusOID, OID_LENGTH(securityStatusOID), [](const std::string&) { return g_stats.securityStatus.load(); });
+  registerGauge64Stat("securityStatus", securityStatusOID, OID_LENGTH(securityStatusOID), [](const std::string&) { return dnsdist::metrics::g_stats.securityStatus.load(); });
   registerGauge64Stat("realMemoryUsage", realMemoryUsageOID, OID_LENGTH(realMemoryUsageOID), &getRealMemoryUsage);
 
 
index b72f0e0f5f9ef11876ddba06d5c8f9fe88701a7a..7b99f6be7d1e103f60215eac20bc51372dd09ba5 100644 (file)
@@ -507,7 +507,7 @@ void IncomingTCPConnectionState::handleResponse(const struct timeval& now, TCPRe
     }
   }
 
-  ++g_stats.responses;
+  ++dnsdist::metrics::g_stats.responses;
   ++state->d_ci.cs->responses;
 
   queueResponse(state, now, std::move(response));
@@ -578,7 +578,7 @@ void IncomingTCPConnectionState::handleCrossProtocolResponse(const struct timeva
   try {
     auto ptr = std::make_unique<TCPCrossProtocolResponse>(std::move(response), state, now);
     if (!state->d_threadData.crossProtocolResponseSender.send(std::move(ptr))) {
-      ++g_stats.tcpCrossProtocolResponsePipeFull;
+      ++dnsdist::metrics::g_stats.tcpCrossProtocolResponsePipeFull;
       vinfolog("Unable to pass a cross-protocol response to the TCP worker thread because the pipe is full");
     }
   }
@@ -590,7 +590,7 @@ void IncomingTCPConnectionState::handleCrossProtocolResponse(const struct timeva
 static void handleQuery(std::shared_ptr<IncomingTCPConnectionState>& state, const struct timeval& now)
 {
   if (state->d_querySize < sizeof(dnsheader)) {
-    ++g_stats.nonCompliantQueries;
+    ++dnsdist::metrics::g_stats.nonCompliantQueries;
     ++state->d_ci.cs->nonCompliantQueries;
     state->terminateClientConnection();
     return;
@@ -598,7 +598,7 @@ static void handleQuery(std::shared_ptr<IncomingTCPConnectionState>& state, cons
 
   ++state->d_queriesCount;
   ++state->d_ci.cs->queries;
-  ++g_stats.queries;
+  ++dnsdist::metrics::g_stats.queries;
 
   if (state->d_handler.isTLS()) {
     auto tlsVersion = state->d_handler.getTLSVersion();
@@ -837,7 +837,7 @@ void IncomingTCPConnectionState::handleIO(std::shared_ptr<IncomingTCPConnectionS
             ssize_t remaining = isProxyHeaderComplete(state->d_buffer);
             if (remaining == 0) {
               vinfolog("Unable to consume proxy protocol header in packet from TCP client %s", state->d_ci.remote.toStringWithPort());
-              ++g_stats.proxyProtocolInvalid;
+              ++dnsdist::metrics::g_stats.proxyProtocolInvalid;
               break;
             }
             else if (remaining < 0) {
@@ -1358,7 +1358,7 @@ static void acceptNewConnection(const TCPAcceptorParam& param, TCPClientThreadDa
     }
 
     if (!acl->match(remote)) {
-      ++g_stats.aclDrops;
+      ++dnsdist::metrics::g_stats.aclDrops;
       vinfolog("Dropped TCP connection from %s because of ACL", remote.toStringWithPort());
       return;
     }
index c7fd3812c23c5c4dad5674fce1b296de06f029af..dfb9718b3bf4dbd944f752446849a2614112a602 100644 (file)
@@ -34,6 +34,7 @@
 #include "dnsdist.hh"
 #include "dnsdist-dynblocks.hh"
 #include "dnsdist-healthchecks.hh"
+#include "dnsdist-metrics.hh"
 #include "dnsdist-prometheus.hh"
 #include "dnsdist-web.hh"
 #include "dolog.hh"
@@ -468,7 +469,7 @@ static void handlePrometheus(const YaHTTP::Request& req, YaHTTP::Response& resp)
   std::ostringstream output;
   static const std::set<std::string> metricBlacklist = { "special-memory-usage", "latency-count", "latency-sum" };
   {
-    auto entries = g_stats.entries.read_lock();
+    auto entries = dnsdist::metrics::g_stats.entries.read_lock();
     for (const auto& entry : *entries) {
       const auto& metricName = entry.d_name;
 
@@ -504,16 +505,16 @@ static void handlePrometheus(const YaHTTP::Request& req, YaHTTP::Response& resp)
       output << "# TYPE " << helpName << " " << prometheusTypeName << "\n";
       output << prometheusMetricName << " ";
 
-      if (const auto& val = boost::get<pdns::stat_t*>(&entry.d_value)) {
+      if (const auto& val = std::get_if<pdns::stat_t*>(&entry.d_value)) {
         output << (*val)->load();
       }
-      else if (const auto& adval = boost::get<pdns::stat_t_trait<double>*>(&entry.d_value)) {
+      else if (const auto& adval = std::get_if<pdns::stat_t_trait<double>*>(&entry.d_value)) {
         output << (*adval)->load();
       }
-      else if (const auto& dval = boost::get<double*>(&entry.d_value)) {
+      else if (const auto& dval = std::get_if<double*>(&entry.d_value)) {
         output << **dval;
       }
-      else if (const auto& func = boost::get<DNSDistStats::statfunction_t>(&entry.d_value)) {
+      else if (const auto& func = std::get_if<dnsdist::metrics::Stats::statfunction_t>(&entry.d_value)) {
         output << (*func)(entry.d_name);
       }
 
@@ -524,20 +525,20 @@ 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 = g_stats.latency0_1;
+  uint64_t latency_amounts = dnsdist::metrics::g_stats.latency0_1;
   output << "dnsdist_latency_bucket{le=\"1\"} " << latency_amounts << "\n";
-  latency_amounts += g_stats.latency1_10;
+  latency_amounts += dnsdist::metrics::g_stats.latency1_10;
   output << "dnsdist_latency_bucket{le=\"10\"} " << latency_amounts << "\n";
-  latency_amounts += g_stats.latency10_50;
+  latency_amounts += dnsdist::metrics::g_stats.latency10_50;
   output << "dnsdist_latency_bucket{le=\"50\"} " << latency_amounts << "\n";
-  latency_amounts += g_stats.latency50_100;
+  latency_amounts += dnsdist::metrics::g_stats.latency50_100;
   output << "dnsdist_latency_bucket{le=\"100\"} " << latency_amounts << "\n";
-  latency_amounts += g_stats.latency100_1000;
+  latency_amounts += dnsdist::metrics::g_stats.latency100_1000;
   output << "dnsdist_latency_bucket{le=\"1000\"} " << latency_amounts << "\n";
-  latency_amounts += g_stats.latencySlow; // Should be the same as latency_count
+  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 " << g_stats.latencySum << "\n";
-  output << "dnsdist_latency_count " << g_stats.latencyCount << "\n";
+  output << "dnsdist_latency_sum " << dnsdist::metrics::g_stats.latencySum << "\n";
+  output << "dnsdist_latency_count " << dnsdist::metrics::g_stats.latencyCount << "\n";
 
   auto states = g_dstates.getLocal();
   const string statesbase = "dnsdist_server_";
@@ -895,18 +896,18 @@ using namespace json11;
 
 static void addStatsToJSONObject(Json::object& obj)
 {
-  auto entries = g_stats.entries.read_lock();
+  auto entries = dnsdist::metrics::g_stats.entries.read_lock();
   for (const auto& entry : *entries) {
     if (entry.d_name == "special-memory-usage") {
       continue; // Too expensive for get-all
     }
-    if (const auto& val = boost::get<pdns::stat_t*>(&entry.d_value)) {
+    if (const auto& val = std::get_if<pdns::stat_t*>(&entry.d_value)) {
       obj.emplace(entry.d_name, (double)(*val)->load());
-    } else if (const auto& adval = boost::get<pdns::stat_t_trait<double>*>(&entry.d_value)) {
+    } else if (const auto& adval = std::get_if<pdns::stat_t_trait<double>*>(&entry.d_value)) {
       obj.emplace(entry.d_name, (*adval)->load());
-    } else if (const auto& dval = boost::get<double*>(&entry.d_value)) {
+    } else if (const auto& dval = std::get_if<double*>(&entry.d_value)) {
       obj.emplace(entry.d_name, (**dval));
-    } else if (const auto& func = boost::get<DNSDistStats::statfunction_t>(&entry.d_value)) {
+    } else if (const auto& func = std::get_if<dnsdist::metrics::Stats::statfunction_t>(&entry.d_value)) {
       obj.emplace(entry.d_name, (double)(*func)(entry.d_name));
     }
   }
@@ -1336,34 +1337,34 @@ static void handleStatsOnly(const YaHTTP::Request& req, YaHTTP::Response& resp)
 
   Json::array doc;
   {
-    auto entries = g_stats.entries.read_lock();
+    auto entries = dnsdist::metrics::g_stats.entries.read_lock();
     for (const auto& item : *entries) {
       if (item.d_name == "special-memory-usage") {
         continue; // Too expensive for get-all
       }
 
-      if (const auto& val = boost::get<pdns::stat_t*>(&item.d_value)) {
+      if (const auto& val = std::get_if<pdns::stat_t*>(&item.d_value)) {
         doc.push_back(Json::object {
             { "type", "StatisticItem" },
             { "name", item.d_name },
             { "value", (double)(*val)->load() }
           });
       }
-      else if (const auto& adval = boost::get<pdns::stat_t_trait<double>*>(&item.d_value)) {
+      else if (const auto& adval = std::get_if<pdns::stat_t_trait<double>*>(&item.d_value)) {
         doc.push_back(Json::object {
             { "type", "StatisticItem" },
             { "name", item.d_name },
             { "value", (*adval)->load() }
           });
       }
-      else if (const auto& dval = boost::get<double*>(&item.d_value)) {
+      else if (const auto& dval = std::get_if<double*>(&item.d_value)) {
         doc.push_back(Json::object {
             { "type", "StatisticItem" },
             { "name", item.d_name },
             { "value", (**dval) }
           });
       }
-      else if (const auto& func = boost::get<DNSDistStats::statfunction_t>(&item.d_value)) {
+      else if (const auto& func = std::get_if<dnsdist::metrics::Stats::statfunction_t>(&item.d_value)) {
         doc.push_back(Json::object {
             { "type", "StatisticItem" },
             { "name", item.d_name },
index a9af1a217d3ca70eea0f98fba28cae8112c7541a..62fef05a2e3cbfc15f017ef817beaab70ed787ac 100644 (file)
@@ -96,8 +96,6 @@ using std::thread;
 bool g_verbose;
 std::optional<std::ofstream> g_verboseStream{std::nullopt};
 
-struct DNSDistStats g_stats;
-
 uint16_t g_maxOutstanding{std::numeric_limits<uint16_t>::max()};
 uint32_t g_staleCacheEntriesTTL{0};
 bool g_syslog{true};
@@ -205,7 +203,7 @@ static void truncateTC(PacketBuffer& packet, size_t maximumSize, unsigned int qn
   }
   catch(...)
   {
-    ++g_stats.truncFail;
+    ++dnsdist::metrics::g_stats.truncFail;
   }
 }
 
@@ -258,49 +256,49 @@ static void doLatencyStats(dnsdist::Protocol protocol, double udiff)
 
   if (protocol == dnsdist::Protocol::DoUDP || protocol == dnsdist::Protocol::DNSCryptUDP) {
     if (udiff < 1000) {
-      ++g_stats.latency0_1;
+      ++dnsdist::metrics::g_stats.latency0_1;
     }
     else if (udiff < 10000) {
-      ++g_stats.latency1_10;
+      ++dnsdist::metrics::g_stats.latency1_10;
     }
     else if (udiff < 50000) {
-      ++g_stats.latency10_50;
+      ++dnsdist::metrics::g_stats.latency10_50;
     }
     else if (udiff < 100000) {
-      ++g_stats.latency50_100;
+      ++dnsdist::metrics::g_stats.latency50_100;
     }
     else if (udiff < 1000000) {
-      ++g_stats.latency100_1000;
+      ++dnsdist::metrics::g_stats.latency100_1000;
     }
     else {
-      ++g_stats.latencySlow;
+      ++dnsdist::metrics::g_stats.latencySlow;
     }
 
-    g_stats.latencySum += udiff / 1000;
-    ++g_stats.latencyCount;
+    dnsdist::metrics::g_stats.latencySum += udiff / 1000;
+    ++dnsdist::metrics::g_stats.latencyCount;
 
-    doAvg(g_stats.latencyAvg100,     udiff,     100);
-    doAvg(g_stats.latencyAvg1000,    udiff,    1000);
-    doAvg(g_stats.latencyAvg10000,   udiff,   10000);
-    doAvg(g_stats.latencyAvg1000000, udiff, 1000000);
+    doAvg(dnsdist::metrics::g_stats.latencyAvg100,     udiff,     100);
+    doAvg(dnsdist::metrics::g_stats.latencyAvg1000,    udiff,    1000);
+    doAvg(dnsdist::metrics::g_stats.latencyAvg10000,   udiff,   10000);
+    doAvg(dnsdist::metrics::g_stats.latencyAvg1000000, udiff, 1000000);
   }
   else if (protocol == dnsdist::Protocol::DoTCP || protocol == dnsdist::Protocol::DNSCryptTCP) {
-    doAvg(g_stats.latencyTCPAvg100,     udiff,     100);
-    doAvg(g_stats.latencyTCPAvg1000,    udiff,    1000);
-    doAvg(g_stats.latencyTCPAvg10000,   udiff,   10000);
-    doAvg(g_stats.latencyTCPAvg1000000, udiff, 1000000);
+    doAvg(dnsdist::metrics::g_stats.latencyTCPAvg100,     udiff,     100);
+    doAvg(dnsdist::metrics::g_stats.latencyTCPAvg1000,    udiff,    1000);
+    doAvg(dnsdist::metrics::g_stats.latencyTCPAvg10000,   udiff,   10000);
+    doAvg(dnsdist::metrics::g_stats.latencyTCPAvg1000000, udiff, 1000000);
   }
   else if (protocol == dnsdist::Protocol::DoT) {
-    doAvg(g_stats.latencyDoTAvg100,     udiff,     100);
-    doAvg(g_stats.latencyDoTAvg1000,    udiff,    1000);
-    doAvg(g_stats.latencyDoTAvg10000,   udiff,   10000);
-    doAvg(g_stats.latencyDoTAvg1000000, udiff, 1000000);
+    doAvg(dnsdist::metrics::g_stats.latencyDoTAvg100,     udiff,     100);
+    doAvg(dnsdist::metrics::g_stats.latencyDoTAvg1000,    udiff,    1000);
+    doAvg(dnsdist::metrics::g_stats.latencyDoTAvg10000,   udiff,   10000);
+    doAvg(dnsdist::metrics::g_stats.latencyDoTAvg1000000, udiff, 1000000);
   }
   else if (protocol == dnsdist::Protocol::DoH) {
-    doAvg(g_stats.latencyDoHAvg100,     udiff,     100);
-    doAvg(g_stats.latencyDoHAvg1000,    udiff,    1000);
-    doAvg(g_stats.latencyDoHAvg10000,   udiff,   10000);
-    doAvg(g_stats.latencyDoHAvg1000000, udiff, 1000000);
+    doAvg(dnsdist::metrics::g_stats.latencyDoHAvg100,     udiff,     100);
+    doAvg(dnsdist::metrics::g_stats.latencyDoHAvg1000,    udiff,    1000);
+    doAvg(dnsdist::metrics::g_stats.latencyDoHAvg10000,   udiff,   10000);
+    doAvg(dnsdist::metrics::g_stats.latencyDoHAvg1000000, udiff, 1000000);
   }
 }
 
@@ -312,7 +310,7 @@ bool responseContentMatches(const PacketBuffer& response, const DNSName& qname,
 
   const struct dnsheader* dh = reinterpret_cast<const struct dnsheader*>(response.data());
   if (dh->qr == 0) {
-    ++g_stats.nonCompliantResponses;
+    ++dnsdist::metrics::g_stats.nonCompliantResponses;
     if (remote) {
       ++remote->nonCompliantResponses;
     }
@@ -324,7 +322,7 @@ bool responseContentMatches(const PacketBuffer& response, const DNSName& qname,
       return true;
     }
     else {
-      ++g_stats.nonCompliantResponses;
+      ++dnsdist::metrics::g_stats.nonCompliantResponses;
       if (remote) {
         ++remote->nonCompliantResponses;
       }
@@ -341,7 +339,7 @@ bool responseContentMatches(const PacketBuffer& response, const DNSName& qname,
     if (remote && response.size() > 0 && static_cast<size_t>(response.size()) > sizeof(dnsheader)) {
       infolog("Backend %s sent us a response with id %d that did not parse: %s", remote->d_config.remote.toStringWithPort(), ntohs(dh->id), e.what());
     }
-    ++g_stats.nonCompliantResponses;
+    ++dnsdist::metrics::g_stats.nonCompliantResponses;
     if (remote) {
       ++remote->nonCompliantResponses;
     }
@@ -636,16 +634,16 @@ void handleResponseSent(const DNSName& qname, const QType& qtype, double udiff,
 
   switch (cleartextDH.rcode) {
   case RCode::NXDomain:
-    ++g_stats.frontendNXDomain;
+    ++dnsdist::metrics::g_stats.frontendNXDomain;
     break;
   case RCode::ServFail:
     if (fromBackend) {
-      ++g_stats.servfailResponses;
+      ++dnsdist::metrics::g_stats.servfailResponses;
     }
-    ++g_stats.frontendServFail;
+    ++dnsdist::metrics::g_stats.frontendServFail;
     break;
   case RCode::NoError:
-    ++g_stats.frontendNoError;
+    ++dnsdist::metrics::g_stats.frontendNoError;
     break;
   }
 
@@ -680,7 +678,7 @@ static void handleResponseForUDPClient(InternalQueryState& ids, PacketBuffer& re
     }
   }
 
-  ++g_stats.responses;
+  ++dnsdist::metrics::g_stats.responses;
   if (ids.cs) {
     ++ids.cs->responses;
   }
@@ -873,7 +871,7 @@ bool processRulesResult(const DNSAction::Action& action, DNSQuestion& dq, std::s
     return true;
     break;
   case DNSAction::Action::Drop:
-    ++g_stats.ruleDrop;
+    ++dnsdist::metrics::g_stats.ruleDrop;
     drop = true;
     return true;
     break;
@@ -911,7 +909,7 @@ bool processRulesResult(const DNSAction::Action& action, DNSQuestion& dq, std::s
       dq.getHeader()->ra = dq.getHeader()->rd;
       dq.getHeader()->aa = false;
       dq.getHeader()->ad = false;
-      ++g_stats.ruleTruncated;
+      ++dnsdist::metrics::g_stats.ruleTruncated;
       return true;
     }
     break;
@@ -970,7 +968,7 @@ static bool applyRulesToQuery(LocalHolders& holders, DNSQuestion& dq, const stru
   /* the Dynamic Block mechanism supports address and port ranges, so we need to pass the full address and port */
   if (auto got = holders.dynNMGBlock->lookup(AddressAndPortRange(dq.ids.origRemote, dq.ids.origRemote.isIPv4() ? 32 : 128, 16))) {
     auto updateBlockStats = [&got]() {
-      ++g_stats.dynBlocked;
+      ++dnsdist::metrics::g_stats.dynBlocked;
       got->second.blocks++;
     };
 
@@ -1030,7 +1028,7 @@ static bool applyRulesToQuery(LocalHolders& holders, DNSQuestion& dq, const stru
 
   if (auto got = holders.dynSMTBlock->lookup(dq.ids.qname)) {
     auto updateBlockStats = [&got]() {
-      ++g_stats.dynBlocked;
+      ++dnsdist::metrics::g_stats.dynBlocked;
       got->blocks++;
     };
 
@@ -1147,14 +1145,14 @@ static bool isUDPQueryAcceptable(ClientState& cs, LocalHolders& holders, const s
     /* message was too large for our buffer */
     vinfolog("Dropping message too large for our buffer");
     ++cs.nonCompliantQueries;
-    ++g_stats.nonCompliantQueries;
+    ++dnsdist::metrics::g_stats.nonCompliantQueries;
     return false;
   }
 
   expectProxyProtocol = expectProxyProtocolFrom(remote);
   if (!holders.acl->match(remote) && !expectProxyProtocol) {
     vinfolog("Query from %s dropped because of ACL", remote.toStringWithPort());
-    ++g_stats.aclDrops;
+    ++dnsdist::metrics::g_stats.aclDrops;
     return false;
   }
 
@@ -1184,7 +1182,7 @@ static bool isUDPQueryAcceptable(ClientState& cs, LocalHolders& holders, const s
   }
 
   ++cs.queries;
-  ++g_stats.queries;
+  ++dnsdist::metrics::g_stats.queries;
 
   return true;
 }
@@ -1213,20 +1211,20 @@ bool checkDNSCryptQuery(const ClientState& cs, PacketBuffer& query, std::unique_
 bool checkQueryHeaders(const struct dnsheader* dh, ClientState& cs)
 {
   if (dh->qr) {   // don't respond to responses
-    ++g_stats.nonCompliantQueries;
+    ++dnsdist::metrics::g_stats.nonCompliantQueries;
     ++cs.nonCompliantQueries;
     return false;
   }
 
   if (dh->qdcount == 0) {
-    ++g_stats.emptyQueries;
+    ++dnsdist::metrics::g_stats.emptyQueries;
     if (g_dropEmptyQueries) {
       return false;
     }
   }
 
   if (dh->rd) {
-    ++g_stats.rdQueries;
+    ++dnsdist::metrics::g_stats.rdQueries;
   }
 
   return true;
@@ -1268,7 +1266,7 @@ static bool prepareOutgoingResponse(LocalHolders& holders, const ClientState& cs
   }
 
   if (cacheHit) {
-    ++g_stats.cacheHits;
+    ++dnsdist::metrics::g_stats.cacheHits;
   }
 
   if (dr.isAsynchronous()) {
@@ -1300,16 +1298,16 @@ ProcessQueryResult processQueryAfterRules(DNSQuestion& dq, LocalHolders& holders
 
       const auto rcode = dq.getHeader()->rcode;
       if (rcode == RCode::NXDomain) {
-        ++g_stats.ruleNXDomain;
+        ++dnsdist::metrics::g_stats.ruleNXDomain;
       }
       else if (rcode == RCode::Refused) {
-        ++g_stats.ruleRefused;
+        ++dnsdist::metrics::g_stats.ruleRefused;
       }
       else if (rcode == RCode::ServFail) {
-        ++g_stats.ruleServFail;
+        ++dnsdist::metrics::g_stats.ruleServFail;
       }
 
-      ++g_stats.selfAnswered;
+      ++dnsdist::metrics::g_stats.selfAnswered;
       ++dq.ids.cs->responses;
       return ProcessQueryResult::SendAnswer;
     }
@@ -1340,7 +1338,7 @@ ProcessQueryResult processQueryAfterRules(DNSQuestion& dq, LocalHolders& holders
             return ProcessQueryResult::Drop;
           }
 
-          ++g_stats.responses;
+          ++dnsdist::metrics::g_stats.responses;
           ++dq.ids.cs->responses;
           return ProcessQueryResult::SendAnswer;
         }
@@ -1375,7 +1373,7 @@ ProcessQueryResult processQueryAfterRules(DNSQuestion& dq, LocalHolders& holders
           return ProcessQueryResult::Drop;
         }
 
-        ++g_stats.responses;
+        ++dnsdist::metrics::g_stats.responses;
         ++dq.ids.cs->responses;
         return ProcessQueryResult::SendAnswer;
       }
@@ -1386,7 +1384,7 @@ ProcessQueryResult processQueryAfterRules(DNSQuestion& dq, LocalHolders& holders
             return ProcessQueryResult::Drop;
           }
 
-          ++g_stats.responses;
+          ++dnsdist::metrics::g_stats.responses;
           ++dq.ids.cs->responses;
           return ProcessQueryResult::SendAnswer;
         }
@@ -1394,11 +1392,11 @@ ProcessQueryResult processQueryAfterRules(DNSQuestion& dq, LocalHolders& holders
 
       vinfolog("Packet cache miss for query for %s|%s from %s (%s, %d bytes)", dq.ids.qname.toLogString(), QType(dq.ids.qtype).toString(), dq.ids.origRemote.toStringWithPort(), dq.ids.protocol.toString(), dq.getData().size());
 
-      ++g_stats.cacheMisses;
+      ++dnsdist::metrics::g_stats.cacheMisses;
     }
 
     if (!selectedBackend) {
-      ++g_stats.noPolicy;
+      ++dnsdist::metrics::g_stats.noPolicy;
 
       vinfolog("%s query for %s|%s from %s, no downstream server available", g_servFailOnNoPolicy ? "ServFailed" : "Dropped", dq.ids.qname.toLogString(), QType(dq.ids.qtype).toString(), dq.ids.origRemote.toStringWithPort());
       if (g_servFailOnNoPolicy) {
@@ -1410,7 +1408,7 @@ ProcessQueryResult processQueryAfterRules(DNSQuestion& dq, LocalHolders& holders
         if (!prepareOutgoingResponse(holders, *dq.ids.cs, dq, false)) {
           return ProcessQueryResult::Drop;
         }
-        ++g_stats.responses;
+        ++dnsdist::metrics::g_stats.responses;
         ++dq.ids.cs->responses;
         // no response-only statistics counter to update.
         return ProcessQueryResult::SendAnswer;
@@ -1591,7 +1589,7 @@ bool assignOutgoingUDPQueryToBackend(std::shared_ptr<DownstreamState>& ds, uint1
           dq.ids.du->status_code = 502;
         }
       }
-      ++g_stats.downstreamSendErrors;
+      ++dnsdist::metrics::g_stats.downstreamSendErrors;
       ++ds->sendErrors;
       return false;
     }
@@ -1795,7 +1793,7 @@ static void MultipleMessagesUDPClientThread(ClientState* cs, LocalHolders& holde
       const ComboAddress& remote = recvData[msgIdx].remote;
 
       if (static_cast<size_t>(got) < sizeof(struct dnsheader)) {
-        ++g_stats.nonCompliantQueries;
+        ++dnsdist::metrics::g_stats.nonCompliantQueries;
         ++cs->nonCompliantQueries;
         continue;
       }
@@ -1862,7 +1860,7 @@ static void udpClientThread(std::vector<ClientState*> states)
         ssize_t got = recvmsg(param.socket, &msgh, 0);
 
         if (got < 0 || static_cast<size_t>(got) < sizeof(struct dnsheader)) {
-          ++g_stats.nonCompliantQueries;
+          ++dnsdist::metrics::g_stats.nonCompliantQueries;
           ++param.cs->nonCompliantQueries;
           return;
         }
index 1f7b4e8704e2611da757628f910a222cc1b5ad91..fca2e3c4dbdd2dd258b800b0cc4354bd0d7aa55f 100644 (file)
@@ -330,156 +330,6 @@ extern vector<pair<struct timeval, std::string> > g_confDelta;
 
 using pdns::stat_t;
 
-struct DNSDistStats
-{
-  stat_t responses{0};
-  stat_t servfailResponses{0};
-  stat_t queries{0};
-  stat_t frontendNXDomain{0};
-  stat_t frontendServFail{0};
-  stat_t frontendNoError{0};
-  stat_t nonCompliantQueries{0};
-  stat_t nonCompliantResponses{0};
-  stat_t rdQueries{0};
-  stat_t emptyQueries{0};
-  stat_t aclDrops{0};
-  stat_t dynBlocked{0};
-  stat_t ruleDrop{0};
-  stat_t ruleNXDomain{0};
-  stat_t ruleRefused{0};
-  stat_t ruleServFail{0};
-  stat_t ruleTruncated{0};
-  stat_t selfAnswered{0};
-  stat_t downstreamTimeouts{0};
-  stat_t downstreamSendErrors{0};
-  stat_t truncFail{0};
-  stat_t noPolicy{0};
-  stat_t cacheHits{0};
-  stat_t cacheMisses{0};
-  stat_t latency0_1{0}, latency1_10{0}, latency10_50{0}, latency50_100{0}, latency100_1000{0}, latencySlow{0}, latencySum{0}, latencyCount{0};
-  stat_t securityStatus{0};
-  stat_t dohQueryPipeFull{0};
-  stat_t dohResponsePipeFull{0};
-  stat_t outgoingDoHQueryPipeFull{0};
-  stat_t proxyProtocolInvalid{0};
-  stat_t tcpQueryPipeFull{0};
-  stat_t tcpCrossProtocolQueryPipeFull{0};
-  stat_t tcpCrossProtocolResponsePipeFull{0};
-  double latencyAvg100{0}, latencyAvg1000{0}, latencyAvg10000{0}, latencyAvg1000000{0};
-  double latencyTCPAvg100{0}, latencyTCPAvg1000{0}, latencyTCPAvg10000{0}, latencyTCPAvg1000000{0};
-  double latencyDoTAvg100{0}, latencyDoTAvg1000{0}, latencyDoTAvg10000{0}, latencyDoTAvg1000000{0};
-  double latencyDoHAvg100{0}, latencyDoHAvg1000{0}, latencyDoHAvg10000{0}, latencyDoHAvg1000000{0};
-  using statfunction_t =  std::function<uint64_t(const std::string&)>;
-  using entry_t = boost::variant<stat_t*, pdns::stat_t_trait<double>*, double*, statfunction_t>;
-  struct EntryPair
-  {
-    std::string d_name;
-    entry_t d_value;
-  };
-
-  SharedLockGuarded<std::vector<EntryPair>> entries{std::vector<EntryPair>{
-    {"responses", &responses},
-    {"servfail-responses", &servfailResponses},
-    {"queries", &queries},
-    {"frontend-nxdomain", &frontendNXDomain},
-    {"frontend-servfail", &frontendServFail},
-    {"frontend-noerror", &frontendNoError},
-    {"acl-drops", &aclDrops},
-    {"rule-drop", &ruleDrop},
-    {"rule-nxdomain", &ruleNXDomain},
-    {"rule-refused", &ruleRefused},
-    {"rule-servfail", &ruleServFail},
-    {"rule-truncated", &ruleTruncated},
-    {"self-answered", &selfAnswered},
-    {"downstream-timeouts", &downstreamTimeouts},
-    {"downstream-send-errors", &downstreamSendErrors},
-    {"trunc-failures", &truncFail},
-    {"no-policy", &noPolicy},
-    {"latency0-1", &latency0_1},
-    {"latency1-10", &latency1_10},
-    {"latency10-50", &latency10_50},
-    {"latency50-100", &latency50_100},
-    {"latency100-1000", &latency100_1000},
-    {"latency-slow", &latencySlow},
-    {"latency-avg100", &latencyAvg100},
-    {"latency-avg1000", &latencyAvg1000},
-    {"latency-avg10000", &latencyAvg10000},
-    {"latency-avg1000000", &latencyAvg1000000},
-    {"latency-tcp-avg100", &latencyTCPAvg100},
-    {"latency-tcp-avg1000", &latencyTCPAvg1000},
-    {"latency-tcp-avg10000", &latencyTCPAvg10000},
-    {"latency-tcp-avg1000000", &latencyTCPAvg1000000},
-    {"latency-dot-avg100", &latencyDoTAvg100},
-    {"latency-dot-avg1000", &latencyDoTAvg1000},
-    {"latency-dot-avg10000", &latencyDoTAvg10000},
-    {"latency-dot-avg1000000", &latencyDoTAvg1000000},
-    {"latency-doh-avg100", &latencyDoHAvg100},
-    {"latency-doh-avg1000", &latencyDoHAvg1000},
-    {"latency-doh-avg10000", &latencyDoHAvg10000},
-    {"latency-doh-avg1000000", &latencyDoHAvg1000000},
-    {"uptime", uptimeOfProcess},
-    {"real-memory-usage", getRealMemoryUsage},
-    {"special-memory-usage", getSpecialMemoryUsage},
-    {"udp-in-errors", std::bind(udpErrorStats, "udp-in-errors")},
-    {"udp-noport-errors", std::bind(udpErrorStats, "udp-noport-errors")},
-    {"udp-recvbuf-errors", std::bind(udpErrorStats, "udp-recvbuf-errors")},
-    {"udp-sndbuf-errors", std::bind(udpErrorStats, "udp-sndbuf-errors")},
-    {"udp-in-csum-errors", std::bind(udpErrorStats, "udp-in-csum-errors")},
-    {"udp6-in-errors", std::bind(udp6ErrorStats, "udp6-in-errors")},
-    {"udp6-recvbuf-errors", std::bind(udp6ErrorStats, "udp6-recvbuf-errors")},
-    {"udp6-sndbuf-errors", std::bind(udp6ErrorStats, "udp6-sndbuf-errors")},
-    {"udp6-noport-errors", std::bind(udp6ErrorStats, "udp6-noport-errors")},
-    {"udp6-in-csum-errors", std::bind(udp6ErrorStats, "udp6-in-csum-errors")},
-    {"tcp-listen-overflows", std::bind(tcpErrorStats, "ListenOverflows")},
-    {"noncompliant-queries", &nonCompliantQueries},
-    {"noncompliant-responses", &nonCompliantResponses},
-    {"proxy-protocol-invalid", &proxyProtocolInvalid},
-    {"rdqueries", &rdQueries},
-    {"empty-queries", &emptyQueries},
-    {"cache-hits", &cacheHits},
-    {"cache-misses", &cacheMisses},
-    {"cpu-iowait", getCPUIOWait},
-    {"cpu-steal", getCPUSteal},
-    {"cpu-sys-msec", getCPUTimeSystem},
-    {"cpu-user-msec", getCPUTimeUser},
-    {"fd-usage", getOpenFileDescriptors},
-    {"dyn-blocked", &dynBlocked},
-    {"dyn-block-nmg-size", [](const std::string&) { return g_dynblockNMG.getLocal()->size(); }},
-    {"security-status", &securityStatus},
-    {"doh-query-pipe-full", &dohQueryPipeFull},
-    {"doh-response-pipe-full", &dohResponsePipeFull},
-    {"outgoing-doh-query-pipe-full", &outgoingDoHQueryPipeFull},
-    {"tcp-query-pipe-full", &tcpQueryPipeFull},
-    {"tcp-cross-protocol-query-pipe-full", &tcpCrossProtocolQueryPipeFull},
-    {"tcp-cross-protocol-response-pipe-full", &tcpCrossProtocolResponsePipeFull},
-    // Latency histogram
-    {"latency-sum", &latencySum},
-    {"latency-count", &latencyCount},
-  }};
-  struct MutableCounter
-  {
-    MutableCounter() = default;
-    MutableCounter(MutableCounter&& rhs): d_value(rhs.d_value.load())
-    {
-    }
-
-    mutable stat_t d_value{0};
-  };
-  struct MutableGauge
-  {
-    MutableGauge() = default;
-    MutableGauge(MutableGauge&& rhs): d_value(rhs.d_value.load())
-    {
-    }
-
-    mutable pdns::stat_t_trait<double> d_value{0};
-  };
-  SharedLockGuarded<std::map<std::string, MutableCounter, std::less<>>> customCounters;
-  SharedLockGuarded<std::map<std::string, MutableGauge, std::less<>>> customGauges;
-};
-
-extern struct DNSDistStats g_stats;
-
 class BasicQPSLimiter
 {
 public:
index 97cd0e46ec5c8fef36e7f5f3b87d999572495cf1..87326c93a59fd425a3f571d181d57536ebc7712c 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include "dnsdist.hh"
+#include "dnsdist-metrics.hh"
 #include "dnsdist-nghttp2.hh"
 #include "dnsdist-random.hh"
 #include "dnsdist-rings.hh"
@@ -362,7 +363,7 @@ void DownstreamState::handleUDPTimeout(IDState& ids)
   handleDOHTimeout(std::move(ids.internal.du));
   ++reuseds;
   --outstanding;
-  ++g_stats.downstreamTimeouts; // this is an 'actively' discovered timeout
+  ++dnsdist::metrics::g_stats.downstreamTimeouts; // this is an 'actively' discovered timeout
   vinfolog("Had a downstream timeout from %s (%s) for query for %s|%s from %s",
            d_config.remote.toStringWithPort(), getName(),
            ids.internal.qname.toLogString(), QType(ids.internal.qtype).toString(), ids.internal.origRemote.toStringWithPort());
@@ -461,7 +462,7 @@ uint16_t DownstreamState::saveState(InternalQueryState&& state)
 
         auto oldDU = std::move(it->second.internal.du);
         ++reuseds;
-        ++g_stats.downstreamTimeouts;
+        ++dnsdist::metrics::g_stats.downstreamTimeouts;
         handleDOHTimeout(std::move(oldDU));
       }
       else {
@@ -488,7 +489,7 @@ uint16_t DownstreamState::saveState(InternalQueryState&& state)
          to handle it because it's about to be overwritten. */
       auto oldDU = std::move(ids.internal.du);
       ++reuseds;
-      ++g_stats.downstreamTimeouts;
+      ++dnsdist::metrics::g_stats.downstreamTimeouts;
       handleDOHTimeout(std::move(oldDU));
     }
     else {
@@ -511,7 +512,7 @@ void DownstreamState::restoreState(uint16_t id, InternalQueryState&& state)
     if (!inserted) {
       /* already used */
       ++reuseds;
-      ++g_stats.downstreamTimeouts;
+      ++dnsdist::metrics::g_stats.downstreamTimeouts;
       handleDOHTimeout(std::move(state.du));
     }
     else {
@@ -526,14 +527,14 @@ void DownstreamState::restoreState(uint16_t id, InternalQueryState&& state)
   if (!guard) {
     /* already used */
     ++reuseds;
-    ++g_stats.downstreamTimeouts;
+    ++dnsdist::metrics::g_stats.downstreamTimeouts;
     handleDOHTimeout(std::move(state.du));
     return;
   }
   if (ids.isInUse()) {
     /* already used */
     ++reuseds;
-    ++g_stats.downstreamTimeouts;
+    ++dnsdist::metrics::g_stats.downstreamTimeouts;
     handleDOHTimeout(std::move(state.du));
     return;
   }
index acf85243833b86237188d177e91be10a246d4c9e..9b7bee8ae3bd4165152304e5434ff70b4cde51e5 100644 (file)
@@ -1,6 +1,7 @@
 
 #include "dnsdist.hh"
 #include "dnsdist-dynblocks.hh"
+#include "dnsdist-metrics.hh"
 
 GlobalStateHolder<NetmaskTree<DynBlock, AddressAndPortRange>> g_dynblockNMG;
 GlobalStateHolder<SuffixMatchTree<DynBlock>> g_dynblockSMT;
@@ -462,7 +463,7 @@ void DynBlockMaintenance::purgeExpired(const struct timespec& now)
         updated.erase(entry);
       }
       g_dynblockNMG.setState(std::move(updated));
-      g_stats.dynBlocked += bpfBlocked;
+      dnsdist::metrics::g_stats.dynBlocked += bpfBlocked;
     }
   }
 
index 0eed93566aa4f8d004c51cda82c8edda08ac429c..18b4e8330647faf12eadc7afa9c4ce70833d609e 100644 (file)
 
 namespace dnsdist::metrics {
 
+struct MutableCounter
+{
+  MutableCounter() = default;
+  MutableCounter(MutableCounter&& rhs): d_value(rhs.d_value.load())
+  {
+  }
+
+  mutable stat_t d_value{0};
+};
+
+struct MutableGauge
+{
+  MutableGauge() = default;
+  MutableGauge(MutableGauge&& rhs): d_value(rhs.d_value.load())
+  {
+  }
+
+  mutable pdns::stat_t_trait<double> d_value{0};
+};
+
+static SharedLockGuarded<std::map<std::string, MutableCounter, std::less<>>> s_customCounters;
+static SharedLockGuarded<std::map<std::string, MutableGauge, std::less<>>> s_customGauges;
+
+Stats::Stats(): entries{std::vector<EntryPair>{
+    {"responses", &responses},
+    {"servfail-responses", &servfailResponses},
+    {"queries", &queries},
+    {"frontend-nxdomain", &frontendNXDomain},
+    {"frontend-servfail", &frontendServFail},
+    {"frontend-noerror", &frontendNoError},
+    {"acl-drops", &aclDrops},
+    {"rule-drop", &ruleDrop},
+    {"rule-nxdomain", &ruleNXDomain},
+    {"rule-refused", &ruleRefused},
+    {"rule-servfail", &ruleServFail},
+    {"rule-truncated", &ruleTruncated},
+    {"self-answered", &selfAnswered},
+    {"downstream-timeouts", &downstreamTimeouts},
+    {"downstream-send-errors", &downstreamSendErrors},
+    {"trunc-failures", &truncFail},
+    {"no-policy", &noPolicy},
+    {"latency0-1", &latency0_1},
+    {"latency1-10", &latency1_10},
+    {"latency10-50", &latency10_50},
+    {"latency50-100", &latency50_100},
+    {"latency100-1000", &latency100_1000},
+    {"latency-slow", &latencySlow},
+    {"latency-avg100", &latencyAvg100},
+    {"latency-avg1000", &latencyAvg1000},
+    {"latency-avg10000", &latencyAvg10000},
+    {"latency-avg1000000", &latencyAvg1000000},
+    {"latency-tcp-avg100", &latencyTCPAvg100},
+    {"latency-tcp-avg1000", &latencyTCPAvg1000},
+    {"latency-tcp-avg10000", &latencyTCPAvg10000},
+    {"latency-tcp-avg1000000", &latencyTCPAvg1000000},
+    {"latency-dot-avg100", &latencyDoTAvg100},
+    {"latency-dot-avg1000", &latencyDoTAvg1000},
+    {"latency-dot-avg10000", &latencyDoTAvg10000},
+    {"latency-dot-avg1000000", &latencyDoTAvg1000000},
+    {"latency-doh-avg100", &latencyDoHAvg100},
+    {"latency-doh-avg1000", &latencyDoHAvg1000},
+    {"latency-doh-avg10000", &latencyDoHAvg10000},
+    {"latency-doh-avg1000000", &latencyDoHAvg1000000},
+    {"uptime", uptimeOfProcess},
+    {"real-memory-usage", getRealMemoryUsage},
+    {"special-memory-usage", getSpecialMemoryUsage},
+    {"udp-in-errors", std::bind(udpErrorStats, "udp-in-errors")},
+    {"udp-noport-errors", std::bind(udpErrorStats, "udp-noport-errors")},
+    {"udp-recvbuf-errors", std::bind(udpErrorStats, "udp-recvbuf-errors")},
+    {"udp-sndbuf-errors", std::bind(udpErrorStats, "udp-sndbuf-errors")},
+    {"udp-in-csum-errors", std::bind(udpErrorStats, "udp-in-csum-errors")},
+    {"udp6-in-errors", std::bind(udp6ErrorStats, "udp6-in-errors")},
+    {"udp6-recvbuf-errors", std::bind(udp6ErrorStats, "udp6-recvbuf-errors")},
+    {"udp6-sndbuf-errors", std::bind(udp6ErrorStats, "udp6-sndbuf-errors")},
+    {"udp6-noport-errors", std::bind(udp6ErrorStats, "udp6-noport-errors")},
+    {"udp6-in-csum-errors", std::bind(udp6ErrorStats, "udp6-in-csum-errors")},
+    {"tcp-listen-overflows", std::bind(tcpErrorStats, "ListenOverflows")},
+    {"noncompliant-queries", &nonCompliantQueries},
+    {"noncompliant-responses", &nonCompliantResponses},
+    {"proxy-protocol-invalid", &proxyProtocolInvalid},
+    {"rdqueries", &rdQueries},
+    {"empty-queries", &emptyQueries},
+    {"cache-hits", &cacheHits},
+    {"cache-misses", &cacheMisses},
+    {"cpu-iowait", getCPUIOWait},
+    {"cpu-steal", getCPUSteal},
+    {"cpu-sys-msec", getCPUTimeSystem},
+    {"cpu-user-msec", getCPUTimeUser},
+    {"fd-usage", getOpenFileDescriptors},
+    {"dyn-blocked", &dynBlocked},
+    {"dyn-block-nmg-size", [](const std::string&) { return g_dynblockNMG.getLocal()->size(); }},
+    {"security-status", &securityStatus},
+    {"doh-query-pipe-full", &dohQueryPipeFull},
+    {"doh-response-pipe-full", &dohResponsePipeFull},
+    {"outgoing-doh-query-pipe-full", &outgoingDoHQueryPipeFull},
+    {"tcp-query-pipe-full", &tcpQueryPipeFull},
+    {"tcp-cross-protocol-query-pipe-full", &tcpCrossProtocolQueryPipeFull},
+    {"tcp-cross-protocol-response-pipe-full", &tcpCrossProtocolResponsePipeFull},
+    // Latency histogram
+    {"latency-sum", &latencySum},
+    {"latency-count", &latencyCount},
+  }}
+{
+}
+
+struct Stats g_stats;
+
 std::optional<std::string> declareCustomMetric(const std::string& name, const std::string& type, const std::string& description, std::optional<std::string> customName)
 {
   if (!std::regex_match(name, std::regex("^[a-z0-9-]+$"))) {
@@ -34,18 +141,18 @@ std::optional<std::string> declareCustomMetric(const std::string& name, const st
   }
 
   if (type == "counter") {
-    auto customCounters = g_stats.customCounters.write_lock();
-    auto itp = customCounters->insert({name, DNSDistStats::MutableCounter()});
+    auto customCounters = s_customCounters.write_lock();
+    auto itp = customCounters->insert({name, MutableCounter()});
     if (itp.second) {
-      g_stats.entries.write_lock()->emplace_back(DNSDistStats::EntryPair{name, &(*customCounters)[name].d_value});
+      g_stats.entries.write_lock()->emplace_back(Stats::EntryPair{name, &(*customCounters)[name].d_value});
       addMetricDefinition(name, "counter", description, customName ? *customName : "");
     }
   }
   else if (type == "gauge") {
-    auto customGauges = g_stats.customGauges.write_lock();
-    auto itp = customGauges->insert({name, DNSDistStats::MutableGauge()});
+    auto customGauges = s_customGauges.write_lock();
+    auto itp = customGauges->insert({name, MutableGauge()});
     if (itp.second) {
-      g_stats.entries.write_lock()->emplace_back(DNSDistStats::EntryPair{name, &(*customGauges)[name].d_value});
+      g_stats.entries.write_lock()->emplace_back(Stats::EntryPair{name, &(*customGauges)[name].d_value});
       addMetricDefinition(name, "gauge", description, customName ? *customName : "");
     }
   }
@@ -57,7 +164,7 @@ std::optional<std::string> declareCustomMetric(const std::string& name, const st
 
 std::variant<uint64_t, Error> incrementCustomCounter(const std::string_view& name, uint64_t step)
 {
-  auto customCounters = g_stats.customCounters.read_lock();
+  auto customCounters = s_customCounters.read_lock();
   auto metric = customCounters->find(name);
   if (metric != customCounters->end()) {
     if (step) {
@@ -71,7 +178,7 @@ std::variant<uint64_t, Error> incrementCustomCounter(const std::string_view& nam
 
 std::variant<uint64_t, Error> decrementCustomCounter(const std::string_view& name, uint64_t step)
 {
-  auto customCounters = g_stats.customCounters.read_lock();
+  auto customCounters = s_customCounters.read_lock();
   auto metric = customCounters->find(name);
   if (metric != customCounters->end()) {
     if (step) {
@@ -85,7 +192,7 @@ std::variant<uint64_t, Error> decrementCustomCounter(const std::string_view& nam
 
 std::variant<double, Error> setCustomGauge(const std::string_view& name, const double value)
 {
-  auto customGauges = g_stats.customGauges.read_lock();
+  auto customGauges = s_customGauges.read_lock();
   auto metric = customGauges->find(name);
   if (metric != customGauges->end()) {
     metric->second.d_value = value;
@@ -98,14 +205,14 @@ std::variant<double, Error> setCustomGauge(const std::string_view& name, const d
 std::variant<double, Error> getCustomMetric(const std::string_view& name)
 {
   {
-    auto customCounters = g_stats.customCounters.read_lock();
+    auto customCounters = s_customCounters.read_lock();
     auto counter = customCounters->find(name);
     if (counter != customCounters->end()) {
       return static_cast<double>(counter->second.d_value.load());
     }
   }
   {
-    auto customGauges = g_stats.customGauges.read_lock();
+    auto customGauges = s_customGauges.read_lock();
     auto gauge = customGauges->find(name);
     if (gauge != customGauges->end()) {
       return gauge->second.d_value.load();
@@ -113,4 +220,5 @@ std::variant<double, Error> getCustomMetric(const std::string_view& name)
   }
   return std::string("Unable to get metric '") + std::string(name) + "': no such metric";
 }
+
 }
index 88a812ea8e5eaffd941b2395641e29b481f8bab7..a44c3c0c646e8bfa45f8fe948cca2b5c649d095f 100644 (file)
 #include <string_view>
 #include <variant>
 
+#include "lock.hh"
+#include "stat_t.hh"
+
 namespace dnsdist::metrics
 {
-  using Error = std::string;
+using Error = std::string;
+
+[[nodiscard]] std::optional<Error> declareCustomMetric(const std::string& name, const std::string& type, const std::string& description, std::optional<std::string> customName);
+[[nodiscard]] std::variant<uint64_t, Error> incrementCustomCounter(const std::string_view& name, uint64_t step);
+[[nodiscard]] std::variant<uint64_t, Error> decrementCustomCounter(const std::string_view& name, uint64_t step);
+[[nodiscard]] std::variant<double, Error> setCustomGauge(const std::string_view& name, const double value);
+[[nodiscard]] std::variant<double, Error> getCustomMetric(const std::string_view& name);
+
+using pdns::stat_t;
+
+struct Stats
+{
+  Stats();
+
+  stat_t responses{0};
+  stat_t servfailResponses{0};
+  stat_t queries{0};
+  stat_t frontendNXDomain{0};
+  stat_t frontendServFail{0};
+  stat_t frontendNoError{0};
+  stat_t nonCompliantQueries{0};
+  stat_t nonCompliantResponses{0};
+  stat_t rdQueries{0};
+  stat_t emptyQueries{0};
+  stat_t aclDrops{0};
+  stat_t dynBlocked{0};
+  stat_t ruleDrop{0};
+  stat_t ruleNXDomain{0};
+  stat_t ruleRefused{0};
+  stat_t ruleServFail{0};
+  stat_t ruleTruncated{0};
+  stat_t selfAnswered{0};
+  stat_t downstreamTimeouts{0};
+  stat_t downstreamSendErrors{0};
+  stat_t truncFail{0};
+  stat_t noPolicy{0};
+  stat_t cacheHits{0};
+  stat_t cacheMisses{0};
+  stat_t latency0_1{0}, latency1_10{0}, latency10_50{0}, latency50_100{0}, latency100_1000{0}, latencySlow{0}, latencySum{0}, latencyCount{0};
+  stat_t securityStatus{0};
+  stat_t dohQueryPipeFull{0};
+  stat_t dohResponsePipeFull{0};
+  stat_t outgoingDoHQueryPipeFull{0};
+  stat_t proxyProtocolInvalid{0};
+  stat_t tcpQueryPipeFull{0};
+  stat_t tcpCrossProtocolQueryPipeFull{0};
+  stat_t tcpCrossProtocolResponsePipeFull{0};
+  double latencyAvg100{0}, latencyAvg1000{0}, latencyAvg10000{0}, latencyAvg1000000{0};
+  double latencyTCPAvg100{0}, latencyTCPAvg1000{0}, latencyTCPAvg10000{0}, latencyTCPAvg1000000{0};
+  double latencyDoTAvg100{0}, latencyDoTAvg1000{0}, latencyDoTAvg10000{0}, latencyDoTAvg1000000{0};
+  double latencyDoHAvg100{0}, latencyDoHAvg1000{0}, latencyDoHAvg10000{0}, latencyDoHAvg1000000{0};
+  using statfunction_t =  std::function<uint64_t(const std::string&)>;
+  using entry_t = std::variant<stat_t*, pdns::stat_t_trait<double>*, double*, statfunction_t>;
+  struct EntryPair
+  {
+    std::string d_name;
+    entry_t d_value;
+  };
+
+  SharedLockGuarded<std::vector<EntryPair>> entries;
+};
 
-  [[nodiscard]] std::optional<Error> declareCustomMetric(const std::string& name, const std::string& type, const std::string& description, std::optional<std::string> customName);
-  [[nodiscard]] std::variant<uint64_t, Error> incrementCustomCounter(const std::string_view& name, uint64_t step);
-  [[nodiscard]] std::variant<uint64_t, Error> decrementCustomCounter(const std::string_view& name, uint64_t step);
-  [[nodiscard]] std::variant<double, Error> setCustomGauge(const std::string_view& name, const double value);
-  [[nodiscard]] std::variant<double, Error> getCustomMetric(const std::string_view& name);
+extern struct Stats g_stats;
 }
index 9c505cdcebe3cc295be23dd03098ebce54f8e137..fdc3d7a294c25bd76ce5333c211fe0e18798f7a8 100644 (file)
@@ -1043,7 +1043,7 @@ bool DoHClientCollection::passCrossProtocolQueryToThread(std::unique_ptr<CrossPr
 
   uint64_t pos = d_pos++;
   if (!d_clientThreads.at(pos % d_numberOfThreads).d_sender.send(std::move(cpq))) {
-    ++g_stats.outgoingDoHQueryPipeFull;
+    ++dnsdist::metrics::g_stats.outgoingDoHQueryPipeFull;
     return false;
   }
 
index aefcafba544d93cc376e53322a3eab36a792c8bf..d19e87206e2f47249a97f4ec6e6a3efda17d2a5e 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include "dnsdist-proxy-protocol.hh"
+#include "dnsdist-metrics.hh"
 #include "dolog.hh"
 
 NetmaskGroup g_proxyProtocolACL;
@@ -81,13 +82,13 @@ bool handleProxyProtocol(const ComboAddress& remote, bool isTCP, const NetmaskGr
 
   ssize_t used = parseProxyHeader(query, proxyProto, realRemote, realDestination, tcp, values);
   if (used <= 0) {
-    ++g_stats.proxyProtocolInvalid;
+    ++dnsdist::metrics::g_stats.proxyProtocolInvalid;
     vinfolog("Ignoring invalid proxy protocol (%d, %d) query over %s from %s", query.size(), used, (isTCP ? "TCP" : "UDP"), remote.toStringWithPort());
     return false;
   }
   else if (static_cast<size_t>(used) > g_proxyProtocolMaximumSize) {
     vinfolog("Proxy protocol header in %s packet from %s is larger than proxy-protocol-maximum-size (%d), dropping", (isTCP ? "TCP" : "UDP"), remote.toStringWithPort(), used);
-    ++g_stats.proxyProtocolInvalid;
+    ++dnsdist::metrics::g_stats.proxyProtocolInvalid;
     return false;
   }
 
@@ -95,14 +96,14 @@ bool handleProxyProtocol(const ComboAddress& remote, bool isTCP, const NetmaskGr
 
   /* on TCP we have not read the actual query yet */
   if (!isTCP && query.size() < sizeof(struct dnsheader)) {
-    ++g_stats.nonCompliantQueries;
+    ++dnsdist::metrics::g_stats.nonCompliantQueries;
     return false;
   }
 
   if (proxyProto && g_applyACLToProxiedClients) {
     if (!acl.match(realRemote)) {
       vinfolog("Query from %s dropped because of ACL", realRemote.toStringWithPort());
-      ++g_stats.aclDrops;
+      ++dnsdist::metrics::g_stats.aclDrops;
       return false;
     }
   }
index eb38d356c65ec359c6f123711d3597dd115bae13..7964d1490b0c16322f1a5af85fcbf242d952d059 100644 (file)
@@ -36,6 +36,7 @@
 #include "sstuff.hh"
 
 #include "dnsdist.hh"
+#include "dnsdist-metrics.hh"
 #include "dnsdist-random.hh"
 
 #ifndef PACKAGEVERSION
@@ -220,7 +221,7 @@ void doSecPoll(const std::string& suffix)
       errlog("PowerDNS DNSDist Security Update Mandatory: %s", securityMessage);
     }
 
-    g_stats.securityStatus = securityStatus;
+    dnsdist::metrics::g_stats.securityStatus = securityStatus;
     g_secPollDone = true;
     return;
   }
index ea25853e9c2e6acc373eb772dec1d5144ef9e5e8..d5f2edb0d1e895bfa67bee48cbc48ab994fbd086 100644 (file)
@@ -25,6 +25,7 @@
 #include "channel.hh"
 #include "iputils.hh"
 #include "dnsdist.hh"
+#include "dnsdist-metrics.hh"
 
 struct ConnectionInfo
 {
@@ -220,7 +221,7 @@ public:
     ++d_queued;
     if (!d_tcpclientthreads.at(pos % d_numthreads).d_querySender.send(std::move(conn))) {
       --d_queued;
-      ++g_stats.tcpQueryPipeFull;
+      ++dnsdist::metrics::g_stats.tcpQueryPipeFull;
       return false;
     }
 
@@ -235,7 +236,7 @@ public:
 
     uint64_t pos = d_pos++;
     if (!d_tcpclientthreads.at(pos % d_numthreads).d_crossProtocolQuerySender.send(std::move(cpq))) {
-      ++g_stats.tcpCrossProtocolQueryPipeFull;
+      ++dnsdist::metrics::g_stats.tcpCrossProtocolQueryPipeFull;
       return false;
     }
 
index 4573addbab885ac806a90ca1346430304c891a0e..4959039ffed69a593eb23c8616c1e0f757ced7d4 100644 (file)
@@ -26,6 +26,7 @@
 #include "dolog.hh"
 #include "dnsdist-concurrent-connections.hh"
 #include "dnsdist-ecs.hh"
+#include "dnsdist-metrics.hh"
 #include "dnsdist-proxy-protocol.hh"
 #include "dnsdist-rules.hh"
 #include "dnsdist-xpf.hh"
@@ -223,7 +224,7 @@ static void sendDoHUnitToTheMainThread(DOHUnitUniquePtr&& du, const char* descri
   }
   try {
     if (!du->responseSender->send(std::move(du))) {
-      ++g_stats.dohResponsePipeFull;
+      ++dnsdist::metrics::g_stats.dohResponsePipeFull;
       vinfolog("Unable to pass a %s to the DoH worker thread because the pipe is full", description);
     }
   } catch (const std::exception& e) {
@@ -463,7 +464,7 @@ public:
       handleResponseSent(du->ids, udiff, du->ids.origRemote, du->downstream->d_config.remote, du->response.size(), cleartextDH, backendProtocol, true);
     }
 
-    ++g_stats.responses;
+    ++dnsdist::metrics::g_stats.responses;
     if (du->ids.cs) {
       ++du->ids.cs->responses;
     }
@@ -643,7 +644,7 @@ static void processDOHQuery(DOHUnitUniquePtr&& unit, bool inMainThread = false)
     ClientState& cs = *dsc->cs;
 
     if (du->query.size() < sizeof(dnsheader)) {
-      ++g_stats.nonCompliantQueries;
+      ++dnsdist::metrics::g_stats.nonCompliantQueries;
       ++cs.nonCompliantQueries;
       du->status_code = 400;
       handleImmediateResponse(std::move(du), "DoH non-compliant query");
@@ -651,7 +652,7 @@ static void processDOHQuery(DOHUnitUniquePtr&& unit, bool inMainThread = false)
     }
 
     ++cs.queries;
-    ++g_stats.queries;
+    ++dnsdist::metrics::g_stats.queries;
     du->ids.queryRealTime.start();
 
     {
@@ -872,7 +873,7 @@ static void doh_dispatch_query(DOHServerConfig* dsc, h2o_handler_t* self, h2o_re
 #else /* USE_SINGLE_ACCEPTOR_THREAD */
     try {
       if (!dsc->d_querySender.send(std::move(du))) {
-        ++g_stats.dohQueryPipeFull;
+        ++dnsdist::metrics::g_stats.dohQueryPipeFull;
         vinfolog("Unable to pass a DoH query to the DoH worker thread because the pipe is full");
         h2o_send_error_500(req, "Internal Server Error", "Internal Server Error", 0);
       }
@@ -976,7 +977,7 @@ static int doh_handler(h2o_handler_t *self, h2o_req_t *req)
 
     auto& holders = dsc->holders;
     if (!holders.acl->match(conn.d_remote)) {
-      ++g_stats.aclDrops;
+      ++dnsdist::metrics::g_stats.aclDrops;
       vinfolog("Query from %s (DoH) dropped because of ACL", conn.d_remote.toStringWithPort());
       h2o_send_error_403(req, "Forbidden", "dns query not allowed because of ACL", 0);
       return 0;
@@ -1688,7 +1689,7 @@ void handleUDPResponseForDoH(DOHUnitUniquePtr&& du, PacketBuffer&& udpResponse,
 
     handleResponseSent(du->ids, udiff, dr.ids.origRemote, du->downstream->d_config.remote, du->response.size(), cleartextDH, du->downstream->getProtocol(), true);
 
-    ++g_stats.responses;
+    ++dnsdist::metrics::g_stats.responses;
     if (du->ids.cs) {
       ++du->ids.cs->responses;
     }
index 0904441da6fe2239d0bf828d6b4595ea660acd8a..2aa5adbe2063b782e577df4af7baaa8a9f6d88d2 100644 (file)
@@ -31,7 +31,6 @@
 #include "dnsdist-tcp-downstream.hh"
 #include "dnsdist-tcp-upstream.hh"
 
-struct DNSDistStats g_stats;
 GlobalStateHolder<NetmaskGroup> g_ACL;
 GlobalStateHolder<vector<DNSDistRuleAction> > g_ruleactions;
 GlobalStateHolder<vector<DNSDistResponseRuleAction> > g_respruleactions;