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.
This commit is contained in:
Kittywhiskers Van Gogh 2024-09-12 17:02:28 +00:00
parent 3e12ac0e09
commit 69603a83fa
No known key found for this signature in database
GPG Key ID: 30CD0C065E5C4AAD
3 changed files with 37 additions and 25 deletions

View File

@ -4145,7 +4145,7 @@ void CConnman::RecordBytesRecv(uint64_t bytes)
{ {
nTotalBytesRecv += bytes; nTotalBytesRecv += bytes;
::g_stats_client->count("bandwidth.bytesReceived", bytes, 0.1f); ::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) void CConnman::RecordBytesSent(uint64_t bytes)

View File

@ -49,6 +49,12 @@ static constexpr float EPSILON{0.0001f};
/** Delimiter segmenting two fully formed Statsd messages */ /** Delimiter segmenting two fully formed Statsd messages */
static constexpr char STATSD_MSG_DELIMITER{'\n'}; 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 } // anonymous namespace
std::unique_ptr<StatsdClient> g_stats_client; std::unique_ptr<StatsdClient> 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::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) 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) 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 <typename T1> template <typename T1>
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<T1>::value, "Must specialize to an arithmetic type"); static_assert(std::is_arithmetic<T1>::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; 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);

View File

@ -15,10 +15,15 @@
class RawSender; class RawSender;
/** Default state of Statsd enablement */
static constexpr bool DEFAULT_STATSD_ENABLE{false}; static constexpr bool DEFAULT_STATSD_ENABLE{false};
/** Default port used to connect to a Statsd server */
static constexpr uint16_t DEFAULT_STATSD_PORT{8125}; 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"}; 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{""}; static const std::string DEFAULT_STATSD_HOSTNAME{""};
/** Default prefix prepended to Statsd message keys */
static const std::string DEFAULT_STATSD_NAMESPACE{""}; static const std::string DEFAULT_STATSD_NAMESPACE{""};
/** Default number of milliseconds between flushing a queue of messages */ /** Default number of milliseconds between flushing a queue of messages */
@ -40,39 +45,34 @@ public:
~StatsdClient(); ~StatsdClient();
public: 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 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 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 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 /* Statsd-compatible APIs */
* 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:
template <typename T1> template <typename T1>
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: private:
/* Mutex to protect PRNG */
mutable Mutex cs; mutable Mutex cs;
/* PRNG used to dice-roll messages that are 0 < f < 1 */
mutable FastRandomContext insecure_rand GUARDED_BY(cs); mutable FastRandomContext insecure_rand GUARDED_BY(cs);
/* Broadcasts messages crafted by StatsdClient */
std::unique_ptr<RawSender> m_sender{nullptr}; std::unique_ptr<RawSender> m_sender{nullptr};
/* Phrase prepended to keys */
const std::string m_nodename; const std::string m_nodename;
/* Phrase appended to keys */
const std::string m_ns; const std::string m_ns;
}; };
/** Global smart pointer containing StatsdClient instance */
extern std::unique_ptr<StatsdClient> g_stats_client; extern std::unique_ptr<StatsdClient> g_stats_client;
#endif // BITCOIN_STATS_CLIENT_H #endif // BITCOIN_STATS_CLIENT_H