Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(stats): modernize statsd::StatsdClient, make global unique_ptr #5167

Merged
merged 13 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 26 additions & 16 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ void PrepareShutdown(NodeContext& node)
node.banman.reset();
node.addrman.reset();
node.netgroupman.reset();
::g_stats_client.reset();

if (node.mempool && node.mempool->IsLoaded() && node.args->GetBoolArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) {
DumpMempool(*node.mempool);
Expand Down Expand Up @@ -839,12 +840,12 @@ static void PeriodicStats(ArgsManager& args, ChainstateManager& chainman, const
CCoinsStats stats{CoinStatsHashType::NONE};
chainman.ActiveChainstate().ForceFlushStateToDisk();
if (WITH_LOCK(cs_main, return GetUTXOStats(&chainman.ActiveChainstate().CoinsDB(), std::ref(chainman.m_blockman), stats, RpcInterruptionPoint, chainman.ActiveChain().Tip()))) {
statsClient.gauge("utxoset.tx", stats.nTransactions, 1.0f);
statsClient.gauge("utxoset.txOutputs", stats.nTransactionOutputs, 1.0f);
statsClient.gauge("utxoset.dbSizeBytes", stats.nDiskSize, 1.0f);
statsClient.gauge("utxoset.blockHeight", stats.nHeight, 1.0f);
::g_stats_client->gauge("utxoset.tx", stats.nTransactions, 1.0f);
::g_stats_client->gauge("utxoset.txOutputs", stats.nTransactionOutputs, 1.0f);
::g_stats_client->gauge("utxoset.dbSizeBytes", stats.nDiskSize, 1.0f);
::g_stats_client->gauge("utxoset.blockHeight", stats.nHeight, 1.0f);
if (stats.total_amount.has_value()) {
statsClient.gauge("utxoset.totalAmount", (double)stats.total_amount.value() / (double)COIN, 1.0f);
::g_stats_client->gauge("utxoset.totalAmount", (double)stats.total_amount.value() / (double)COIN, 1.0f);
}
} else {
// something went wrong
Expand All @@ -866,22 +867,22 @@ static void PeriodicStats(ArgsManager& args, ChainstateManager& chainman, const
int64_t timeDiff = maxTime - minTime;
double nNetworkHashPS = workDiff.getdouble() / timeDiff;

statsClient.gaugeDouble("network.hashesPerSecond", nNetworkHashPS);
statsClient.gaugeDouble("network.terahashesPerSecond", nNetworkHashPS / 1e12);
statsClient.gaugeDouble("network.petahashesPerSecond", nNetworkHashPS / 1e15);
statsClient.gaugeDouble("network.exahashesPerSecond", nNetworkHashPS / 1e18);
::g_stats_client->gaugeDouble("network.hashesPerSecond", nNetworkHashPS);
::g_stats_client->gaugeDouble("network.terahashesPerSecond", nNetworkHashPS / 1e12);
::g_stats_client->gaugeDouble("network.petahashesPerSecond", nNetworkHashPS / 1e15);
::g_stats_client->gaugeDouble("network.exahashesPerSecond", nNetworkHashPS / 1e18);
// No need for cs_main, we never use null tip here
statsClient.gaugeDouble("network.difficulty", (double)GetDifficulty(tip));
::g_stats_client->gaugeDouble("network.difficulty", (double)GetDifficulty(tip));

statsClient.gauge("transactions.txCacheSize", WITH_LOCK(cs_main, return chainman.ActiveChainstate().CoinsTip().GetCacheSize()), 1.0f);
statsClient.gauge("transactions.totalTransactions", tip->nChainTx, 1.0f);
::g_stats_client->gauge("transactions.txCacheSize", WITH_LOCK(cs_main, return chainman.ActiveChainstate().CoinsTip().GetCacheSize()), 1.0f);
::g_stats_client->gauge("transactions.totalTransactions", tip->nChainTx, 1.0f);

{
LOCK(mempool.cs);
statsClient.gauge("transactions.mempool.totalTransactions", mempool.size(), 1.0f);
statsClient.gauge("transactions.mempool.totalTxBytes", (int64_t) mempool.GetTotalTxSize(), 1.0f);
statsClient.gauge("transactions.mempool.memoryUsageBytes", (int64_t) mempool.DynamicMemoryUsage(), 1.0f);
statsClient.gauge("transactions.mempool.minFeePerKb", mempool.GetMinFee(args.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFeePerK(), 1.0f);
::g_stats_client->gauge("transactions.mempool.totalTransactions", mempool.size(), 1.0f);
::g_stats_client->gauge("transactions.mempool.totalTxBytes", (int64_t) mempool.GetTotalTxSize(), 1.0f);
::g_stats_client->gauge("transactions.mempool.memoryUsageBytes", (int64_t) mempool.DynamicMemoryUsage(), 1.0f);
::g_stats_client->gauge("transactions.mempool.minFeePerKb", mempool.GetMinFee(args.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFeePerK(), 1.0f);
}
}

Expand Down Expand Up @@ -1524,6 +1525,15 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
fDiscover = args.GetBoolArg("-discover", true);
const bool ignores_incoming_txs{args.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)};

// We need to initialize g_stats_client early as currently, g_stats_client is called
// regardless of whether transmitting stats are desirable or not and if
// g_stats_client isn't present when that attempt is made, the client will crash.
::g_stats_client = std::make_unique<statsd::StatsdClient>(args.GetArg("-statshost", DEFAULT_STATSD_HOST),
args.GetArg("-statshostname", DEFAULT_STATSD_HOSTNAME),
args.GetArg("-statsport", DEFAULT_STATSD_PORT),
args.GetArg("-statsns", DEFAULT_STATSD_NAMESPACE),
args.GetBoolArg("-statsenabled", DEFAULT_STATSD_ENABLE));

{

// Read asmap file if configured
Expand Down
40 changes: 20 additions & 20 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
/*inbound_onion=*/false,
std::move(i2p_transient_session));
pnode->AddRef();
statsClient.inc("peers.connect", 1.0f);
::g_stats_client->inc("peers.connect", 1.0f);

// We're making a new connection, harvest entropy from the time (and our peer count)
RandAddEvent((uint32_t)id);
Expand Down Expand Up @@ -666,7 +666,7 @@ void CNode::CloseSocketDisconnect(CConnman* connman)
m_sock.reset();
m_i2p_sam_session.reset();

statsClient.inc("peers.disconnect", 1.0f);
::g_stats_client->inc("peers.disconnect", 1.0f);
}

void CConnman::AddWhitelistPermissionFlags(NetPermissionFlags& flags, const CNetAddr &addr) const {
Expand Down Expand Up @@ -817,7 +817,7 @@ bool CNode::ReceiveMsgBytes(Span<const uint8_t> msg_bytes, bool& complete)
}
assert(i != mapRecvBytesPerMsgType.end());
i->second += msg.m_raw_message_size;
statsClient.count("bandwidth.message." + std::string(msg.m_type) + ".bytesReceived", msg.m_raw_message_size, 1.0f);
::g_stats_client->count("bandwidth.message." + std::string(msg.m_type) + ".bytesReceived", msg.m_raw_message_size, 1.0f);

// push the message to the process queue,
vRecvMsg.push_back(std::move(msg));
Expand Down Expand Up @@ -1741,20 +1741,20 @@ void CConnman::CalculateNumConnectionsChangedStats()
torNodes++;
const auto last_ping_time = count_microseconds(pnode->m_last_ping_time);
if (last_ping_time > 0)
statsClient.timing("peers.ping_us", last_ping_time, 1.0f);
::g_stats_client->timing("peers.ping_us", last_ping_time, 1.0f);
}
for (const std::string &msg : getAllNetMessageTypes()) {
statsClient.gauge("bandwidth.message." + msg + ".totalBytesReceived", mapRecvBytesMsgStats[msg], 1.0f);
statsClient.gauge("bandwidth.message." + msg + ".totalBytesSent", mapSentBytesMsgStats[msg], 1.0f);
::g_stats_client->gauge("bandwidth.message." + msg + ".totalBytesReceived", mapRecvBytesMsgStats[msg], 1.0f);
::g_stats_client->gauge("bandwidth.message." + msg + ".totalBytesSent", mapSentBytesMsgStats[msg], 1.0f);
}
statsClient.gauge("peers.totalConnections", nPrevNodeCount, 1.0f);
statsClient.gauge("peers.spvNodeConnections", spvNodes, 1.0f);
statsClient.gauge("peers.fullNodeConnections", fullNodes, 1.0f);
statsClient.gauge("peers.inboundConnections", inboundNodes, 1.0f);
statsClient.gauge("peers.outboundConnections", outboundNodes, 1.0f);
statsClient.gauge("peers.ipv4Connections", ipv4Nodes, 1.0f);
statsClient.gauge("peers.ipv6Connections", ipv6Nodes, 1.0f);
statsClient.gauge("peers.torConnections", torNodes, 1.0f);
::g_stats_client->gauge("peers.totalConnections", nPrevNodeCount, 1.0f);
::g_stats_client->gauge("peers.spvNodeConnections", spvNodes, 1.0f);
::g_stats_client->gauge("peers.fullNodeConnections", fullNodes, 1.0f);
::g_stats_client->gauge("peers.inboundConnections", inboundNodes, 1.0f);
::g_stats_client->gauge("peers.outboundConnections", outboundNodes, 1.0f);
::g_stats_client->gauge("peers.ipv4Connections", ipv4Nodes, 1.0f);
::g_stats_client->gauge("peers.ipv6Connections", ipv6Nodes, 1.0f);
::g_stats_client->gauge("peers.torConnections", torNodes, 1.0f);
}

bool CConnman::ShouldRunInactivityChecks(const CNode& node, std::chrono::seconds now) const
Expand Down Expand Up @@ -4124,8 +4124,8 @@ bool CConnman::DisconnectNode(NodeId id)
void CConnman::RecordBytesRecv(uint64_t bytes)
{
nTotalBytesRecv += bytes;
statsClient.count("bandwidth.bytesReceived", bytes, 0.1f);
statsClient.gauge("bandwidth.totalBytesReceived", nTotalBytesRecv, 0.01f);
::g_stats_client->count("bandwidth.bytesReceived", bytes, 0.1f);
::g_stats_client->gauge("bandwidth.totalBytesReceived", nTotalBytesRecv, 0.01f);
}

void CConnman::RecordBytesSent(uint64_t bytes)
Expand All @@ -4134,8 +4134,8 @@ void CConnman::RecordBytesSent(uint64_t bytes)
LOCK(m_total_bytes_sent_mutex);

nTotalBytesSent += bytes;
statsClient.count("bandwidth.bytesSent", bytes, 0.01f);
statsClient.gauge("bandwidth.totalBytesSent", nTotalBytesSent, 0.01f);
::g_stats_client->count("bandwidth.bytesSent", bytes, 0.01f);
::g_stats_client->gauge("bandwidth.totalBytesSent", nTotalBytesSent, 0.01f);

const auto now = GetTime<std::chrono::seconds>();
if (nMaxOutboundCycleStartTime + MAX_UPLOAD_TIMEFRAME < now)
Expand Down Expand Up @@ -4291,8 +4291,8 @@ void CConnman::PushMessage(CNode* pnode, CSerializedNetMsg&& msg)
msg.data.data()
);

