diff --git a/src/xrpld/rpc/detail/RPCHandler.cpp b/src/xrpld/rpc/detail/RPCHandler.cpp index 7a9d85748a..27dacdc560 100644 --- a/src/xrpld/rpc/detail/RPCHandler.cpp +++ b/src/xrpld/rpc/detail/RPCHandler.cpp @@ -162,7 +162,10 @@ template Status callMethod(JsonContext& context, Method method, std::string const& name, Object& result) { - auto span = SpanGuard::span(TraceCategory::Rpc, rpc_span::prefix::command, name); + // Scoped so this command nests under rpc.process and becomes the ambient + // parent of any command-internal spans (e.g. pathfind.request). Coro-aware + // storage keeps the scope correct across doRipplePathFind's yield. + auto span = ScopedSpanGuard(TraceCategory::Rpc, rpc_span::prefix::command, name); span.setAttribute(rpc_span::attr::command, name.c_str()); span.setAttribute(rpc_span::attr::version, static_cast(context.apiVersion)); span.setAttribute( @@ -256,7 +259,7 @@ doCommand(RPC::JsonContext& context, json::Value& result) // registered handler names (plus "unknown") — see the helper for why // raw request input must not reach the telemetry pipeline. auto const cmdName = resolveCommandSpanName(context); - auto span = SpanGuard::span(TraceCategory::Rpc, rpc_span::prefix::command, cmdName); + auto span = ScopedSpanGuard(TraceCategory::Rpc, rpc_span::prefix::command, cmdName); span.setAttribute(rpc_span::attr::command, cmdName); span.setAttribute(rpc_span::attr::rpcStatus, rpc_span::val::error); span.setError(getErrorInfo(error).token.cStr()); diff --git a/src/xrpld/rpc/detail/ServerHandler.cpp b/src/xrpld/rpc/detail/ServerHandler.cpp index 9f221a3823..4abee4c79f 100644 --- a/src/xrpld/rpc/detail/ServerHandler.cpp +++ b/src/xrpld/rpc/detail/ServerHandler.cpp @@ -652,7 +652,10 @@ ServerHandler::processRequest( std::string_view forwardedFor, std::string_view user) { - // Scoped child: nests under the httpRequest span active on this thread. + // Scoped child of rpc.http_request. Safe to hold across the coroutine + // yield in doRipplePathFind: the coro-aware context storage moves this + // scope with the coroutine on resume (it is never stranded on a worker's + // thread-local stack), so nesting and log-trace correlation both hold. auto span = ScopedSpanGuard(TraceCategory::Rpc, rpc_span::prefix::rpc, rpc_span::op::process); auto rpcJ = app_.getJournal("RPC");