mirror of
https://github.com/XRPLF/rippled.git
synced 2026-07-24 07:30:30 +00:00
Merge branch 'pratik/otel-phase9-metric-gap-fill' into pratik/otel-phase10-workload-validation
Brings the coroutine-aware OTel context storage refactor forward to phase-10: CoroAwareContextStorage + install, ScopedSpanGuard same-store assertion, non-owning ScopedActivation, scoped rpc.command spans, tx/consensus/ledger worker-body activation, coro-store-swap tests, and the M1/M2 hardening. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -147,6 +147,15 @@ later spans — the `stage` attribute identifies where it stopped.
|
||||
> clean root, not a "root span not yet received" warning. Cross-node correlation
|
||||
> still works because every node derives the same `trace_id` from the shared hash.
|
||||
|
||||
> **Log-trace correlation is retained across coroutines.** OTel context storage
|
||||
> is coroutine-aware (backed by `LocalValue`), so the active span travels with a
|
||||
> coroutine across `yield()` and resumes on whatever thread the scheduler picks.
|
||||
> RPC, consensus, and transaction spans therefore keep per-line log-trace
|
||||
> correlation, and their scopes are safe across coroutine yields. Job-handoff
|
||||
> spans — transaction apply and receive, consensus accept, and ledger acquire —
|
||||
> are activated inside their worker bodies rather than at enqueue, so each
|
||||
> worker's log lines carry the span's trace context.
|
||||
|
||||
**Where to find**: Tempo → TraceQL: `{resource.service.name="xrpld" && name=~"tx.process|tx.receive"}`
|
||||
or, for the apply pipeline: `{resource.service.name="xrpld" && name=~"tx.preflight|tx.preclaim|tx.transactor"}`
|
||||
|
||||
@@ -234,19 +243,21 @@ under an unrelated transaction's trace.
|
||||
|
||||
Controlled by `trace_rpc=1` in `[telemetry]` config.
|
||||
|
||||
| Span Name | Parent | Source File | Description |
|
||||
| --------------------- | ------------------ | --------------- | ---------------------------------------------------------- |
|
||||
| `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 |
|
||||
| Span Name | Parent | Source File | Description |
|
||||
| --------------------- | -------------------- | --------------- | ---------------------------------------------------------- |
|
||||
| `pathfind.request` | `rpc.command.<name>` | 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`.
|
||||
> **Note**: `pathfind.request` nests under the active `rpc.command.<name>` span.
|
||||
> Because OTel context storage is coroutine-aware (backed by `LocalValue`), the
|
||||
> `rpc.command.*` scope stays correct even though its generic dispatch
|
||||
> (`callMethod`) also wraps handlers such as `doRipplePathFind` whose span is held
|
||||
> across a coroutine `yield()` — the ambient context travels with the coroutine
|
||||
> when it resumes, so there is no wrong-thread scope pop. The
|
||||
> `pathfind.request → compute → discover` sub-tree therefore parents to
|
||||
> `rpc.command.<name>`, giving an exact request-to-pathfind nesting.
|
||||
|
||||
**Where to find**: Tempo → TraceQL: `{resource.service.name="xrpld" && name=~"pathfind.*"}`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user