mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-21 09:05:10 -07:00
[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
This commit is contained in:
parent
26c0484297
commit
9fc0218be7
7 changed files with 54 additions and 187 deletions
|
|
@ -1,22 +1,18 @@
|
|||
#include <QRegularExpression>
|
||||
#include <QList>
|
||||
#include <gtest/gtest.h>
|
||||
#include <metrics_registry.h>
|
||||
|
||||
TEST(MetricsRegistryTest, EmptyRegistryProducesNoHistogramLines)
|
||||
TEST(MetricsRegistryTest, EmptyRegistryHasZeroedCounters)
|
||||
{
|
||||
MetricsRegistry registry;
|
||||
|
||||
EXPECT_EQ(0, registry.totalCommands());
|
||||
EXPECT_EQ(0, registry.totalTimeMs());
|
||||
EXPECT_EQ(0, registry.activeTypeCount());
|
||||
|
||||
const QString text = registry.toPrometheusText([](int) { return QString("x"); }, {});
|
||||
// The family TYPE declaration may stand alone. What must not exist is a
|
||||
// histogram sample without data behind it.
|
||||
EXPECT_FALSE(text.contains(QRegularExpression("servatrice_commands_duration_ms_(bucket|sum|count)")));
|
||||
EXPECT_EQ(0, registry.getGameStartSnapshot().count);
|
||||
}
|
||||
|
||||
TEST(MetricsRegistryTest, SingleSampleIsRecordedInTotalsAndBuckets)
|
||||
TEST(MetricsRegistryTest, SampleIsRecordedInTotalsAndSlot)
|
||||
{
|
||||
MetricsRegistry registry;
|
||||
registry.observeCommand(MetricsRegistry::typeIdFor(0, 1000), 7);
|
||||
|
|
@ -25,31 +21,11 @@ TEST(MetricsRegistryTest, SingleSampleIsRecordedInTotalsAndBuckets)
|
|||
EXPECT_EQ(7, registry.totalTimeMs());
|
||||
EXPECT_EQ(1, registry.activeTypeCount());
|
||||
|
||||
const QString text = registry.toPrometheusText(
|
||||
[](int typeId) {
|
||||
return QString("%1/%2").arg(typeId / MetricsRegistry::KindStride).arg(typeId % MetricsRegistry::KindStride);
|
||||
},
|
||||
{});
|
||||
// 7ms falls into the le="10" bucket. Smaller buckets stay empty
|
||||
EXPECT_TRUE(text.contains("# TYPE servatrice_commands_duration_ms histogram\n"));
|
||||
EXPECT_TRUE(text.contains(",le=\"10\"} 1"));
|
||||
EXPECT_TRUE(text.contains(",le=\"5\"} 0"));
|
||||
EXPECT_TRUE(text.contains("_sum{command=\"0/1000\"} 7"));
|
||||
EXPECT_TRUE(text.contains("_count{command=\"0/1000\"} 1"));
|
||||
}
|
||||
|
||||
TEST(MetricsRegistryTest, BucketsAreCumulative)
|
||||
{
|
||||
MetricsRegistry registry;
|
||||
registry.observeCommand(MetricsRegistry::typeIdFor(0, 1000), 2);
|
||||
registry.observeCommand(MetricsRegistry::typeIdFor(0, 1000), 30);
|
||||
|
||||
const QString text = registry.toPrometheusText([](int) { return QString("cmd"); }, {});
|
||||
|
||||
// cumulative counts: <=25 -> 1 sample, <=50 -> 2 samples
|
||||
EXPECT_TRUE(text.contains(",le=\"25\"} 1\n"));
|
||||
EXPECT_TRUE(text.contains(",le=\"50\"} 2\n"));
|
||||
EXPECT_TRUE(text.contains(",le=\"+Inf\"} 2\n"));
|
||||
const auto stats = registry.collectActiveStats();
|
||||
ASSERT_EQ(1, stats.size());
|
||||
EXPECT_EQ(MetricsRegistry::typeIdFor(0, 1000), stats[0].typeId);
|
||||
EXPECT_EQ(1, stats[0].count);
|
||||
EXPECT_EQ(7, stats[0].totalMs);
|
||||
}
|
||||
|
||||
TEST(MetricsRegistryTest, KindEncodingSeparatesSameExtensionNumber)
|
||||
|
|
@ -84,48 +60,16 @@ TEST(MetricsRegistryTest, NegativeDurationsAreClamped)
|
|||
EXPECT_EQ(0, registry.totalTimeMs());
|
||||
}
|
||||
|
||||
TEST(MetricsRegistryTest, GaugesAndLabelEscapingAreRendered)
|
||||
TEST(MetricsRegistryTest, GameStartTrackedSeparatelyFromCommands)
|
||||
{
|
||||
MetricsRegistry registry;
|
||||
|
||||
QHash<QString, qint64> gauges;
|
||||
gauges.insert("servatrice_users_current", 42);
|
||||
|
||||
const QString text = registry.toPrometheusText(nullptr, gauges);
|
||||
EXPECT_TRUE(text.contains("# TYPE servatrice_users_current gauge\n"));
|
||||
EXPECT_TRUE(text.contains("servatrice_users_current 42\n"));
|
||||
}
|
||||
|
||||
TEST(MetricsRegistryTest, UnnamedTypesFallBackToNumericLabel)
|
||||
{
|
||||
MetricsRegistry registry;
|
||||
registry.observeCommand(MetricsRegistry::typeIdFor(2, 1042), 9);
|
||||
|
||||
const QString text = registry.toPrometheusText(nullptr, {});
|
||||
EXPECT_TRUE(text.contains("{command=\"" + QString::number(MetricsRegistry::typeIdFor(2, 1042)) + "\"}"));
|
||||
}
|
||||
|
||||
TEST(MetricsRegistryTest, GameStartHistogramOnlyAppearsAfterSamples)
|
||||
{
|
||||
MetricsRegistry registry;
|
||||
EXPECT_FALSE(registry.toPrometheusText(nullptr, {}).contains("servatrice_game_start_duration_ms"));
|
||||
|
||||
registry.observeGameStartDurationMs(120);
|
||||
const QString text = registry.toPrometheusText(nullptr, {});
|
||||
// 120ms falls into the le="250" bucket
|
||||
EXPECT_TRUE(text.contains("# TYPE servatrice_game_start_duration_ms histogram\n"));
|
||||
EXPECT_TRUE(text.contains(",le=\"100\"} 0\n"));
|
||||
EXPECT_TRUE(text.contains(",le=\"250\"} 1\n"));
|
||||
EXPECT_TRUE(text.contains("servatrice_game_start_duration_ms_sum 120\n"));
|
||||
EXPECT_TRUE(text.contains("servatrice_game_start_duration_ms_count 1\n"));
|
||||
}
|
||||
|
||||
TEST(MetricsRegistryTest, GameStartHistogramIsSeparateFromCommandTotals)
|
||||
{
|
||||
MetricsRegistry registry;
|
||||
registry.observeGameStartDurationMs(10);
|
||||
|
||||
EXPECT_EQ(0, registry.totalCommands());
|
||||
EXPECT_EQ(0, registry.totalTimeMs());
|
||||
EXPECT_EQ(0, registry.activeTypeCount());
|
||||
}
|
||||
|
||||
const auto snapshot = registry.getGameStartSnapshot();
|
||||
EXPECT_EQ(1, snapshot.count);
|
||||
EXPECT_EQ(120, snapshot.totalMs);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue