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 <cstdio>
|
||||||
#include <random>
|
#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 */
|
/** Delimiter segmenting two fully formed Statsd messages */
|
||||||
static constexpr char STATSD_MSG_DELIMITER{'\n'};
|
static constexpr char STATSD_MSG_DELIMITER{'\n'};
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
std::unique_ptr<StatsdClient> g_stats_client;
|
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,
|
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) :
|
const std::string& nodename, const std::string& ns, bool enabled) :
|
||||||
m_nodename{nodename},
|
m_nodename{nodename},
|
||||||
@ -88,16 +78,6 @@ StatsdClient::StatsdClient(const std::string& host, uint16_t port, uint64_t batc
|
|||||||
|
|
||||||
StatsdClient::~StatsdClient() {}
|
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::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); }
|
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);
|
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) {
|
if (!m_sender) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ShouldSend(sample_rate)) {
|
// Determine if we should send the message at all but claim that we did even if we don't
|
||||||
// Not our turn to send but report that we have
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// partition stats by node name if set
|
// partition stats by node name if set
|
||||||
if (!m_nodename.empty()) key = key + "." + m_nodename;
|
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:%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);
|
|
||||||
|
|
||||||
RawMessage msg{strprintf("%s%s:%f|%s", m_ns, key, value, type)};
|
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);
|
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()) {
|
if (auto error_opt = m_sender->Send(msg); error_opt.has_value()) {
|
||||||
LogPrintf("ERROR: %s.\n", error_opt.value());
|
LogPrintf("ERROR: %s.\n", error_opt.value());
|
||||||
return false;
|
return false;
|
||||||
|
@ -50,12 +50,18 @@ public:
|
|||||||
/* (Low Level Api) manually send a message
|
/* (Low Level Api) manually send a message
|
||||||
* type = "c", "g" or "ms"
|
* type = "c", "g" or "ms"
|
||||||
*/
|
*/
|
||||||
bool send(std::string key, int64_t 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)
|
||||||
bool sendDouble(std::string key, double value, const std::string& type, float sample_rate);
|
{
|
||||||
|
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:
|
private:
|
||||||
void cleanup(std::string& key);
|
template <typename T1>
|
||||||
bool ShouldSend(float sample_rate);
|
bool Send(const std::string& key, T1 value, const std::string& type, float sample_rate);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable Mutex cs;
|
mutable Mutex cs;
|
||||||
|
Loading…
Reference in New Issue
Block a user