From e083b6bb3acb26991085a55405d172c8e64e9e53 Mon Sep 17 00:00:00 2001 From: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com> Date: Fri, 25 Sep 2026 14:01:53 +0100 Subject: [PATCH 1/3] docs(telemetry): Correct where txq.enqueue nests on the rebuild path With no parent context the enqueue span takes the ambient span as its parent. On the open-ledger rebuild path that is consensus.accept.apply inside doAccept. Only on the switchLastClosedLedger jump is the span a root. --- src/xrpld/app/misc/detail/TxQ.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/xrpld/app/misc/detail/TxQ.cpp b/src/xrpld/app/misc/detail/TxQ.cpp index 8d8c784469..2fcc4e7e55 100644 --- a/src/xrpld/app/misc/detail/TxQ.cpp +++ b/src/xrpld/app/misc/detail/TxQ.cpp @@ -781,8 +781,9 @@ TxQ::apply( // is ambient, and this ScopedSpanGuard's scope is RAII-bounded to this fully // synchronous call (no coroutine yield), so no unrelated parent leaks in and // its scope cannot leak out onto a reused worker. - // On the open-ledger rebuild path parentCtx is null and this is a root; the - // current_ledger_seq attribute below correlates it to the ledger instead. + // On the open-ledger rebuild path parentCtx is null, so the span nests under + // the ambient span: consensus.accept.apply inside doAccept, a root on the + // switchLastClosedLedger jump. current_ledger_seq below ties it to a ledger. // A lambda (not a ternary) picks the factory: ScopedSpanGuard's move ctor is // deleted, so guaranteed copy elision on each return is the only way to // construct it conditionally. From 9edf2ea5600e9987c0cfd0fc633886a15e52c5c9 Mon Sep 17 00:00:00 2001 From: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com> Date: Fri, 25 Sep 2026 14:01:55 +0100 Subject: [PATCH 2/3] docs(telemetry): List rpc.startup in the runbook span tables Adds the span to the RPC span table and to the span, metric and dashboard summary. It has no dashboard panel. --- docs/telemetry-runbook.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/telemetry-runbook.md b/docs/telemetry-runbook.md index 3a37870257..c538c48d30 100644 --- a/docs/telemetry-runbook.md +++ b/docs/telemetry-runbook.md @@ -85,6 +85,7 @@ All spans instrumented in xrpld, grouped by subsystem: | `rpc.ws_message` | ServerHandler.cpp | `command` | WebSocket RPC message | | `rpc.process` | ServerHandler.cpp | `is_batch`, `batch_size` | RPC processing (child of rpc.http_request/ws_message) | | `rpc.command.` | RPCHandler.cpp | `command`, `version`, `rpc_role`, `rpc_status`, `load_type` | Per-command span (e.g., `rpc.command.server_info`) | +| `rpc.startup` | Application.cpp | — | `[rpc_startup]` batch; parent of its command spans | ### Transaction Spans @@ -585,6 +586,7 @@ Three dashboards are pre-provisioned in `docker/telemetry/grafana/dashboards/`: | `rpc.ws_message` | `{span_name="rpc.ws_message"}` | -- (available but not paneled) | | `rpc.process` | `{span_name="rpc.process"}` | -- (available but not paneled) | | `rpc.command.*` | `{span_name=~"rpc.command.*"}` | RPC Performance (all 4 panels) | +| `rpc.startup` | `{span_name="rpc.startup"}` | -- (available but not paneled) | | `tx.process` | `{span_name="tx.process"}` | Transaction Overview (3 panels) | | `tx.receive` | `{span_name="tx.receive"}` | Transaction Overview (2 panels) | | `txq.enqueue` | `{span_name="txq.enqueue"}` | -- (available but not paneled) | From e7ae987451507425523596837bc1da084d8053a3 Mon Sep 17 00:00:00 2001 From: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com> Date: Fri, 25 Sep 2026 14:01:58 +0100 Subject: [PATCH 3/3] docs(telemetry): Add rpc.startup to the data collection reference Adds the span row, lists it as a parent of rpc.command.*, and moves the span totals from 38 to 39. --- .../09-data-collection-reference.md | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/OpenTelemetryPlan/09-data-collection-reference.md b/OpenTelemetryPlan/09-data-collection-reference.md index 446204dc23..814314abaa 100644 --- a/OpenTelemetryPlan/09-data-collection-reference.md +++ b/OpenTelemetryPlan/09-data-collection-reference.md @@ -84,7 +84,7 @@ always goes through `beast::insight` instead. ## 1. OpenTelemetry Spans -### 1.1 Complete Span Inventory (38 spans) +### 1.1 Complete Span Inventory (39 spans) > **See also**: [02-design-decisions.md §2.3](./02-design-decisions.md#23-span-naming-conventions) for naming conventions and the full span catalog with rationale. [04-code-samples.md §4.6](./04-code-samples.md#46-span-flow-visualization) for span flow diagrams. @@ -92,13 +92,14 @@ always goes through `beast::insight` instead. Controlled by `trace_rpc=1` in `[telemetry]` config. -| Span Name | Parent | Source File | Description | -| -------------------- | ------------------ | ----------------- | ------------------------------------------------------------------------ | -| `rpc.http_request` | — | ServerHandler.cpp | Top-level HTTP RPC request entry point | -| `rpc.process` | `rpc.http_request` | ServerHandler.cpp | RPC processing pipeline | -| `rpc.ws_message` | — | ServerHandler.cpp | WebSocket message handling | -| `rpc.ws_upgrade` | — | ServerHandler.cpp | WebSocket upgrade handshake (error path) | -| `rpc.command.` | `rpc.process` | RPCHandler.cpp | Per-command span (e.g., `rpc.command.server_info`, `rpc.command.ledger`) | +| Span Name | Parent | Source File | Description | +| -------------------- | ---------------------------------------------- | ----------------- | ------------------------------------------------------------------------ | +| `rpc.http_request` | — | ServerHandler.cpp | Top-level HTTP RPC request entry point | +| `rpc.process` | `rpc.http_request` | ServerHandler.cpp | RPC processing pipeline | +| `rpc.ws_message` | — | ServerHandler.cpp | WebSocket message handling | +| `rpc.ws_upgrade` | — | ServerHandler.cpp | WebSocket upgrade handshake (error path) | +| `rpc.command.` | `rpc.process`, `rpc.ws_message`, `rpc.startup` | RPCHandler.cpp | Per-command span (e.g., `rpc.command.server_info`, `rpc.command.ledger`) | +| `rpc.startup` | — | Application.cpp | `[rpc_startup]` batch run during setup; parent of its command spans | **Where to find**: Tempo → TraceQL: `{resource.service.name="xrpld" && name=~"rpc.http_request|rpc.command.*"}` @@ -900,7 +901,7 @@ All span names and attributes are defined as compile-time constants in colocated | Header File | Subsystem | Span Count | Attribute Count | Notes | | ----------------------------------------------- | ------------- | ---------- | --------------- | ------------------------------------------- | -| `src/xrpld/rpc/detail/RpcSpanNames.h` | RPC (HTTP/WS) | 5 | 5 | Includes `rpc.ws_upgrade` error path | +| `src/xrpld/rpc/detail/RpcSpanNames.h` | RPC (HTTP/WS) | 6 | 5 | Includes `rpc.ws_upgrade` error path | | `src/xrpld/rpc/detail/PathFindSpanNames.h` | PathFind | 5 | 8 | Covers one-shot and subscription paths | | `src/xrpld/app/main/GrpcSpanNames.h` | gRPC | 1 | 3 | Flat single-span structure per request | | `src/xrpld/telemetry/TxSpanNames.h` | Transaction | 2 | 7 | Includes peer context attributes | @@ -910,7 +911,7 @@ All span names and attributes are defined as compile-time constants in colocated | `src/xrpld/app/ledger/detail/LedgerSpanNames.h` | Ledger | 4 | 7 | Build, store, validate, tx.apply | | `src/xrpld/overlay/detail/PeerSpanNames.h` | Peer Overlay | 2 | 5 | Proposal and validation receive | -Column totals: **38 spans** and **89 attribute rows**, matching §1.1 and §1.2. `tx.apply` is counted under `LedgerSpanNames.h`, which defines it; §1.1 lists it with the transaction spans. +Column totals: **39 spans** and **89 attribute rows**, matching §1.1 and §1.2. `tx.apply` is counted under `LedgerSpanNames.h`, which defines it; §1.1 lists it with the transaction spans. > **Design convention**: SpanNames headers are colocated with their subsystem classes rather than centralized in `telemetry/`. See [memory/feedback_span-names-colocation.md](../.claude/memory/feedback_span-names-colocation.md) for rationale.