diff --git a/OpenTelemetryPlan/09-data-collection-reference.md b/OpenTelemetryPlan/09-data-collection-reference.md index 710a5a4d17..87f6e97666 100644 --- a/OpenTelemetryPlan/09-data-collection-reference.md +++ b/OpenTelemetryPlan/09-data-collection-reference.md @@ -136,12 +136,19 @@ Controlled by `trace_rpc=1` in `[telemetry]` config (pathfinding spans fire with | Span Name | Parent | Source File | Description | | --------------------- | ------------------ | ---------------- | -------------------------------------------------------- | -| `pathfind.request` | `rpc.command.*` | PathRequests.cpp | RPC entry for path_find / ripple_path_find | +| `pathfind.request` | `rpc.process` | PathFind.cpp | RPC entry for path_find (doPathFind) | | `pathfind.compute` | `pathfind.request` | PathRequest.cpp | Single path computation (doUpdate) | | `pathfind.update_all` | — | PathRequests.cpp | Async recomputation of all active path requests on close | | `pathfind.discover` | `pathfind.compute` | Pathfinder.cpp | Graph exploration phase (Pathfinder::find) | | `pathfind.rank` | `pathfind.compute` | Pathfinder.cpp | Path ranking and selection phase | +> **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.*"}` **Grafana dashboard**: _RPC & Pathfinding (StatsD)_ (`xrpld-statsd-rpc`) for StatsD timers; span-derived metrics via _RPC Performance_ (`rpc-performance`)