From: Otto Date: Fri, 19 Feb 2021 09:24:48 +0000 (+0100) Subject: Start using new Histogram class and refactor accounting to always X-Git-Tag: dnsdist-1.6.0-alpha2~18^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a71665e51401389cbedc02b42148cd06729d2efa;p=thirdparty%2Fpdns.git Start using new Histogram class and refactor accounting to always work in microseconds instead of a mixed set. --- diff --git a/pdns/histogram.hh b/pdns/histogram.hh index d5d3202295..34f429d7c6 100644 --- a/pdns/histogram.hh +++ b/pdns/histogram.hh @@ -1,9 +1,29 @@ +/* + * 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 #include #include #include -#include namespace pdns { @@ -11,8 +31,8 @@ namespace pdns { struct Bucket { std::string d_name; - uint64_t d_boundary; - uint64_t d_count; + uint64_t d_boundary{0}; + uint64_t d_count{0}; }; inline bool operator<(uint64_t b, const Bucket& bu) @@ -23,15 +43,14 @@ inline bool operator<(uint64_t b, const Bucket& bu) struct AtomicBucket { - // We need the constrcutors in this case, since atomics have a disabled - // copy constructor. + // We need the constructors in this case, since atomics have a disabled copy constructor. AtomicBucket() {} AtomicBucket(std::string name, uint64_t boundary, uint64_t val) : d_name(std::move(name)), d_boundary(boundary), d_count(val) {} AtomicBucket(const AtomicBucket& rhs) : d_name(rhs.d_name), d_boundary(rhs.d_boundary), d_count(rhs.d_count.load()) {} std::string d_name; - uint64_t d_boundary; - std::atomic d_count; + uint64_t d_boundary{0}; + std::atomic d_count{0}; }; inline bool operator<(uint64_t b, const AtomicBucket& bu) @@ -57,12 +76,10 @@ public: } d_buckets.reserve(boundaries.size() + 1); for (auto b: boundaries) { - // to_string gives too many .00000's - std::ostringstream str; - str << prefix << "le-" << b; - d_buckets.push_back(B{str.str(), b, 0}); + std::string str = prefix + "le-" + std::to_string(b); + d_buckets.push_back(B{str, b, 0}); } - // everything above last boundary, plus NaN, Inf etc + // everything above last boundary d_buckets.push_back(B{prefix + "le-max", std::numeric_limits::max(), 0}); } diff --git a/pdns/misc.hh b/pdns/misc.hh index a6c926da70..3ee14f8ad7 100644 --- a/pdns/misc.hh +++ b/pdns/misc.hh @@ -312,9 +312,9 @@ inline float makeFloat(const struct timeval& tv) { return tv.tv_sec + tv.tv_usec/1000000.0f; } -inline double makeDouble(const struct timeval& tv) +inline uint64_t uSec(const struct timeval& tv) { - return tv.tv_sec + tv.tv_usec/1000000.0; + return tv.tv_sec * 1000000 + tv.tv_usec; } inline bool operator<(const struct timeval& lhs, const struct timeval& rhs) diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index c330997aa5..81baa50558 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -2142,11 +2142,13 @@ static void startDoResolve(void *p) finishTCPReply(dc, hadError, true); } - double spent = makeDouble(sr.getNow() - dc->d_now); + // Originally this code used a mix of floats, doubles, uint64_t with different units. + // Now it always uses an integral number of microseconds, expect for avarages, which are using doubles + uint64_t spentUsec = uSec(sr.getNow() - dc->d_now); if (!g_quiet) { g_log<getTid()<<"/"<numProcesses()<<"] answer to "<<(dc->d_mdp.d_header.rd?"":"non-rd ")<<"question '"<d_mdp.d_qname<<"|"<d_mdp.d_qtype); g_log<<"': "<ancount)<<" answers, "<arcount)<<" additional, took "< servFails; std::atomic nxDomains; std::atomic noErrors; - std::atomic answers0_1, answers1_10, answers10_100, answers100_1000, answersSlow; - std::atomic auth4Answers0_1, auth4Answers1_10, auth4Answers10_100, auth4Answers100_1000, auth4AnswersSlow; - std::atomic auth6Answers0_1, auth6Answers1_10, auth6Answers10_100, auth6Answers100_1000, auth6AnswersSlow; - std::atomic ourtime0_1, ourtime1_2, ourtime2_4, ourtime4_8, ourtime8_16, ourtime16_32, ourtimeSlow; + pdns::AtomicHistogram answers; + pdns::AtomicHistogram auth4Answers; + pdns::AtomicHistogram auth6Answers; + pdns::AtomicHistogram ourtime; std::atomic avgLatencyUsec; std::atomic avgLatencyOursUsec; std::atomic qcounter; // not increased for unauth packets @@ -1021,6 +1022,14 @@ struct RecursorStats std::atomic rebalancedQueries{0}; std::atomic proxyProtocolInvalidCount{0}; std::atomic nodLookupsDroppedOversize{0}; + + RecursorStats() : + answers("answers", { 1000, 10000, 100000, 1000000 }), + auth4Answers("answers", { 1000, 10000, 100000, 1000000 }), + auth6Answers("answers", { 1000, 10000, 100000, 1000000 }), + ourtime("ourtime", { 1000, 2000, 4000, 8000, 16000, 32000 }) + { + } }; //! represents a running TCP/IP client session