From 77f35c03db51f7d6ac2b3048ad26e296d5b1da0d Mon Sep 17 00:00:00 2001 From: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com> Date: Wed, 8 Jul 2026 17:45:36 +0100 Subject: [PATCH] fix(telemetry): remove metric prefix, lowercase names, fix spaces in formatName MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop the xrpld_ prefix from beast::insight metric names — the OTel resource (service.name=xrpld) already identifies the service. formatName() now lowercases and sanitizes spaces/dots to underscores for Prometheus-compatible names. Also fix 4 source strings containing spaces that produced invalid OTel instrument names (silently rejected by the SDK). Co-Authored-By: Claude Opus 4.6 --- src/libxrpl/beast/insight/OTelCollector.cpp | 20 ++++++++------------ src/xrpld/app/main/Application.cpp | 2 +- src/xrpld/overlay/detail/TrafficCount.h | 2 +- src/xrpld/shamap/NodeFamily.cpp | 4 ++-- 4 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/libxrpl/beast/insight/OTelCollector.cpp b/src/libxrpl/beast/insight/OTelCollector.cpp index 77120dbd36..5ce716118c 100644 --- a/src/libxrpl/beast/insight/OTelCollector.cpp +++ b/src/libxrpl/beast/insight/OTelCollector.cpp @@ -823,21 +823,17 @@ OTelCollectorImp::otelMeter() const std::string OTelCollectorImp::formatName(std::string const& name) const { - // StatsD uses "prefix.group.name" format. The OTel StatsD receiver - // converts dots to underscores for Prometheus. We replicate this - // to preserve metric name compatibility. - // - // Example: prefix="xrpld", name="LedgerMaster.Validated_Ledger_Age" - // -> "xrpld_LedgerMaster_Validated_Ledger_Age" + // Produce a clean, lowercase, Prometheus-compatible metric name. + // No prefix — the OTel resource (service.name) identifies the service. + // Dots and spaces become underscores; everything lowercased. std::string result; - if (!prefix_.empty()) - { - result = prefix_; - result += '_'; - } + result.reserve(name.size()); for (char const c : name) { - result += (c == '.') ? '_' : c; + if (c == '.' || c == ' ') + result += '_'; + else + result += static_cast(std::tolower(static_cast(c))); } return result; } diff --git a/src/xrpld/app/main/Application.cpp b/src/xrpld/app/main/Application.cpp index 6d6082411f..a470a277dc 100644 --- a/src/xrpld/app/main/Application.cpp +++ b/src/xrpld/app/main/Application.cpp @@ -390,7 +390,7 @@ public: stopwatch(), logs_->journal("TaggedCache")) , cachedSLEs_( - "Cached SLEs", + "Cached_SLEs", 0, std::chrono::minutes(1), stopwatch(), diff --git a/src/xrpld/overlay/detail/TrafficCount.h b/src/xrpld/overlay/detail/TrafficCount.h index b96ee022d6..c382db18bb 100644 --- a/src/xrpld/overlay/detail/TrafficCount.h +++ b/src/xrpld/overlay/detail/TrafficCount.h @@ -278,7 +278,7 @@ public: {Category::ShareCasObject, "getobject_CAS_share"}, {Category::GetCasObject, "getobject_CAS_get"}, {Category::ShareFetchPack, "getobject_Fetch_Pack_share"}, - {Category::GetFetchPack, "getobject_Fetch Pack_get"}, + {Category::GetFetchPack, "getobject_Fetch_Pack_get"}, {Category::GetTransactions, "getobject_Transactions_get"}, {Category::ShareHash, "getobject_share"}, {Category::GetHash, "getobject_get"}, diff --git a/src/xrpld/shamap/NodeFamily.cpp b/src/xrpld/shamap/NodeFamily.cpp index 2e48117d6a..77e23d54c9 100644 --- a/src/xrpld/shamap/NodeFamily.cpp +++ b/src/xrpld/shamap/NodeFamily.cpp @@ -27,7 +27,7 @@ NodeFamily::NodeFamily(Application& app, CollectorManager& cm) , j_(app.getJournal("NodeFamily")) , fbCache_( std::make_shared( - "Node family full below cache", + "Node_family_full_below_cache", stopwatch(), app.getJournal("NodeFamilyFulLBelowCache"), cm.collector(), @@ -35,7 +35,7 @@ NodeFamily::NodeFamily(Application& app, CollectorManager& cm) kFullBelowExpiration)) , tnCache_( std::make_shared( - "Node family tree node cache", + "Node_family_tree_node_cache", app.config().getValueFor(SizedItem::TreeCacheSize), std::chrono::seconds(app.config().getValueFor(SizedItem::TreeCacheAge)), stopwatch(),