mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 03:52:49 +01:00
stats: deduplicate send
and sendDouble
logic
Additionally, let's remove the key sanitation logic since keys are hardcoded. Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
This commit is contained in:
parent
bf44fc3bf6
commit
3e12ac0e09
@ -43,26 +43,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <cstdio>
|
||||
#include <random>
|
||||
|
||||
namespace {
|
||||
/** Threshold below which a value is considered effectively zero */
|
||||
static constexpr float EPSILON{0.0001f};
|
||||
|
||||
/** Delimiter segmenting two fully formed Statsd messages */
|
||||
static constexpr char STATSD_MSG_DELIMITER{'\n'};
|
||||
} // anonymous namespace
|
||||
|
||||
std::unique_ptr<StatsdClient> g_stats_client;
|
||||
|
||||
bool StatsdClient::ShouldSend(float sample_rate)
|
||||
{
|
||||
sample_rate = std::clamp(sample_rate, 0.f, 1.f);
|
||||
|
||||
constexpr float EPSILON{0.0001f};
|
||||
/* If sample rate is 1, we should always send */
|
||||
if (std::fabs(sample_rate - 1.f) < EPSILON) return true;
|
||||
/* If sample rate is 0, we should never send */
|
||||
if (std::fabs(sample_rate) < EPSILON) return false;
|
||||
|
||||
/* Sample rate is >0 and <1, roll the dice */
|
||||
LOCK(cs);
|
||||
return sample_rate > std::uniform_real_distribution<float>(0.f, 1.f)(insecure_rand);
|
||||
}
|
||||
|
||||
StatsdClient::StatsdClient(const std::string& host, uint16_t port, uint64_t batch_size, uint64_t interval_ms,
|
||||
const std::string& nodename, const std::string& ns, bool enabled) :
|
||||
m_nodename{nodename},
|
||||
@ -88,16 +78,6 @@ StatsdClient::StatsdClient(const std::string& host, uint16_t port, uint64_t batc
|
||||
|
||||
StatsdClient::~StatsdClient() {}
|
||||
|
||||
/* will change the original string */
|
||||
void StatsdClient::cleanup(std::string& key)
|
||||
{
|
||||
auto pos = key.find_first_of(":|@");
|
||||
while (pos != std::string::npos) {
|
||||
key[pos] = '_';
|
||||
pos = key.find_first_of(":|@");
|
||||
}
|
||||
}
|
||||
|
||||
bool StatsdClient::dec(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); }
|
||||
@ -122,56 +102,34 @@ bool StatsdClient::timing(const std::string& key, int64_t ms, float sample_rate)
|
||||
return send(key, ms, "ms", sample_rate);
|
||||
}
|
||||
|
||||
bool StatsdClient::send(std::string key, int64_t value, const std::string& type, float sample_rate)
|
||||
template <typename T1>
|
||||
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");
|
||||
|
||||
if (!m_sender) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ShouldSend(sample_rate)) {
|
||||
// Not our turn to send but report that we have
|
||||
// Determine if we should send the message at all but claim that we did even if we don't
|
||||
sample_rate = std::clamp(sample_rate, 0.f, 1.f);
|
||||
bool always_send = std::fabs(sample_rate - 1.f) < EPSILON;
|
||||
bool never_send = std::fabs(sample_rate) < EPSILON;
|
||||
if (never_send || (!always_send &&
|
||||
WITH_LOCK(cs, return sample_rate < std::uniform_real_distribution<float>(0.f, 1.f)(insecure_rand)))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// partition stats by node name if set
|
||||
if (!m_nodename.empty()) key = key + "." + m_nodename;
|
||||
|
||||
cleanup(key);
|
||||
|
||||
RawMessage msg{strprintf("%s%s:%d|%s", m_ns, key, value, type)};
|
||||
if (sample_rate < 1.f) {
|
||||
msg += strprintf("|@%.2f", sample_rate);
|
||||
}
|
||||
|
||||
if (auto error_opt = m_sender->Send(msg); error_opt.has_value()) {
|
||||
LogPrintf("ERROR: %s.\n", error_opt.value());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StatsdClient::sendDouble(std::string key, double value, const std::string& type, float sample_rate)
|
||||
{
|
||||
if (!m_sender) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ShouldSend(sample_rate)) {
|
||||
// Not our turn to send but report that we have
|
||||
return true;
|
||||
}
|
||||
|
||||
// partition stats by node name if set
|
||||
if (!m_nodename.empty()) key = key + "." + m_nodename;
|
||||
|
||||
cleanup(key);
|
||||
|
||||
// Construct the message and if our message isn't always-send, report the sample rate
|
||||
RawMessage msg{strprintf("%s%s:%f|%s", m_ns, key, value, type)};
|
||||
if (sample_rate < 1.f) {
|
||||
if (!always_send) {
|
||||
msg += strprintf("|@%.2f", sample_rate);
|
||||
}
|
||||
|
||||
// Send it and report an error if we encounter one
|
||||
if (auto error_opt = m_sender->Send(msg); error_opt.has_value()) {
|
||||
LogPrintf("ERROR: %s.\n", error_opt.value());
|
||||
return false;
|
||||
|
@ -50,12 +50,18 @@ public:
|
||||
/* (Low Level Api) manually send a message
|
||||
* type = "c", "g" or "ms"
|
||||
*/
|
||||
bool send(std::string key, int64_t value, const std::string& type, float sample_rate);
|
||||
bool sendDouble(std::string key, double value, const std::string& type, float sample_rate);
|
||||
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:
|
||||
void cleanup(std::string& key);
|
||||
bool ShouldSend(float sample_rate);
|
||||
template <typename T1>
|
||||
bool Send(const std::string& key, T1 value, const std::string& type, float sample_rate);
|
||||
|
||||
private:
|
||||
mutable Mutex cs;
|
||||
|
Loading…
Reference in New Issue
Block a user