From 69603a83fab9d0d7f3fdce0fd4a3906ca21f6003 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Thu, 12 Sep 2024 17:02:28 +0000 Subject: [PATCH] stats: miscellaneous changes and housekeeping - `timing` cannot contain a negative value, change to `uint64_t` - remove `sendDouble`, use template specialization of `Send` instead, that can be reused as `send` - rename `value` in `count()` to `delta` - add more comments `gaugeDouble` has been kept around because utilizing templates for it would require us to either write template specializations for every kind of `gauge` value (implicit conversions will not save us from this) or move all logic to the header, neither option seems desirable. --- src/net.cpp | 2 +- src/stats/client.cpp | 26 +++++++++++++++++++------- src/stats/client.h | 34 +++++++++++++++++----------------- 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index c3a51a103a..98daa17117 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -4145,7 +4145,7 @@ void CConnman::RecordBytesRecv(uint64_t bytes) { nTotalBytesRecv += bytes; ::g_stats_client->count("bandwidth.bytesReceived", bytes, 0.1f); - ::g_stats_client->gauge("bandwidth.totalBytesReceived", nTotalBytesRecv, 0.01f); + ::g_stats_client->gauge("bandwidth.totalBytesReceived", nTotalBytesRecv.load(), 0.01f); } void CConnman::RecordBytesSent(uint64_t bytes) diff --git a/src/stats/client.cpp b/src/stats/client.cpp index 90aa940c51..df5c3ea027 100644 --- a/src/stats/client.cpp +++ b/src/stats/client.cpp @@ -49,6 +49,12 @@ static constexpr float EPSILON{0.0001f}; /** Delimiter segmenting two fully formed Statsd messages */ static constexpr char STATSD_MSG_DELIMITER{'\n'}; +/** Character used to denote Statsd message type as count */ +static constexpr char STATSD_METRIC_COUNT[]{"c"}; +/** Character used to denote Statsd message type as gauge */ +static constexpr char STATSD_METRIC_GAUGE[]{"g"}; +/** Characters used to denote Statsd message type as timing */ +static constexpr char STATSD_METRIC_TIMING[]{"ms"}; } // anonymous namespace std::unique_ptr g_stats_client; @@ -82,28 +88,28 @@ bool StatsdClient::dec(const std::string& key, float sample_rate) { return count bool StatsdClient::inc(const std::string& key, float sample_rate) { return count(key, 1, sample_rate); } -bool StatsdClient::count(const std::string& key, int64_t value, float sample_rate) +bool StatsdClient::count(const std::string& key, int64_t delta, float sample_rate) { - return send(key, value, "c", sample_rate); + return send(key, delta, STATSD_METRIC_COUNT, sample_rate); } bool StatsdClient::gauge(const std::string& key, int64_t value, float sample_rate) { - return send(key, value, "g", sample_rate); + return send(key, value, STATSD_METRIC_GAUGE, sample_rate); } bool StatsdClient::gaugeDouble(const std::string& key, double value, float sample_rate) { - return sendDouble(key, value, "g", sample_rate); + return send(key, value, STATSD_METRIC_GAUGE, sample_rate); } -bool StatsdClient::timing(const std::string& key, int64_t ms, float sample_rate) +bool StatsdClient::timing(const std::string& key, uint64_t ms, float sample_rate) { - return send(key, ms, "ms", sample_rate); + return send(key, ms, STATSD_METRIC_TIMING, sample_rate); } template -bool StatsdClient::Send(const std::string& key, T1 value, const std::string& type, float sample_rate) +bool StatsdClient::send(const std::string& key, T1 value, const std::string& type, float sample_rate) { static_assert(std::is_arithmetic::value, "Must specialize to an arithmetic type"); @@ -137,3 +143,9 @@ bool StatsdClient::Send(const std::string& key, T1 value, const std::string& typ return true; } + +template bool StatsdClient::send(const std::string& key, double value, const std::string& type, float sample_rate); +template bool StatsdClient::send(const std::string& key, int32_t value, const std::string& type, float sample_rate); +template bool StatsdClient::send(const std::string& key, int64_t value, const std::string& type, float sample_rate); +template bool StatsdClient::send(const std::string& key, uint32_t value, const std::string& type, float sample_rate); +template bool StatsdClient::send(const std::string& key, uint64_t value, const std::string& type, float sample_rate); diff --git a/src/stats/client.h b/src/stats/client.h index bfc1d67f11..fb152daec8 100644 --- a/src/stats/client.h +++ b/src/stats/client.h @@ -15,10 +15,15 @@ class RawSender; +/** Default state of Statsd enablement */ static constexpr bool DEFAULT_STATSD_ENABLE{false}; +/** Default port used to connect to a Statsd server */ static constexpr uint16_t DEFAULT_STATSD_PORT{8125}; +/** Default host assumed to be running a Statsd server */ static const std::string DEFAULT_STATSD_HOST{"127.0.0.1"}; +/** Default suffix appended to Statsd message keys */ static const std::string DEFAULT_STATSD_HOSTNAME{""}; +/** Default prefix prepended to Statsd message keys */ static const std::string DEFAULT_STATSD_NAMESPACE{""}; /** Default number of milliseconds between flushing a queue of messages */ @@ -40,39 +45,34 @@ public: ~StatsdClient(); public: - bool inc(const std::string& key, float sample_rate = 1.f); + /* Statsd-defined APIs */ bool dec(const std::string& key, float sample_rate = 1.f); - bool count(const std::string& key, int64_t value, float sample_rate = 1.f); + bool inc(const std::string& key, float sample_rate = 1.f); + bool count(const std::string& key, int64_t delta, float sample_rate = 1.f); bool gauge(const std::string& key, int64_t value, float sample_rate = 1.f); bool gaugeDouble(const std::string& key, double value, float sample_rate = 1.f); - bool timing(const std::string& key, int64_t ms, float sample_rate = 1.f); + bool timing(const std::string& key, uint64_t ms, float sample_rate = 1.f); - /* (Low Level Api) manually send a message - * type = "c", "g" or "ms" - */ - bool send(const std::string& key, int64_t value, const std::string& type, float sample_rate = 1.f) - { - return Send(key, value, type, sample_rate); - } - bool sendDouble(const std::string& key, double value, const std::string& type, float sample_rate = 1.f) - { - return Send(key, value, type, sample_rate); - } - -private: + /* Statsd-compatible APIs */ template - bool Send(const std::string& key, T1 value, const std::string& type, float sample_rate); + bool send(const std::string& key, T1 value, const std::string& type, float sample_rate = 1.f); private: + /* Mutex to protect PRNG */ mutable Mutex cs; + /* PRNG used to dice-roll messages that are 0 < f < 1 */ mutable FastRandomContext insecure_rand GUARDED_BY(cs); + /* Broadcasts messages crafted by StatsdClient */ std::unique_ptr m_sender{nullptr}; + /* Phrase prepended to keys */ const std::string m_nodename; + /* Phrase appended to keys */ const std::string m_ns; }; +/** Global smart pointer containing StatsdClient instance */ extern std::unique_ptr g_stats_client; #endif // BITCOIN_STATS_CLIENT_H