diff --git a/OpenTelemetryPlan/Phase2_taskList.md b/OpenTelemetryPlan/Phase2_taskList.md index 4c33dca66c..cb5c1fa98f 100644 --- a/OpenTelemetryPlan/Phase2_taskList.md +++ b/OpenTelemetryPlan/Phase2_taskList.md @@ -167,13 +167,13 @@ This surfaces all RPCs served during a blocked period — critical for post-inci | ---- | ------------------------------------------- | ------------------- | ------------------------------------------------ | | 2.1 | W3C Trace Context header extraction | Deferred → Phase 3 | No consumer in Phase 2; needs cross-node tracing | | 2.2 | Per-category span creation | Complete (Phase 1c) | Superseded by TraceCategory enum + SpanGuard | -| 2.3 | Add shouldTraceLedger() interface method | Complete | All 3 implementations present | +| 2.3 | Add shouldTraceLedger() interface method | Complete (Phase 1c) | Delivered in Phase 1c base branch | | 2.4 | Unit tests for core telemetry | Complete | TelemetryConfig + SpanGuardFactory tests | | 2.5 | Enhanced RPC span attributes (HTTP-level) | Deferred | Low value; span duration covers timing natively | | 2.6 | Build verification and performance baseline | Complete | Verified in CI on Phase 1c | | 2.7 | Grafana Tempo search filters | Complete | rpc-command, rpc-status, rpc-role filters | | 2.8 | RPC span attribute enrichment (node health) | Complete | amendment_blocked + server_state | -**Delivered in this branch**: Tasks 2.3, 2.4, 2.6, 2.7, 2.8. +**Delivered in this branch**: Tasks 2.4, 2.7, 2.8. **Deferred with rationale**: Tasks 2.1 (→Phase 3), 2.5 (low priority). **Superseded**: Task 2.2 (Phase 1c SpanGuard factory covers this). diff --git a/docker/telemetry/grafana/provisioning/datasources/tempo.yaml b/docker/telemetry/grafana/provisioning/datasources/tempo.yaml index 576819660c..198c2550d3 100644 --- a/docker/telemetry/grafana/provisioning/datasources/tempo.yaml +++ b/docker/telemetry/grafana/provisioning/datasources/tempo.yaml @@ -106,3 +106,14 @@ datasources: operator: "=" scope: span type: dynamic + # Phase 2: Node health filters (Task 2.8) + - id: node-amendment-blocked + tag: xrpl.node.amendment_blocked + operator: "=" + scope: span + type: static + - id: node-server-state + tag: xrpl.node.server_state + operator: "=" + scope: span + type: dynamic diff --git a/include/xrpl/telemetry/SpanNames.h b/include/xrpl/telemetry/SpanNames.h index 0fde9a18c1..895ade77b4 100644 --- a/include/xrpl/telemetry/SpanNames.h +++ b/include/xrpl/telemetry/SpanNames.h @@ -100,6 +100,13 @@ namespace attr { inline constexpr auto networkId = join(join(seg::xrpl, seg::network), makeStr("id")); inline constexpr auto networkType = join(join(seg::xrpl, seg::network), makeStr("type")); inline constexpr auto linkType = join(join(seg::xrpl, seg::link), makeStr("type")); + +/// Node health attributes (cross-cutting, used by RPC/consensus/tx spans). +inline constexpr auto xrplNode = join(seg::xrpl, makeStr("node")); +/// "xrpl.node.amendment_blocked" +inline constexpr auto nodeAmendmentBlocked = join(xrplNode, makeStr("amendment_blocked")); +/// "xrpl.node.server_state" +inline constexpr auto nodeServerState = join(xrplNode, makeStr("server_state")); } // namespace attr // ===== Shared attribute values ============================================= diff --git a/src/tests/libxrpl/telemetry/TelemetryConfig.cpp b/src/tests/libxrpl/telemetry/TelemetryConfig.cpp index bbd2fea8a5..8c00a2c286 100644 --- a/src/tests/libxrpl/telemetry/TelemetryConfig.cpp +++ b/src/tests/libxrpl/telemetry/TelemetryConfig.cpp @@ -106,3 +106,16 @@ TEST(TelemetryConfig, null_telemetry_factory) tel->start(); tel->stop(); } + +TEST(TelemetryConfig, sampling_ratio_clamped) +{ + Section section; + section.set("sampling_ratio", "2.5"); + auto setup = telemetry::setup_Telemetry(section, "nHUtest123", "2.0.0", 0); + EXPECT_DOUBLE_EQ(setup.samplingRatio, 1.0); + + Section section2; + section2.set("sampling_ratio", "-0.5"); + auto setup2 = telemetry::setup_Telemetry(section2, "nHUtest123", "2.0.0", 0); + EXPECT_DOUBLE_EQ(setup2.samplingRatio, 0.0); +} diff --git a/src/xrpld/rpc/detail/RPCHandler.cpp b/src/xrpld/rpc/detail/RPCHandler.cpp index ded44fa64b..afef781a98 100644 --- a/src/xrpld/rpc/detail/RPCHandler.cpp +++ b/src/xrpld/rpc/detail/RPCHandler.cpp @@ -167,8 +167,8 @@ callMethod(JsonContext& context, Method method, std::string const& name, Object& rpc_span::attr::role, context.role == Role::ADMIN ? std::string_view(rpc_span::val::admin) : std::string_view(rpc_span::val::user)); - span.setAttribute("xrpl.node.amendment_blocked", context.app.getOPs().isAmendmentBlocked()); - span.setAttribute("xrpl.node.server_state", context.app.getOPs().strOperatingMode().c_str()); + span.setAttribute(attr::nodeAmendmentBlocked, context.app.getOPs().isAmendmentBlocked()); + span.setAttribute(attr::nodeServerState, context.app.getOPs().strOperatingMode()); static std::atomic requestId{0}; auto& perfLog = context.app.getPerfLog();