From 96a34953284f0e99a06f6af7abfc426888e30afd Mon Sep 17 00:00:00 2001 From: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com> Date: Wed, 9 Sep 2026 12:01:36 +0100 Subject: [PATCH 1/4] fix(telemetry): brace the direct-apply status branch in TxQ clang-tidy's readability-braces-around-statements exempts statements of at most two lines, but not an if/else chain. Brace both arms. --- src/xrpld/app/misc/detail/TxQ.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/xrpld/app/misc/detail/TxQ.cpp b/src/xrpld/app/misc/detail/TxQ.cpp index d98736e9f2..e6626473e0 100644 --- a/src/xrpld/app/misc/detail/TxQ.cpp +++ b/src/xrpld/app/misc/detail/TxQ.cpp @@ -807,9 +807,13 @@ TxQ::apply( { span.setAttribute(txq_span::attr::terCode, transToken(directApplied->ter).c_str()); if (directApplied->applied) + { span.setAttribute(txq_span::attr::txqStatus, txq_span::val::appliedDirect); + } else + { span.setAttribute(txq_span::attr::txqStatus, txq_span::val::failed); + } } return *directApplied; } From 08a1ab8cd340fd966db1956efd6473ce543281b4 Mon Sep 17 00:00:00 2001 From: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com> Date: Wed, 9 Sep 2026 12:01:39 +0100 Subject: [PATCH 2/4] fix(telemetry): drop the unused include from NullTelemetry The file names only std::string_view, which already provides. --- src/libxrpl/telemetry/NullTelemetry.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libxrpl/telemetry/NullTelemetry.cpp b/src/libxrpl/telemetry/NullTelemetry.cpp index 64030b02d7..b1ae7e9e5b 100644 --- a/src/libxrpl/telemetry/NullTelemetry.cpp +++ b/src/libxrpl/telemetry/NullTelemetry.cpp @@ -31,7 +31,6 @@ #endif #include -#include #include namespace xrpl::telemetry { From 302a76f73ea2594f3558ff7e109525c250bcc657 Mon Sep 17 00:00:00 2001 From: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com> Date: Wed, 9 Sep 2026 12:01:42 +0100 Subject: [PATCH 3/4] fix(telemetry): make the readability probe stream const The stream is only tested for failure, and both operator bool and operator! are const members. --- src/libxrpl/telemetry/TelemetryConfig.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libxrpl/telemetry/TelemetryConfig.cpp b/src/libxrpl/telemetry/TelemetryConfig.cpp index 005be4f18a..681d5c98ec 100644 --- a/src/libxrpl/telemetry/TelemetryConfig.cpp +++ b/src/libxrpl/telemetry/TelemetryConfig.cpp @@ -194,7 +194,7 @@ requireReadableFile(std::string const& path, char const* configKey) { reason = "not a regular file"; } - else if (std::ifstream stream{path, std::ios::in}; !stream) + else if (std::ifstream const stream{path, std::ios::in}; !stream) { reason = std::error_code{errno, std::generic_category()}.message(); } From 0eb4291688028702abe94d72e15689e8010ad48b Mon Sep 17 00:00:00 2001 From: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com> Date: Wed, 9 Sep 2026 12:01:44 +0100 Subject: [PATCH 4/4] fix(telemetry): drive the collection lifecycle in the StatsD tests A StatsDCollector polls its metrics only after onCollectionReady(), so neither test flushed anything: the gauge test timed out and the counter test passed for the wrong reason. Call it in both, and drop the two includes whose symbols the file never names. --- src/tests/libxrpl/beast/insight/StatsDCollector.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/tests/libxrpl/beast/insight/StatsDCollector.cpp b/src/tests/libxrpl/beast/insight/StatsDCollector.cpp index 7024318ec8..aaab3e571e 100644 --- a/src/tests/libxrpl/beast/insight/StatsDCollector.cpp +++ b/src/tests/libxrpl/beast/insight/StatsDCollector.cpp @@ -1,7 +1,5 @@ #include -#include -#include #include #include @@ -39,6 +37,7 @@ namespace beast::insight { * "test", * Journal(Journal::getNullSink())); * auto const gauge = collector->makeGauge("g"); + * collector->onCollectionReady(); // Nothing is polled before this. * EXPECT_EQ(server.receive(std::chrono::seconds(10)), "test.g:0|g\n"); * * // Edge case: nothing was sent, so the wait runs out and returns empty. @@ -128,6 +127,10 @@ TEST(StatsDCollector, UntouchedGaugePublishesInitialZero) // Created and then left alone: no set(), no increment(). auto const gauge = collector->makeGauge("untouched"); + // A collector polls its metrics only after this. Without the call no tick + // ever flushes and every assertion below would hold for the wrong reason. + collector->onCollectionReady(); + EXPECT_EQ(server.receive(std::chrono::seconds(10)), std::string("test.untouched:0|g\n")); } @@ -146,6 +149,10 @@ TEST(StatsDCollector, UntouchedCounterPublishesNothing) auto collector = StatsDCollector::make(address, "test", Journal(Journal::getNullSink())); auto const counter = collector->makeCounter("untouched"); + // Same reason as above: polling must be on, or the empty result proves only + // that nothing was polled. + collector->onCollectionReady(); + // Three seconds spans several one-second flush ticks. EXPECT_EQ(server.receive(std::chrono::seconds(3)), std::string()); }