statsClient.count(strprintf("bandwidth.message.%s.bytesSent", msg.m_type), nMessageSize, 1.0f);
statsClient.inc(strprintf("message.sent.%s", msg.m_type), 1.0f);
::g_stats_client->count(strprintf("bandwidth.message.%s.bytesSent", msg.m_type), nMessageSize, 1.0f);
::g_stats_client->inc(strprintf("message.sent.%s", msg.m_type), 1.0f);

{
LOCK(pnode->cs_vSend);
Expand Down
10 changes: 5 additions & 5 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1688,9 +1688,9 @@ void PeerManagerImpl::Misbehaving(const NodeId pnode, const int howmuch, const s
if (score_now >= DISCOURAGEMENT_THRESHOLD && score_before < DISCOURAGEMENT_THRESHOLD) {
warning = " DISCOURAGE THRESHOLD EXCEEDED";
peer->m_should_discourage = true;
statsClient.inc("misbehavior.banned", 1.0f);
::g_stats_client->inc("misbehavior.banned", 1.0f);
} else {
statsClient.count("misbehavior.amount", howmuch, 1.0);
::g_stats_client->count("misbehavior.amount", howmuch, 1.0);
}

LogPrint(BCLog::NET, "Misbehaving: peer=%d (%d -> %d)%s%s\n",
Expand Down Expand Up @@ -3260,7 +3260,7 @@ void PeerManagerImpl::ProcessMessage(
AssertLockHeld(g_msgproc_mutex);

LogPrint(BCLog::NET, "received: %s (%u bytes) peer=%d\n", SanitizeString(msg_type), vRecv.size(), pfrom.GetId());
statsClient.inc("message.received." + SanitizeString(msg_type), 1.0f);
::g_stats_client->inc("message.received." + SanitizeString(msg_type), 1.0f);

const bool is_masternode = m_mn_activeman != nullptr;

Expand Down Expand Up @@ -3759,7 +3759,7 @@ void PeerManagerImpl::ProcessMessage(
if (inv.IsMsgBlk()) {
const bool fAlreadyHave = AlreadyHaveBlock(inv.hash);
LogPrint(BCLog::NET, "got inv: %s %s peer=%d\n", inv.ToString(), fAlreadyHave ? "have" : "new", pfrom.GetId());
statsClient.inc(strprintf("message.received.inv_%s", inv.GetCommand()), 1.0f);
::g_stats_client->inc(strprintf("message.received.inv_%s", inv.GetCommand()), 1.0f);

UpdateBlockAvailability(pfrom.GetId(), inv.hash);
if (!fAlreadyHave && !fImporting && !fReindex && !mapBlocksInFlight.count(inv.hash)) {
Expand All @@ -3774,7 +3774,7 @@ void PeerManagerImpl::ProcessMessage(
} else {
const bool fAlreadyHave = AlreadyHave(inv);
LogPrint(BCLog::NET, "got inv: %s %s peer=%d\n", inv.ToString(), fAlreadyHave ? "have" : "new", pfrom.GetId());
statsClient.inc(strprintf("message.received.inv_%s", inv.GetCommand()), 1.0f);
::g_stats_client->inc(strprintf("message.received.inv_%s", inv.GetCommand()), 1.0f);

static std::set<int> allowWhileInIBDObjs = {
MSG_SPORK
Expand Down
4 changes: 0 additions & 4 deletions src/random.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,10 +207,6 @@ class FastRandomContext
return rand32() % nMax;
}

uint32_t operator()(uint32_t nMax) {
return rand32(nMax);
}

/** Generate random bytes. */
template <typename B = unsigned char>
std::vector<B> randbytes(size_t len);
Expand Down
Loading
Loading