feat(telemetry): add PathFind tracing with 5 spans (Tasks 2.9/2.10)

Instrument the path finding subsystem with full span coverage:

- pathfind.request: wraps doPathFind() and doRipplePathFind() RPC handlers
- pathfind.compute: wraps PathRequest::doUpdate() with fast/normal attr
- pathfind.update_all: wraps PathRequestManager::updateAll() on ledger
  close with ledger_index attr
- pathfind.discover: wraps Pathfinder::findPaths() graph exploration
  with search_level attr
- pathfind.rank: wraps Pathfinder::computePathRanks() liquidity
  validation with num_paths attr

New file: PathFindSpanNames.h with compile-time constants following
the StaticStr/join() pattern from Phase 1c.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Pratik Mankawde
2026-04-21 15:25:44 +01:00
parent eb51457e69
commit 682d7a8d76
6 changed files with 127 additions and 0 deletions

View File

@@ -0,0 +1,90 @@
#pragma once
/** Compile-time span name constants for PathFind tracing.
*
* Covers the path_find and ripple_path_find RPC handlers, the
* PathRequest computation engine, and the Pathfinder graph exploration.
*
* Span hierarchy:
*
* RPC entry (one-shot or subscription):
*
* +-------------------------------------------------------+
* | pathfind.request |
* | doPathFind() / doRipplePathFind() |
* | attrs: source_account, dest_account |
* | |
* | +--------------------------------------------------+ |
* | | pathfind.compute | |
* | | PathRequest::doUpdate() | |
* | | attrs: fast, search_level | |
* | | | |
* | | +---------------------+ +--------------------+ | |
* | | | pathfind.discover | | pathfind.rank | | |
* | | | Pathfinder::find() | | computePathRanks() | | |
* | | +---------------------+ +--------------------+ | |
* | +--------------------------------------------------+ |
* +-------------------------------------------------------+
*
* Async recomputation (ledger close):
*
* +-------------------------------------------------------+
* | pathfind.update_all |
* | PathRequestManager::updateAll() |
* | attrs: ledger_index, num_requests |
* | |
* | +--------------------------------------------------+ |
* | | pathfind.compute (per active request) | |
* | +--------------------------------------------------+ |
* +-------------------------------------------------------+
*/
#include <xrpl/telemetry/SpanNames.h>
namespace xrpl {
namespace telemetry {
namespace pathfind_span {
// ===== Span prefixes =======================================================
namespace prefix {
/// "pathfind" — root prefix for path finding spans.
inline constexpr auto pathfind = makeStr("pathfind");
} // namespace prefix
// ===== Span operation suffixes =============================================
namespace op {
inline constexpr auto request = makeStr("request");
inline constexpr auto compute = makeStr("compute");
inline constexpr auto updateAll = makeStr("update_all");
inline constexpr auto discover = makeStr("discover");
inline constexpr auto rank = makeStr("rank");
} // namespace op
// ===== Attribute keys ======================================================
namespace attr {
inline constexpr auto xrplPathfind = join(seg::xrpl, makeStr("pathfind"));
/// "xrpl.pathfind.source_account"
inline constexpr auto sourceAccount = join(xrplPathfind, makeStr("source_account"));
/// "xrpl.pathfind.dest_account"
inline constexpr auto destAccount = join(xrplPathfind, makeStr("dest_account"));
/// "xrpl.pathfind.fast"
inline constexpr auto fast = join(xrplPathfind, makeStr("fast"));
/// "xrpl.pathfind.search_level"
inline constexpr auto searchLevel = join(xrplPathfind, makeStr("search_level"));
/// "xrpl.pathfind.num_complete_paths"
inline constexpr auto numCompletePaths = join(xrplPathfind, makeStr("num_complete_paths"));
/// "xrpl.pathfind.num_paths"
inline constexpr auto numPaths = join(xrplPathfind, makeStr("num_paths"));
/// "xrpl.pathfind.num_requests"
inline constexpr auto numRequests = join(xrplPathfind, makeStr("num_requests"));
/// "xrpl.pathfind.ledger_index"
inline constexpr auto ledgerIndex = join(xrplPathfind, makeStr("ledger_index"));
} // namespace attr
} // namespace pathfind_span
} // namespace telemetry
} // namespace xrpl

View File

