diff --git a/OpenTelemetryPlan/09-data-collection-reference.md b/OpenTelemetryPlan/09-data-collection-reference.md index 8bbb9597b6..c3eecf3af2 100644 --- a/OpenTelemetryPlan/09-data-collection-reference.md +++ b/OpenTelemetryPlan/09-data-collection-reference.md @@ -233,11 +233,18 @@ Controlled by `trace_rpc=1` in `[telemetry]` config. | Span Name | Parent | Source File | Description | | --------------------- | ------------------ | --------------- | ---------------------------------------------------------- | -| `pathfind.request` | `rpc.command.*` | PathRequest.cpp | `path_find` / `ripple_path_find` RPC entry | +| `pathfind.request` | `rpc.process` | PathFind.cpp | `path_find` RPC entry (`doPathFind`) | | `pathfind.compute` | `pathfind.request` | PathRequest.cpp | Path computation for one request (`PathRequest::doUpdate`) | | `pathfind.discover` | `pathfind.compute` | Pathfinder.cpp | Graph exploration (one per RPC call) | | `pathfind.update_all` | — | PathRequest.cpp | Async recomputation of all active requests at ledger close | +> **Note**: `pathfind.request` parents to `rpc.process`, not `rpc.command.*`. +> `rpc.command.*` is intentionally unscoped: its generic dispatch (`callMethod`) +> also wraps `doRipplePathFind`, whose span is held across a coroutine +> `yield()` — scoping it would risk a wrong-thread scope pop on resume. The +> `pathfind.request → compute → discover` sub-tree nests correctly because those +> handlers run synchronously (no yield) and use `ScopedSpanGuard`. + **Where to find**: Tempo → TraceQL: `{resource.service.name="xrpld" && name=~"pathfind.*"}` --- diff --git a/src/xrpld/app/ledger/detail/BuildLedger.cpp b/src/xrpld/app/ledger/detail/BuildLedger.cpp index d0e8967c09..482721bf6a 100644 --- a/src/xrpld/app/ledger/detail/BuildLedger.cpp +++ b/src/xrpld/app/ledger/detail/BuildLedger.cpp @@ -50,7 +50,9 @@ buildLedgerImpl( ApplyTxs&& applyTxs) { using namespace telemetry; - auto buildSpan = SpanGuard::span(TraceCategory::Ledger, seg::ledger, ledger_span::op::build); + // Scoped so tx.apply (created synchronously below during applyTxs on this + // thread) nests under it. buildLedgerImpl runs synchronously with no yield. + auto buildSpan = ScopedSpanGuard(TraceCategory::Ledger, seg::ledger, ledger_span::op::build); auto built = std::make_shared(*parent, closeTime); diff --git a/src/xrpld/rpc/detail/PathRequest.cpp b/src/xrpld/rpc/detail/PathRequest.cpp index 4fb11ab10c..28a6ad3c5c 100644 --- a/src/xrpld/rpc/detail/PathRequest.cpp +++ b/src/xrpld/rpc/detail/PathRequest.cpp @@ -739,7 +739,9 @@ PathRequest::doUpdate( { using namespace std::chrono; using namespace telemetry; - auto span = SpanGuard::span( + // Scoped so pathfind.discover (created synchronously below via findPaths) + // nests under it. doUpdate does not yield, so scoping is safe. + auto span = ScopedSpanGuard( TraceCategory::Rpc, pathfind_span::prefix::pathfind, pathfind_span::op::compute); span.setAttribute(pathfind_span::attr::fast, fast); span.setAttribute(pathfind_span::attr::destCurrency, to_string(saDstAmount_.asset()).c_str()); diff --git a/src/xrpld/rpc/handlers/orderbook/PathFind.cpp b/src/xrpld/rpc/handlers/orderbook/PathFind.cpp index f04756be15..bf7fdfe264 100644 --- a/src/xrpld/rpc/handlers/orderbook/PathFind.cpp +++ b/src/xrpld/rpc/handlers/orderbook/PathFind.cpp @@ -19,7 +19,9 @@ json::Value doPathFind(RPC::JsonContext& context) { using namespace telemetry; - auto span = SpanGuard::span( + // Scoped so pathfind.compute/discover (created synchronously below on this + // thread) nest under it. doPathFind does not yield, so scoping is safe. + auto span = ScopedSpanGuard( TraceCategory::Rpc, pathfind_span::prefix::pathfind, pathfind_span::op::request); // Addresses are hashed before emission for privacy. if (auto const& src = context.params[jss::source_account]; src.isString())