From: Otto Moerbeek Date: Fri, 11 Sep 2020 09:53:15 +0000 (+0200) Subject: Separate out stat_h into a .hh file and make it a template in the pdns namespace. X-Git-Tag: dnsdist-1.6.0-alpha1~15^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=070fa3bfda4a7c608b194f4045f0ee3bf1f7da15;p=thirdparty%2Fpdns.git Separate out stat_h into a .hh file and make it a template in the pdns namespace. --- diff --git a/pdns/dnsdist-cache.hh b/pdns/dnsdist-cache.hh index 3b4b14038a..a640326162 100644 --- a/pdns/dnsdist-cache.hh +++ b/pdns/dnsdist-cache.hh @@ -27,6 +27,7 @@ #include "iputils.hh" #include "lock.hh" #include "noinitvector.hh" +#include "stat_t.hh" struct DNSQuestion; @@ -126,13 +127,13 @@ private: std::vector d_shards; - std::atomic d_deferredLookups{0}; - std::atomic d_deferredInserts{0}; - std::atomic d_hits{0}; - std::atomic d_misses{0}; - std::atomic d_insertCollisions{0}; - std::atomic d_lookupCollisions{0}; - std::atomic d_ttlTooShorts{0}; + pdns::stat_t d_deferredLookups{0}; + pdns::stat_t d_deferredInserts{0}; + pdns::stat_t d_hits{0}; + pdns::stat_t d_misses{0}; + pdns::stat_t d_insertCollisions{0}; + pdns::stat_t d_lookupCollisions{0}; + pdns::stat_t d_ttlTooShorts{0}; size_t d_maxEntries; uint32_t d_expungeIndex{0}; diff --git a/pdns/dnsdist-carbon.cc b/pdns/dnsdist-carbon.cc index b22e7dc581..05ed9f62a5 100644 --- a/pdns/dnsdist-carbon.cc +++ b/pdns/dnsdist-carbon.cc @@ -78,7 +78,7 @@ void carbonDumpThread() time_t now=time(0); for(const auto& e : g_stats.entries) { str<(&e.second)) + if(const auto& val = boost::get(&e.second)) str<<(*val)->load(); else if (const auto& dval = boost::get(&e.second)) str<<**dval; @@ -201,7 +201,7 @@ void carbonDumpThread() ++(dupPair.first->second); } - vector&>> v{ + vector> v{ {"http-connects", doh->d_httpconnects}, {"http1-queries", doh->d_http1Stats.d_nbQueries}, {"http2-queries", doh->d_http2Stats.d_nbQueries}, diff --git a/pdns/dnsdist-lua-inspection.cc b/pdns/dnsdist-lua-inspection.cc index 3cdc790d91..918dba5c31 100644 --- a/pdns/dnsdist-lua-inspection.cc +++ b/pdns/dnsdist-lua-inspection.cc @@ -656,7 +656,7 @@ void setupLuaInspection(LuaContext& luaCtx) boost::format flt(" %9.1f"); for(const auto& e : entries) { string second; - if(const auto& val = boost::get(&e.second)) + if(const auto& val = boost::get(&e.second)) second=std::to_string((*val)->load()); else if (const auto& dval = boost::get(&e.second)) second=(flt % (**dval)).str(); diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index 87e7a11783..a65be53b70 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -1652,7 +1652,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) setLuaNoSideEffect(); std::unordered_map res; for(const auto& entry : g_stats.entries) { - if(const auto& val = boost::get(&entry.second)) + if(const auto& val = boost::get(&entry.second)) res[entry.first] = (*val)->load(); } return res; diff --git a/pdns/dnsdist-rings.hh b/pdns/dnsdist-rings.hh index 511c522c1c..3678235634 100644 --- a/pdns/dnsdist-rings.hh +++ b/pdns/dnsdist-rings.hh @@ -30,6 +30,7 @@ #include "circular_buffer.hh" #include "dnsname.hh" #include "iputils.hh" +#include "stat_t.hh" struct Rings { @@ -196,10 +197,10 @@ struct Rings { size_t loadFromFile(const std::string& filepath, const struct timespec& now); std::vector > d_shards; - std::atomic d_blockingQueryInserts; - std::atomic d_blockingResponseInserts; - std::atomic d_deferredQueryInserts; - std::atomic d_deferredResponseInserts; + pdns::stat_t d_blockingQueryInserts; + pdns::stat_t d_blockingResponseInserts; + pdns::stat_t d_deferredQueryInserts; + pdns::stat_t d_deferredResponseInserts; private: size_t getShardId() diff --git a/pdns/dnsdist-snmp.cc b/pdns/dnsdist-snmp.cc index 53ac8051bd..6aedb06ee6 100644 --- a/pdns/dnsdist-snmp.cc +++ b/pdns/dnsdist-snmp.cc @@ -80,14 +80,14 @@ static int handleCounter64Stats(netsnmp_mib_handler* handler, return SNMP_ERR_GENERR; } - if (const auto& val = boost::get(&it->second)) { + if (const auto& val = boost::get(&it->second)) { return DNSDistSNMPAgent::setCounter64Value(requests, (*val)->load()); } return SNMP_ERR_GENERR; } -static void registerCounter64Stat(const char* name, const oid statOID[], size_t statOIDLength, DNSDistStats::stat_t* ptr) +static void registerCounter64Stat(const char* name, const oid statOID[], size_t statOIDLength, pdns::stat_t* ptr) { if (statOIDLength != OID_LENGTH(queriesOID)) { errlog("Invalid OID for SNMP Counter64 statistic %s", name); diff --git a/pdns/dnsdist-web.cc b/pdns/dnsdist-web.cc index 668aa7ce38..3f1b90c40e 100644 --- a/pdns/dnsdist-web.cc +++ b/pdns/dnsdist-web.cc @@ -375,7 +375,7 @@ static void handlePrometheus(const YaHTTP::Request& req, YaHTTP::Response& resp) output << "# TYPE " << prometheusMetricName << " " << prometheusTypeName << "\n"; output << prometheusMetricName << " "; - if (const auto& val = boost::get(&std::get<1>(e))) + if (const auto& val = boost::get(&std::get<1>(e))) output << (*val)->load(); else if (const auto& dval = boost::get(&std::get<1>(e))) output << **dval; @@ -740,7 +740,7 @@ static void handleJSONStats(const YaHTTP::Request& req, YaHTTP::Response& resp) for (const auto& e : g_stats.entries) { if (e.first == "special-memory-usage") continue; // Too expensive for get-all - if(const auto& val = boost::get(&e.second)) + if(const auto& val = boost::get(&e.second)) obj.insert({e.first, (double)(*val)->load()}); else if (const auto& dval = boost::get(&e.second)) obj.insert({e.first, (**dval)}); @@ -1050,7 +1050,7 @@ static void handleStatsOnly(const YaHTTP::Request& req, YaHTTP::Response& resp) if (item.first == "special-memory-usage") continue; // Too expensive for get-all - if(const auto& val = boost::get(&item.second)) { + if(const auto& val = boost::get(&item.second)) { doc.push_back(Json::object { { "type", "StatisticItem" }, { "name", item.first }, diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index 0731ee9a95..375f51a0a8 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -82,7 +82,6 @@ On the C++ side, both could be inherited from a class Rule and a class Action, on the Lua side we can't do that. */ -using std::atomic; using std::thread; bool g_verbose; @@ -1585,8 +1584,8 @@ uint16_t getRandomDNSID() } boost::optional g_maxTCPClientThreads{boost::none}; -std::atomic g_cacheCleaningDelay{60}; -std::atomic g_cacheCleaningPercentage{100}; +pdns::stat16_t g_cacheCleaningDelay{60}; +pdns::stat16_t g_cacheCleaningPercentage{100}; static void maintThread() { diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index 3ac73f9ac4..79349414ec 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -23,7 +23,6 @@ #include "config.h" #include "ext/luawrapper/include/LuaContext.hpp" -#include #include #include #include @@ -51,6 +50,7 @@ #include "tcpiohandler.hh" #include "uuid-utils.hh" #include "proxy-protocol.hh" +#include "stat_t.hh" void carbonDumpThread(); uint64_t uptimeOfProcess(const std::string& str); @@ -297,43 +297,10 @@ extern vector > g_confDelta; extern uint64_t getLatencyCount(const std::string&); +using pdns::stat_t; + struct DNSDistStats { -#define CPU_LEVEL1_DCACHE_LINESIZE 64 // Until we know better via configure/getconf - - class stat_t { - public: - typedef uint64_t base_t; - typedef std::atomic atomic_t; - stat_t() : stat_t(0) { - } - stat_t(const base_t x) { - new(&counter) atomic_t(x); - } - ~stat_t() { - reinterpret_cast(&counter)->~atomic_t(); - } - stat_t(const stat_t&) = delete; - base_t operator++(int) { - return (*reinterpret_cast(&counter))++; - } - base_t operator++() { - return ++(*reinterpret_cast(&counter)); - } - base_t operator+=(const stat_t& v) { - return (*reinterpret_cast(&counter)) += *reinterpret_cast(&v.counter); - } - base_t load() const { - return reinterpret_cast(&counter)->load(); - } - operator base_t() const { - return reinterpret_cast(&counter)->load(); - } - //const atomic_t& operator()() { return *reinterpret_cast(&counter); } - private: - typename std::aligned_storage::type counter; - }; - stat_t responses{0}; stat_t servfailResponses{0}; stat_t queries{0}; @@ -745,26 +712,26 @@ struct ClientState std::shared_ptr tlsFrontend{nullptr}; std::shared_ptr dohFrontend{nullptr}; std::string interface; - std::atomic queries{0}; - mutable std::atomic responses{0}; - std::atomic tcpDiedReadingQuery{0}; - std::atomic tcpDiedSendingResponse{0}; - std::atomic tcpGaveUp{0}; - std::atomic tcpClientTimeouts{0}; - std::atomic tcpDownstreamTimeouts{0}; - std::atomic tcpCurrentConnections{0}; - std::atomic tlsNewSessions{0}; // A new TLS session has been negotiated, no resumption - std::atomic tlsResumptions{0}; // A TLS session has been resumed, either via session id or via a TLS ticket - std::atomic tlsUnknownTicketKey{0}; // A TLS ticket has been presented but we don't have the associated key (might have expired) - std::atomic tlsInactiveTicketKey{0}; // A TLS ticket has been successfully resumed but the key is no longer active, we should issue a new one - std::atomic tls10queries{0}; // valid DNS queries received via TLSv1.0 - std::atomic tls11queries{0}; // valid DNS queries received via TLSv1.1 - std::atomic tls12queries{0}; // valid DNS queries received via TLSv1.2 - std::atomic tls13queries{0}; // valid DNS queries received via TLSv1.3 - std::atomic tlsUnknownqueries{0}; // valid DNS queries received via unknown TLS version - std::atomic tcpAvgQueriesPerConnection{0.0}; + stat_t queries{0}; + mutable stat_t responses{0}; + stat_t tcpDiedReadingQuery{0}; + stat_t tcpDiedSendingResponse{0}; + stat_t tcpGaveUp{0}; + stat_t tcpClientTimeouts{0}; + stat_t tcpDownstreamTimeouts{0}; + stat_t tcpCurrentConnections{0}; + stat_t tlsNewSessions{0}; // A new TLS session has been negotiated, no resumption + stat_t tlsResumptions{0}; // A TLS session has been resumed, either via session id or via a TLS ticket + stat_t tlsUnknownTicketKey{0}; // A TLS ticket has been presented but we don't have the associated key (might have expired) + stat_t tlsInactiveTicketKey{0}; // A TLS ticket has been successfully resumed but the key is no longer active, we should issue a new one + stat_t tls10queries{0}; // valid DNS queries received via TLSv1.0 + stat_t tls11queries{0}; // valid DNS queries received via TLSv1.1 + stat_t tls12queries{0}; // valid DNS queries received via TLSv1.2 + stat_t tls13queries{0}; // valid DNS queries received via TLSv1.3 + stat_t tlsUnknownqueries{0}; // valid DNS queries received via unknown TLS version + pdns::stat_t_trait tcpAvgQueriesPerConnection{0.0}; /* in ms */ - std::atomic tcpAvgConnectionDuration{0.0}; + pdns::stat_t_trait tcpAvgConnectionDuration{0.0}; size_t d_maxInFlightQueriesPerConn{1}; int udpFD{-1}; int tcpFD{-1}; @@ -839,9 +806,9 @@ struct ClientState class TCPClientCollection { std::vector d_tcpclientthreads; - std::atomic d_numthreads{0}; - std::atomic d_pos{0}; - std::atomic d_queued{0}; + stat_t d_numthreads{0}; + stat_t d_pos{0}; + stat_t d_queued{0}; const uint64_t d_maxthreads{0}; std::mutex d_mutex; int d_singlePipe[2]; @@ -925,25 +892,25 @@ struct DownstreamState QType checkType{QType::A}; uint16_t checkClass{QClass::IN}; std::atomic idOffset{0}; - std::atomic sendErrors{0}; - std::atomic outstanding{0}; - std::atomic reuseds{0}; - std::atomic queries{0}; - std::atomic responses{0}; + stat_t sendErrors{0}; + stat_t outstanding{0}; + stat_t reuseds{0}; + stat_t queries{0}; + stat_t responses{0}; struct { - std::atomic sendErrors{0}; - std::atomic reuseds{0}; - std::atomic queries{0}; + stat_t sendErrors{0}; + stat_t reuseds{0}; + stat_t queries{0}; } prev; - std::atomic tcpDiedSendingQuery{0}; - std::atomic tcpDiedReadingResponse{0}; - std::atomic tcpGaveUp{0}; - std::atomic tcpReadTimeouts{0}; - std::atomic tcpWriteTimeouts{0}; - std::atomic tcpCurrentConnections{0}; - std::atomic tcpAvgQueriesPerConnection{0.0}; + stat_t tcpDiedSendingQuery{0}; + stat_t tcpDiedReadingResponse{0}; + stat_t tcpGaveUp{0}; + stat_t tcpReadTimeouts{0}; + stat_t tcpWriteTimeouts{0}; + stat_t tcpCurrentConnections{0}; + pdns::stat_t_trait tcpAvgQueriesPerConnection{0.0}; /* in ms */ - std::atomic tcpAvgConnectionDuration{0.0}; + pdns::stat_t_trait tcpAvgConnectionDuration{0.0}; size_t socketsOffset{0}; size_t d_maxInFlightQueriesPerConn{1}; double queryLoad{0.0}; @@ -1048,7 +1015,7 @@ public: } virtual bool matches(const DNSQuestion* dq) const =0; virtual string toString() const = 0; - mutable std::atomic d_matches{0}; + mutable stat_t d_matches{0}; }; struct ServerPool @@ -1212,8 +1179,8 @@ extern uint64_t g_maxTCPQueuedConnections; extern size_t g_maxTCPQueriesPerConn; extern size_t g_maxTCPConnectionDuration; extern size_t g_maxTCPConnectionsPerClient; -extern std::atomic g_cacheCleaningDelay; -extern std::atomic g_cacheCleaningPercentage; +extern pdns::stat16_t g_cacheCleaningDelay; +extern pdns::stat16_t g_cacheCleaningPercentage; extern uint32_t g_staleCacheEntriesTTL; extern bool g_apiReadWrite; extern std::string g_apiConfigDirectory; diff --git a/pdns/dnsdistdist/Makefile.am b/pdns/dnsdistdist/Makefile.am index dd8d2e3bd1..06586f494b 100644 --- a/pdns/dnsdistdist/Makefile.am +++ b/pdns/dnsdistdist/Makefile.am @@ -205,6 +205,7 @@ dnsdist_SOURCES = \ sodcrypto.cc sodcrypto.hh \ sstuff.hh \ statnode.cc statnode.hh \ + stat_t.hh \ svc-records.cc svc-records.hh \ tcpiohandler-mplexer.hh \ tcpiohandler.cc tcpiohandler.hh \ @@ -258,6 +259,7 @@ testrunner_SOURCES = \ sodcrypto.cc \ sstuff.hh \ statnode.cc statnode.hh \ + stat_t.hh \ svc-records.cc svc-records.hh \ test-base64_cc.cc \ test-delaypipe_hh.cc \ diff --git a/pdns/dnsdistdist/stat_t.hh b/pdns/dnsdistdist/stat_t.hh new file mode 120000 index 0000000000..0b8289ce83 --- /dev/null +++ b/pdns/dnsdistdist/stat_t.hh @@ -0,0 +1 @@ +../stat_t.hh \ No newline at end of file diff --git a/pdns/doh.hh b/pdns/doh.hh index 09fcc71042..eba05c8040 100644 --- a/pdns/doh.hh +++ b/pdns/doh.hh @@ -23,6 +23,7 @@ #include "iputils.hh" #include "libssl.hh" #include "noinitvector.hh" +#include "stat_t.hh" struct DOHServerConfig; @@ -81,23 +82,23 @@ struct DOHFrontend uint32_t d_idleTimeout{30}; // HTTP idle timeout in seconds std::vector d_urls; - std::atomic d_httpconnects{0}; // number of TCP/IP connections established - std::atomic d_getqueries{0}; // valid DNS queries received via GET - std::atomic d_postqueries{0}; // valid DNS queries received via POST - std::atomic d_badrequests{0}; // request could not be converted to dns query - std::atomic d_errorresponses{0}; // dnsdist set 'error' on response - std::atomic d_redirectresponses{0}; // dnsdist set 'redirect' on response - std::atomic d_validresponses{0}; // valid responses sent out + pdns::stat_t d_httpconnects{0}; // number of TCP/IP connections established + pdns::stat_t d_getqueries{0}; // valid DNS queries received via GET + pdns::stat_t d_postqueries{0}; // valid DNS queries received via POST + pdns::stat_t d_badrequests{0}; // request could not be converted to dns query + pdns::stat_t d_errorresponses{0}; // dnsdist set 'error' on response + pdns::stat_t d_redirectresponses{0}; // dnsdist set 'redirect' on response + pdns::stat_t d_validresponses{0}; // valid responses sent out struct HTTPVersionStats { - std::atomic d_nbQueries{0}; // valid DNS queries received - std::atomic d_nb200Responses{0}; - std::atomic d_nb400Responses{0}; - std::atomic d_nb403Responses{0}; - std::atomic d_nb500Responses{0}; - std::atomic d_nb502Responses{0}; - std::atomic d_nbOtherResponses{0}; + pdns::stat_t d_nbQueries{0}; // valid DNS queries received + pdns::stat_t d_nb200Responses{0}; + pdns::stat_t d_nb400Responses{0}; + pdns::stat_t d_nb403Responses{0}; + pdns::stat_t d_nb500Responses{0}; + pdns::stat_t d_nb502Responses{0}; + pdns::stat_t d_nbOtherResponses{0}; }; HTTPVersionStats d_http1Stats; diff --git a/pdns/stat_t.hh b/pdns/stat_t.hh new file mode 100644 index 0000000000..2a765c26a6 --- /dev/null +++ b/pdns/stat_t.hh @@ -0,0 +1,77 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#pragma once + +#define CPU_LEVEL1_DCACHE_LINESIZE 64 // Until we know better via configure/getconf + +namespace pdns { + template + class stat_t_trait { + public: + typedef T base_t; + typedef std::atomic atomic_t; + + stat_t_trait() : stat_t_trait(base_t(0)) { + } + stat_t_trait(const base_t x) { + new(&counter) atomic_t(x); + } + ~stat_t_trait() { + reinterpret_cast(&counter)->~atomic_t(); + } + stat_t_trait(const stat_t_trait&) = delete; + base_t operator++(int) { + return (*reinterpret_cast(&counter))++; + } + base_t operator++() { + return ++(*reinterpret_cast(&counter)); + } + base_t operator--(int) { + return (*reinterpret_cast(&counter))--; + } + base_t operator--() { + return --(*reinterpret_cast(&counter)); + } + base_t operator+=(const stat_t_trait& v) { + return *reinterpret_cast(&counter) += *reinterpret_cast(&v.counter); + } + base_t operator-=(const stat_t_trait& v) { + return *reinterpret_cast(&counter) -= *reinterpret_cast(&v.counter); + } + base_t load() const { + return reinterpret_cast(&counter)->load(); + } + void store(base_t v) { + reinterpret_cast(&counter)->store(v); + } + operator base_t() const { + return reinterpret_cast(&counter)->load(); + } + + private: + typename std::aligned_storage::type counter; + }; + + typedef stat_t_trait stat_t; + typedef stat_t_trait stat32_t; + typedef stat_t_trait stat16_t; +}