diff --git a/OpenTelemetryPlan/09-data-collection-reference.md b/OpenTelemetryPlan/09-data-collection-reference.md index 8f46b18676..545d2cd2ac 100644 --- a/OpenTelemetryPlan/09-data-collection-reference.md +++ b/OpenTelemetryPlan/09-data-collection-reference.md @@ -90,7 +90,7 @@ Code in `libxrpl` cannot use these macros and always goes through `beast::insigh ## 1. OpenTelemetry Spans -### 1.1 Complete Span Inventory (41 spans) +### 1.1 Complete Span Inventory (42 spans) > **41 emitted span-name families.** The count is derived from the `*SpanNames.h` > headers and their call sites, one family per distinct span name @@ -113,13 +113,14 @@ Code in `libxrpl` cannot use these macros and always goes through `beast::insigh Controlled by `trace_rpc=1` in `[telemetry]` config. -| Span Name | Parent | Source File | Description | -| -------------------- | ------------------ | ----------------- | ------------------------------------------------------------------------ | -| `rpc.http_request` | — | ServerHandler.cpp | Top-level HTTP JSON-RPC request entry point | -| `rpc.ws_message` | — | ServerHandler.cpp | WebSocket message handling (one per inbound frame) | -| `rpc.ws_upgrade` | — | ServerHandler.cpp | WebSocket upgrade handshake (records handshake failures) | -| `rpc.process` | `rpc.http_request` | ServerHandler.cpp | RPC processing pipeline (single or batch request) | -| `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 JSON-RPC request entry point | +| `rpc.ws_message` | — | ServerHandler.cpp | WebSocket message handling (one per inbound frame) | +| `rpc.ws_upgrade` | — | ServerHandler.cpp | WebSocket upgrade handshake (records handshake failures) | +| `rpc.process` | `rpc.http_request` | ServerHandler.cpp | RPC processing pipeline (single or batch request) | +| `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.*"}` diff --git a/docs/telemetry-runbook.md b/docs/telemetry-runbook.md index fbdf41f881..25f654b598 100644 --- a/docs/telemetry-runbook.md +++ b/docs/telemetry-runbook.md @@ -265,6 +265,7 @@ All spans instrumented in xrpld, grouped by subsystem: | `rpc.ws_message` | ServerHandler.cpp | `command`, `rpc_status` | 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 | On `rpc.ws_message`, `rpc_status` is set **on four of the five error paths** (resource threshold exceeded, bad API version / missing command, caught @@ -2421,6 +2422,7 @@ enforces that in CI, because the two silently drifted once already. | `rpc.ws_message` | `{span_name="rpc.ws_message"}` | RPC Performance (WebSocket Rate) | | `rpc.process` | `{span_name="rpc.process"}` | RPC Performance (Overall Throughput) | | `rpc.command.*` | `{span_name=~"rpc.command.*"}` | RPC Performance (Rate, Latency, Error, Top) | +| `rpc.startup` | `{span_name="rpc.startup"}` | -- (available but not paneled) | | `tx.process` | `{span_name="tx.process"}` | Transaction Overview (Rate, Latency, Heatmap) | | `tx.receive` | `{span_name="tx.receive"}` | Transaction Overview (Rate, Receive) | | `tx.apply` | `{span_name="tx.apply"}` | Transaction Overview + Ledger Ops (Apply) | diff --git a/src/xrpld/app/misc/detail/TxQ.cpp b/src/xrpld/app/misc/detail/TxQ.cpp index 7f43936c2f..516e83bbd8 100644 --- a/src/xrpld/app/misc/detail/TxQ.cpp +++ b/src/xrpld/app/misc/detail/TxQ.cpp @@ -782,8 +782,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.