@@ -3,6 +3,7 @@
#include <xrpld/app/main/Application.h>
#include <xrpld/core/Config.h>
#include <xrpld/rpc/detail/AccountAssets.h>
#include <xrpld/rpc/detail/PathFindSpanNames.h>
#include <xrpld/rpc/detail/PathRequestManager.h>
#include <xrpld/rpc/detail/Pathfinder.h>
#include <xrpld/rpc/detail/PathfinderUtils.h>
@@ -34,6 +35,8 @@
#include <xrpl/resource/Consumer.h>
#include <xrpl/server/InfoSub.h>
#include <xrpl/server/LoadFeeTrack.h>
#include <xrpl/server/NetworkOPs.h>
#include <xrpl/telemetry/SpanGuard.h>
#include <xrpl/tx/paths/RippleCalc.h>
#include <algorithm>
@@ -711,6 +714,11 @@ PathRequest::doUpdate(
std::function<bool(void)> const& continueCallback)
{
using namespace std::chrono;
using namespace telemetry;
auto span = SpanGuard::span(
TraceCategory::Rpc, pathfind_span::prefix::pathfind, pathfind_span::op::compute);
span.setAttribute(pathfind_span::attr::fast, fast);
JLOG(m_journal.debug()) << iIdentifier << " update " << (fast ? "fast" : "normal");
{

View File

@@ -2,6 +2,7 @@
#include <xrpld/app/ledger/LedgerMaster.h>
#include <xrpld/app/main/Application.h>
#include <xrpld/rpc/detail/PathFindSpanNames.h>
#include <xrpld/rpc/detail/AssetCache.h>
#include <xrpld/rpc/detail/PathRequest.h>
@@ -15,6 +16,7 @@
#include <xrpl/protocol/jss.h>
#include <xrpl/resource/Consumer.h>
#include <xrpl/server/InfoSub.h>
#include <xrpl/telemetry/SpanGuard.h>
#include <algorithm>
#include <cstdint>
@@ -59,6 +61,11 @@ PathRequestManager::getAssetCache(std::shared_ptr<ReadView const> const& ledger,
void
PathRequestManager::updateAll(std::shared_ptr<ReadView const> const& inLedger)
{
using namespace telemetry;
auto span = SpanGuard::span(
TraceCategory::Rpc, pathfind_span::prefix::pathfind, pathfind_span::op::updateAll);
span.setAttribute(pathfind_span::attr::ledgerIndex, static_cast<int64_t>(inLedger->seq()));
auto event = app_.getJobQueue().makeLoadEvent(jtPATH_FIND, "PathRequest::updateAll");
std::vector<PathRequest::wptr> requests;

View File

@@ -1,6 +1,7 @@
#include <xrpld/rpc/detail/Pathfinder.h>
#include <xrpld/app/main/Application.h>
#include <xrpld/rpc/detail/PathFindSpanNames.h>
#include <xrpld/rpc/detail/AssetCache.h>
#include <xrpld/rpc/detail/PathfinderUtils.h>
#include <xrpld/rpc/detail/RippleLineCache.h>
@@ -29,6 +30,7 @@
#include <xrpl/protocol/STPathSet.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/UintTypes.h>
#include <xrpl/telemetry/SpanGuard.h>
#include <xrpl/tx/paths/RippleCalc.h>
#include <algorithm>
@@ -227,6 +229,11 @@ Pathfinder::Pathfinder(
bool
Pathfinder::findPaths(int searchLevel, std::function<bool(void)> const& continueCallback)
{
using namespace telemetry;
auto span = SpanGuard::span(
TraceCategory::Rpc, pathfind_span::prefix::pathfind, pathfind_span::op::discover);
span.setAttribute(pathfind_span::attr::searchLevel, static_cast<int64_t>(searchLevel));
JLOG(j_.trace()) << "findPaths start";
if (mDstAmount == beast::zero)
{
@@ -437,6 +444,11 @@ Pathfinder::getPathLiquidity(
void
Pathfinder::computePathRanks(int maxPaths, std::function<bool(void)> const& continueCallback)
{
using namespace telemetry;
auto span = SpanGuard::span(
TraceCategory::Rpc, pathfind_span::prefix::pathfind, pathfind_span::op::rank);
span.setAttribute(pathfind_span::attr::numPaths, static_cast<int64_t>(maxPaths));
mRemainingAmount = convertAmount(mDstAmount, convert_all_);
// Must subtract liquidity in default path from remaining amount.

View File

@@ -1,6 +1,7 @@
#include <xrpld/app/ledger/LedgerMaster.h>
#include <xrpld/app/main/Application.h>
#include <xrpld/rpc/Context.h>
#include <xrpld/rpc/detail/PathFindSpanNames.h>
#include <xrpld/rpc/detail/PathRequestManager.h>
#include <xrpl/json/json_value.h>
@@ -9,12 +10,16 @@
#include <xrpl/protocol/jss.h>
#include <xrpl/resource/Fees.h>
#include <xrpl/server/InfoSub.h>
#include <xrpl/telemetry/SpanGuard.h>
namespace xrpl {
Json::Value
doPathFind(RPC::JsonContext& context)
{
using namespace telemetry;
auto span = SpanGuard::span(
TraceCategory::Rpc, pathfind_span::prefix::pathfind, pathfind_span::op::request);
if (context.app.config().PATH_SEARCH_MAX == 0)
return rpcError(rpcNOT_SUPPORTED);

View File

@@ -2,6 +2,7 @@
#include <xrpld/rpc/Context.h>
#include <xrpld/rpc/Role.h>
#include <xrpld/rpc/detail/LegacyPathFind.h>
#include <xrpld/rpc/detail/PathFindSpanNames.h>
#include <xrpld/rpc/detail/PathRequest.h>
#include <xrpld/rpc/detail/PathRequestManager.h>
#include <xrpld/rpc/detail/RPCLedgerHelpers.h>
@@ -13,6 +14,7 @@
#include <xrpl/protocol/RPCErr.h>
#include <xrpl/protocol/jss.h>
#include <xrpl/resource/Fees.h>
#include <xrpl/telemetry/SpanGuard.h>
#include <memory>
#include <utility>
@@ -23,6 +25,9 @@ namespace xrpl {
Json::Value
doRipplePathFind(RPC::JsonContext& context)
{
using namespace telemetry;
auto span = SpanGuard::span(
TraceCategory::Rpc, pathfind_span::prefix::pathfind, pathfind_span::op::request);
if (context.app.config().PATH_SEARCH_MAX == 0)
return rpcError(rpcNOT_SUPPORTED);