Cockatrice/servatrice/src/metrics_registry.cpp
Lukas Brübach 49f3d38e15 [Server] Drop dead Prometheus histogram, add developer command metrics, fix watchdog init order
- metrics_registry: remove toPrometheusText/appendCumulativeBuckets and the time-bucket histogram that nothing in production ever emitted (the future /metrics exporter can bring it back); keep counts/totals read by the Developer tab
- Fix +Inf bucket routing that never incremented, and its test that locked the bug in
- Instrument developer_command container (kind 6) in processCommandContainer and stats label resolution
- Read metrics/{slow_command_ms,stall_warn_ms} at the top of initServer() so stall_warn_ms=0 disables the watchdogs before pool threads start
- Shrink KindStride to 1280 (largest extension in use is 1206) with a static_assert; document scrape cost of getCardsInGamesTotal; note slow_command logging has no rate limit in servatrice.ini.example
2026-09-02 13:56:38 +02:00

70 lines
No EOL
2 KiB
C++

#include "metrics_registry.h"
#include <QList>
void MetricsRegistry::observeCommand(int typeId, qint64 elapsedMs)
{
if (typeId < 0 || typeId >= MaxTypes) {
typeId = MaxTypes - 1; // overflow slot keeps misrouted ids visible
}
if (elapsedMs < 0) {
elapsedMs = 0;
}
TypeStats &stats = slotFor(typeId);
stats.count.fetch_add(1, std::memory_order_relaxed);
stats.totalMs.fetch_add(elapsedMs, std::memory_order_relaxed);
totalCommandsCounter.fetch_add(1, std::memory_order_relaxed);
totalTimeCounter.fetch_add(elapsedMs, std::memory_order_relaxed);
}
void MetricsRegistry::observeGameStartDurationMs(qint64 elapsedMs)
{
if (elapsedMs < 0) {
elapsedMs = 0;
}
gameStartStats.count.fetch_add(1, std::memory_order_relaxed);
gameStartStats.totalMs.fetch_add(elapsedMs, std::memory_order_relaxed);
}
MetricsRegistry::TypeStats &MetricsRegistry::slotFor(int typeId)
{
return typeSlots[static_cast<size_t>(typeId)];
}
const MetricsRegistry::TypeStats &MetricsRegistry::slotFor(int typeId) const
{
return typeSlots[static_cast<size_t>(typeId)];
}
int MetricsRegistry::activeTypeCount() const
{
int active = 0;
for (int type = 0; type < MaxTypes; ++type) {
if (slotFor(type).count.load(std::memory_order_relaxed) > 0) {
++active;
}
}
return active;
}
QList<MetricsRegistry::ActiveTypeStats> MetricsRegistry::collectActiveStats() const
{
QList<ActiveTypeStats> result;
for (int type = 0; type < MaxTypes; ++type) {
const TypeStats &stats = slotFor(type);
const qint64 count = stats.count.load(std::memory_order_relaxed);
if (count == 0) {
continue;
}
result.append({type, count, stats.totalMs.load(std::memory_order_relaxed)});
}
return result;
}
MetricsRegistry::GameStartSnapshot MetricsRegistry::getGameStartSnapshot() const
{
return {gameStartStats.count.load(std::memory_order_relaxed),
gameStartStats.totalMs.load(std::memory_order_relaxed)};
}