diff --git a/.github/scripts/levelization/results/loops.txt b/.github/scripts/levelization/results/loops.txt index a1b2bcd92e..cf70468e32 100644 --- a/.github/scripts/levelization/results/loops.txt +++ b/.github/scripts/levelization/results/loops.txt @@ -1,6 +1,3 @@ -Loop: xrpl.telemetry xrpld.rpc - xrpld.rpc > xrpl.telemetry - Loop: xrpld.app xrpld.overlay xrpld.app > xrpld.overlay diff --git a/.github/scripts/levelization/results/ordering.txt b/.github/scripts/levelization/results/ordering.txt index d3eedbc707..6bc0523953 100644 --- a/.github/scripts/levelization/results/ordering.txt +++ b/.github/scripts/levelization/results/ordering.txt @@ -315,6 +315,7 @@ xrpld.rpc > xrpl.rdb xrpld.rpc > xrpl.resource xrpld.rpc > xrpl.server xrpld.rpc > xrpl.shamap +xrpld.rpc > xrpl.telemetry xrpld.rpc > xrpl.tx xrpld.shamap > xrpl.basics xrpld.shamap > xrpld.core diff --git a/include/xrpl/telemetry/DiscardFlag.h b/include/xrpl/telemetry/DiscardFlag.h index b8e7bc4ea7..1bd1f668bb 100644 --- a/include/xrpl/telemetry/DiscardFlag.h +++ b/include/xrpl/telemetry/DiscardFlag.h @@ -1,56 +1,58 @@ #pragma once -/** Thread-local discard signaling between SpanGuard and the span processor. - - SpanGuard::discard() wants to drop a span without sending it to the - exporter. The OTel SDK calls SpanProcessor::OnEnd() synchronously on the - same thread that calls Span::End(), so a thread-local flag set just before - End() and read inside OnEnd() lets FilteringSpanProcessor drop the span - before it enters the batch export queue. - - This side-channel avoids inspecting the Recordable's internals (which vary - by exporter type — SpanData vs OtlpRecordable). - - The flag is a *private* thread-local member of DiscardScope, mutated only by - its constructor and destructor. This gives real access control rather than a - naming convention: no code that includes this header can flip the flag - directly — it can only enter a DiscardScope (which sets and clears the flag - over its own lifetime) and observe the state via DiscardScope::isActive(). - Binding set/clear to a scope also means the flag cannot leak onto the next - span even if End() were to throw. - - Kept in a separate header to avoid transitive include bloat: SpanGuard.h - only needs this signaling, not the full Telemetry.h with BasicConfig/Journal. - - Usage: - @code - // In SpanGuard::discard(): - { - DiscardScope discardScope; // flag set for this scope only - span->End(); // OnEnd() runs synchronously, sees flag - } // flag cleared here, unconditionally - - // In FilteringSpanProcessor::OnEnd(): - if (DiscardScope::isActive()) - return; // drop the span - @endcode - - @note Thread safety: the flag is thread-local, so each thread observes only - its own discard signal — no synchronization is required. - - @see SpanGuard::discard(), FilteringSpanProcessor (Telemetry.cpp) -*/ +/** + * Thread-local discard signaling between SpanGuard and the span processor. + * + * SpanGuard::discard() wants to drop a span without sending it to the + * exporter. The OTel SDK calls SpanProcessor::OnEnd() synchronously on the + * same thread that calls Span::End(), so a thread-local flag set just before + * End() and read inside OnEnd() lets FilteringSpanProcessor drop the span + * before it enters the batch export queue. + * + * This side-channel avoids inspecting the Recordable's internals (which vary + * by exporter type — SpanData vs OtlpRecordable). + * + * The flag is a *private* thread-local member of DiscardScope, mutated only by + * its constructor and destructor. This gives real access control rather than a + * naming convention: no code that includes this header can flip the flag + * directly — it can only enter a DiscardScope (which sets and clears the flag + * over its own lifetime) and observe the state via DiscardScope::isActive(). + * Binding set/clear to a scope also means the flag cannot leak onto the next + * span even if End() were to throw. + * + * Kept in a separate header to avoid transitive include bloat: SpanGuard.h + * only needs this signaling, not the full Telemetry.h with BasicConfig/Journal. + * + * Usage: + * @code + * // In SpanGuard::discard(): + * { + * DiscardScope discardScope; // flag set for this scope only + * span->End(); // OnEnd() runs synchronously, sees flag + * } // flag cleared here, unconditionally + * + * // In FilteringSpanProcessor::OnEnd(): + * if (DiscardScope::isActive()) + * return; // drop the span + * @endcode + * + * @note Thread safety: the flag is thread-local, so each thread observes only + * its own discard signal — no synchronization is required. + * + * @see SpanGuard::discard(), FilteringSpanProcessor (Telemetry.cpp) + */ namespace xrpl::telemetry { -/** RAII guard that marks the current thread's span for discard. - - Sets the thread-local discard flag on construction and clears it on - destruction, so a span ended within the guard's scope is dropped by - FilteringSpanProcessor::OnEnd() while the flag stays confined to that scope. - The flag is private and mutated only here, so no other code can set it. - Non-copyable and non-movable — its sole purpose is the scoped flag lifetime. -*/ +/** + * RAII guard that marks the current thread's span for discard. + * + * Sets the thread-local discard flag on construction and clears it on + * destruction, so a span ended within the guard's scope is dropped by + * FilteringSpanProcessor::OnEnd() while the flag stays confined to that scope. + * The flag is private and mutated only here, so no other code can set it. + * Non-copyable and non-movable — its sole purpose is the scoped flag lifetime. + */ class DiscardScope { public: @@ -71,9 +73,11 @@ public: DiscardScope& operator=(DiscardScope&&) = delete; - /** @return true if the current thread is inside a DiscardScope, i.e. the - span ending now should be dropped rather than exported. Read by - FilteringSpanProcessor::OnEnd(). */ + /** + * @return true if the current thread is inside a DiscardScope, i.e. the + * span ending now should be dropped rather than exported. Read by + * FilteringSpanProcessor::OnEnd(). + */ [[nodiscard]] static bool isActive() noexcept { @@ -81,8 +85,10 @@ public: } private: - /** Thread-local discard flag. Private, so only this class's ctor/dtor can - mutate it; observers use isActive(). One instance per thread. */ + /** + * Thread-local discard flag. Private, so only this class's ctor/dtor can + * mutate it; observers use isActive(). One instance per thread. + */ inline static thread_local bool discarding = false; }; diff --git a/include/xrpl/telemetry/Redaction.h b/include/xrpl/telemetry/Redaction.h index ed84ae2964..3b1e8f67ef 100644 --- a/include/xrpl/telemetry/Redaction.h +++ b/include/xrpl/telemetry/Redaction.h @@ -1,63 +1,65 @@ #pragma once -/** Account-address redaction for telemetry span attributes. - - Path-finding RPC handlers would otherwise emit the caller's raw - account addresses as span attributes. To keep plaintext addresses out - of the telemetry backend, they are hashed at the point of emission. - This header exposes a single pure helper that turns an address into a - short, stable, obfuscated token. - - Data flow: - - handler -> redactAccount(addr) -> span attribute -> OTLP export - - The returned token is the first 16 hex characters (lowercase) of the - SHA-512Half digest of the address. It is deterministic (same address - always maps to the same token) so operators can still correlate spans - for a given account across nodes and restarts. - - The hash is unsalted, so it is obfuscation, not a secrecy guarantee: - XRP account addresses are a public, enumerable set, so a determined - observer with the telemetry stream could rebuild the address->token - mapping. The goal here is to keep plaintext addresses out of traces - and dashboards, not to defend against a precomputation attack. A salt - is intentionally omitted because it would break cross-node/restart - correlation, which is the reason for hashing rather than dropping. - - A second, independent hashing layer runs in the OpenTelemetry - Collector (an `attributes/hash` processor) as defense-in-depth for - any node that emits a raw value. - - @note This function is pure and reentrant: it holds no global state, - performs no I/O, and is safe to call concurrently from any thread. - - Usage example: - @code - #include - using namespace xrpl::telemetry; - - span.setAttribute( - pathfind_span::attr::sourceAccount, redactAccount(src.asString())); - @endcode - - Edge case (empty input yields empty output): - @code - assert(redactAccount("") == ""); - @endcode -*/ +/** + * Account-address redaction for telemetry span attributes. + * + * Path-finding RPC handlers would otherwise emit the caller's raw + * account addresses as span attributes. To keep plaintext addresses out + * of the telemetry backend, they are hashed at the point of emission. + * This header exposes a single pure helper that turns an address into a + * short, stable, obfuscated token. + * + * Data flow: + * + * handler -> redactAccount(addr) -> span attribute -> OTLP export + * + * The returned token is the first 16 hex characters (lowercase) of the + * SHA-512Half digest of the address. It is deterministic (same address + * always maps to the same token) so operators can still correlate spans + * for a given account across nodes and restarts. + * + * The hash is unsalted, so it is obfuscation, not a secrecy guarantee: + * XRP account addresses are a public, enumerable set, so a determined + * observer with the telemetry stream could rebuild the address->token + * mapping. The goal here is to keep plaintext addresses out of traces + * and dashboards, not to defend against a precomputation attack. A salt + * is intentionally omitted because it would break cross-node/restart + * correlation, which is the reason for hashing rather than dropping. + * + * A second, independent hashing layer runs in the OpenTelemetry + * Collector (an `attributes/hash` processor) as defense-in-depth for + * any node that emits a raw value. + * + * @note This function is pure and reentrant: it holds no global state, + * performs no I/O, and is safe to call concurrently from any thread. + * + * Usage example: + * @code + * #include + * using namespace xrpl::telemetry; + * + * span.setAttribute( + * pathfind_span::attr::sourceAccount, redactAccount(src.asString())); + * @endcode + * + * Edge case (empty input yields empty output): + * @code + * assert(redactAccount("") == ""); + * @endcode + */ #include #include namespace xrpl::telemetry { -/** Hash an account address into a short, stable, obfuscated token. - - @param addr The account address to redact (e.g. an r-address). - @return The first 16 lowercase hex characters of sha512Half(addr), - or an empty string when @p addr is empty. -*/ +/** + * Hash an account address into a short, stable, obfuscated token. + * + * @param addr The account address to redact (e.g. an r-address). + * @return The first 16 lowercase hex characters of sha512Half(addr), + * or an empty string when @p addr is empty. + */ [[nodiscard]] std::string redactAccount(std::string_view addr); diff --git a/include/xrpl/telemetry/SpanNames.h b/include/xrpl/telemetry/SpanNames.h index 0461f3d76a..e53d621b2a 100644 --- a/include/xrpl/telemetry/SpanNames.h +++ b/include/xrpl/telemetry/SpanNames.h @@ -1,18 +1,19 @@ #pragma once -/** Compile-time string concatenation utility and shared telemetry constants. +/** + * Compile-time string concatenation utility and shared telemetry constants. * * Provides StaticStr — a compile-time string buffer that implicitly * converts to std::string_view — and join() for dot-separated concatenation. * Module-specific span names (e.g. RPC, consensus) live in their respective * modules and build upon these shared primitives. * - * @note These constants are NOT guarded by XRPL_ENABLE_TELEMETRY because + * @note These constants are NOT guarded by XRPL_ENABLE_TELEMETRY because * call sites reference them even when SpanGuard methods are no-ops * (the no-op stubs still accept string_view parameters). The compiler * elides all inline constexpr values whose only uses are in dead code. * - * @note Json::StaticString (jss.h) is a pointer wrapper without + * @note Json::StaticString (jss.h) is a pointer wrapper without * concatenation support. boost::static_string is not constexpr. * StaticStr exists specifically for compile-time dot-join composition. * @@ -37,8 +38,10 @@ namespace xrpl::telemetry { // ===== Compile-time string utility ========================================= -/// Fixed-size character buffer for compile-time string operations. -/// Implicitly converts to std::string_view at zero cost. +/** + * Fixed-size character buffer for compile-time string operations. + * Implicitly converts to std::string_view at zero cost. + */ template struct StaticStr { @@ -60,11 +63,15 @@ struct StaticStr } }; -/// Deduction guide: StaticStr from string literal. +/** + * Deduction guide: StaticStr from string literal. + */ template StaticStr(char const (&)[N]) -> StaticStr; -/// Create a StaticStr from a string literal. +/** + * Create a StaticStr from a string literal. + */ template constexpr auto makeStr(char const (&str)[N]) @@ -72,7 +79,9 @@ makeStr(char const (&str)[N]) return StaticStr(str); } -/// Concatenate two StaticStr values with a dot separator. +/** + * Concatenate two StaticStr values with a dot separator. + */ template constexpr auto join(StaticStr const& lhs, StaticStr const& rhs) diff --git a/include/xrpl/telemetry/Telemetry.h b/include/xrpl/telemetry/Telemetry.h index b8d199b8fb..aa94329d56 100644 --- a/include/xrpl/telemetry/Telemetry.h +++ b/include/xrpl/telemetry/Telemetry.h @@ -1,90 +1,91 @@ #pragma once -/** Abstract interface for OpenTelemetry distributed tracing. - - Provides the Telemetry base class that all components use to create trace - spans. Three concrete implementations exist, selected at construction time - by makeTelemetry(): - - - TelemetryImpl (Telemetry.cpp): real OTel SDK integration, compiled - only when XRPL_ENABLE_TELEMETRY is defined and enabled at runtime. - - NullTelemetry (NullTelemetry.cpp): no-op stub used when telemetry is - disabled at compile time or runtime. - - NullTelemetryOtel (Telemetry.cpp): no-op stub that still depends on - the OTel API (used during transition or for testing). - - Inheritance / dependency diagram: - - +--------------------+ - | Telemetry | (abstract, this file) - | <> | - +---------+----------+ - | - +---------+-----------+-------------------+ - | | | - +---+------------+ +-----+---------+ +------+----------+ - | TelemetryImpl | | NullTelemetry | | NullTelemetryOtel| - | (Telemetry.cpp)| |(NullTelemetry | | (Telemetry.cpp) | - | OTel SDK | | .cpp) | | noop w/ OTel API | - +----------------+ +---------------+ +------------------+ - - The Setup struct holds all configuration parsed from the [telemetry] - section of xrpld.cfg. See TelemetryConfig.cpp for the parser and - cfg/xrpld-example.cfg for the available options. - - OTel SDK headers are conditionally included behind XRPL_ENABLE_TELEMETRY - so that builds without telemetry have zero dependency on opentelemetry-cpp. - - Usage examples: - - 1. Root span at a subsystem entry point (typical usage): - @code - #include - using namespace xrpl::telemetry; - - // In an RPC handler dispatch: - auto guard = SpanGuard::span( - TraceCategory::Rpc, rpc_span::prefix::command, commandName); - guard.setAttribute(rpc_span::attr::command, commandName); - // ... process request - // guard destructor automatically ends the span on scope exit - @endcode - - 2. Child span for a sub-operation (scoped child): - @code - auto parent = SpanGuard::span( - TraceCategory::Rpc, rpc_span::prefix::rpc, rpc_span::op::process); - { - auto child = parent.childSpan(rpc_span::op::process); - child.setAttribute(rpc_span::attr::version, apiVersion); - // child ends here - } - @endcode - - 3. Unrelated span (cross-scope, same thread): - @code - // gRPC and RPC handlers can be active simultaneously - auto grpcSpan = SpanGuard::span( - TraceCategory::Rpc, grpc_span::prefix::grpc, grpc_span::attr::method); - auto rpcSpan = SpanGuard::span( - TraceCategory::Rpc, rpc_span::prefix::command, commandName); - // both spans end on scope exit - @endcode - - 4. Cross-thread context propagation: - @code - // Thread A: capture the active context while span is in scope - auto ctx = parentGuard.captureContext(); - - // Thread B: create child span with explicit parent - auto child = SpanGuard::childSpan(rpc_span::op::process, ctx); - @endcode - - @note Thread safety: The Telemetry interface is safe for concurrent reads - (isEnabled, shouldTrace*, getTracer, startSpan) after start() completes. - setServiceInstanceId() must be called before start() and is not thread-safe. - The OTel SDK's TracerProvider and Tracer are internally thread-safe. -*/ +/** + * Abstract interface for OpenTelemetry distributed tracing. + * + * Provides the Telemetry base class that all components use to create trace + * spans. Three concrete implementations exist, selected at construction time + * by makeTelemetry(): + * + * - TelemetryImpl (Telemetry.cpp): real OTel SDK integration, compiled + * only when XRPL_ENABLE_TELEMETRY is defined and enabled at runtime. + * - NullTelemetry (NullTelemetry.cpp): no-op stub used when telemetry is + * disabled at compile time or runtime. + * - NullTelemetryOtel (Telemetry.cpp): no-op stub that still depends on + * the OTel API (used during transition or for testing). + * + * Inheritance / dependency diagram: + * + * +--------------------+ + * | Telemetry | (abstract, this file) + * | <> | + * +---------+----------+ + * | + * +---------+-----------+-------------------+ + * | | | + * +---+------------+ +-----+---------+ +------+----------+ + * | TelemetryImpl | | NullTelemetry | | NullTelemetryOtel| + * | (Telemetry.cpp)| |(NullTelemetry | | (Telemetry.cpp) | + * | OTel SDK | | .cpp) | | noop w/ OTel API | + * +----------------+ +---------------+ +------------------+ + * + * The Setup struct holds all configuration parsed from the [telemetry] + * section of xrpld.cfg. See TelemetryConfig.cpp for the parser and + * cfg/xrpld-example.cfg for the available options. + * + * OTel SDK headers are conditionally included behind XRPL_ENABLE_TELEMETRY + * so that builds without telemetry have zero dependency on opentelemetry-cpp. + * + * Usage examples: + * + * 1. Root span at a subsystem entry point (typical usage): + * @code + * #include + * using namespace xrpl::telemetry; + * + * // In an RPC handler dispatch: + * auto guard = SpanGuard::span( + * TraceCategory::Rpc, rpc_span::prefix::command, commandName); + * guard.setAttribute(rpc_span::attr::command, commandName); + * // ... process request + * // guard destructor automatically ends the span on scope exit + * @endcode + * + * 2. Child span for a sub-operation (scoped child): + * @code + * auto parent = SpanGuard::span( + * TraceCategory::Rpc, rpc_span::prefix::rpc, rpc_span::op::process); + * { + * auto child = parent.childSpan(rpc_span::op::process); + * child.setAttribute(rpc_span::attr::version, apiVersion); + * // child ends here + * } + * @endcode + * + * 3. Unrelated span (cross-scope, same thread): + * @code + * // gRPC and RPC handlers can be active simultaneously + * auto grpcSpan = SpanGuard::span( + * TraceCategory::Rpc, grpc_span::prefix::grpc, grpc_span::attr::method); + * auto rpcSpan = SpanGuard::span( + * TraceCategory::Rpc, rpc_span::prefix::command, commandName); + * // both spans end on scope exit + * @endcode + * + * 4. Cross-thread context propagation: + * @code + * // Thread A: capture the active context while span is in scope + * auto ctx = parentGuard.captureContext(); + * + * // Thread B: create child span with explicit parent + * auto child = SpanGuard::childSpan(rpc_span::op::process, ctx); + * @endcode + * + * @note Thread safety: The Telemetry interface is safe for concurrent reads + * (isEnabled, shouldTrace*, getTracer, startSpan) after start() completes. + * setServiceInstanceId() must be called before start() and is not thread-safe. + * The OTel SDK's TracerProvider and Tracer are internally thread-safe. + */ #include #include @@ -107,129 +108,171 @@ namespace xrpl::telemetry { #ifdef XRPL_ENABLE_TELEMETRY -/** OTel instrumentation scope (tracer) name. Identifies this library as the - source of spans; distinct from the `service.name` resource attribute - (Setup::serviceName), which is config-overridable. */ +/** + * OTel instrumentation scope (tracer) name. Identifies this library as the + * source of spans; distinct from the `service.name` resource attribute + * (Setup::serviceName), which is config-overridable. + */ inline constexpr std::string_view kTracerName{"xrpld"}; #endif class Telemetry { - /** Global singleton pointer, set by start()/stop() in the active - implementation. Allows SpanGuard factory methods to access the - Telemetry instance without callers passing it explicitly. - - Atomic with acquire/release ordering: start()/stop() store on - the initialization thread, factory methods load on worker threads. - @see setInstance(), getInstance() - */ + /** + * Global singleton pointer, set by start()/stop() in the active + * implementation. Allows SpanGuard factory methods to access the + * Telemetry instance without callers passing it explicitly. + * + * Atomic with acquire/release ordering: start()/stop() store on + * the initialization thread, factory methods load on worker threads. + * @see setInstance(), getInstance() + */ inline static std::atomic instance{nullptr}; public: - /** Get the global Telemetry instance. - @return Pointer to the active instance, or nullptr if not started. - */ + /** + * Get the global Telemetry instance. + * @return Pointer to the active instance, or nullptr if not started. + */ static Telemetry* getInstance() { return instance.load(std::memory_order_acquire); } - /** Set the global Telemetry instance. - Called by start()/stop() in concrete implementations. - Tests can call this with a mock to override the global instance. - @param t Pointer to the Telemetry instance, or nullptr to clear. - */ + /** + * Set the global Telemetry instance. + * Called by start()/stop() in concrete implementations. + * Tests can call this with a mock to override the global instance. + * @param t Pointer to the Telemetry instance, or nullptr to clear. + */ static void setInstance(Telemetry* t) { instance.store(t, std::memory_order_release); } - /** Configuration parsed from the [telemetry] section of xrpld.cfg. - - All fields have sensible defaults so the section can be minimal - or omitted entirely. See TelemetryConfig.cpp for the parser. - */ + /** + * Configuration parsed from the [telemetry] section of xrpld.cfg. + * + * All fields have sensible defaults so the section can be minimal + * or omitted entirely. See TelemetryConfig.cpp for the parser. + */ struct Setup { - /** Master switch: true to enable tracing at runtime. */ + /** + * Master switch: true to enable tracing at runtime. + */ bool enabled = false; - /** OTel resource attribute `service.name`. */ + /** + * OTel resource attribute `service.name`. + */ std::string serviceName = "xrpld"; - /** OTel resource attribute `service.version` (set from BuildInfo). */ + /** + * OTel resource attribute `service.version` (set from BuildInfo). + */ std::string serviceVersion; - /** OTel resource attribute `service.instance.id` (defaults to node - public key). */ + /** + * OTel resource attribute `service.instance.id` (defaults to node + * public key). + */ std::string serviceInstanceId; - /** OTLP/HTTP endpoint URL where spans are sent. */ + /** + * OTLP/HTTP endpoint URL where spans are sent. + */ std::string exporterEndpoint = "http://localhost:4318/v1/traces"; - /** Whether to use TLS for the exporter connection. */ + /** + * Whether to use TLS for the exporter connection. + */ bool useTls = false; - /** Path to a CA certificate bundle for TLS verification. */ + /** + * Path to a CA certificate bundle for TLS verification. + */ std::string tlsCertPath; - /** Head-based sampling ratio. Intentionally fixed at 1.0 (sample - everything) and NOT read from config. A per-node ratio would let - nodes make divergent keep/drop decisions for the same distributed - trace, producing broken/partial traces. The ratio sampler is wrapped - in a ParentBasedSampler (see Telemetry.cpp) so spans inheriting a - remote parent honor the upstream sampled flag. Volume reduction is - delegated to the collector's tail sampling; for node-local post-hoc - dropping see SpanGuard::discard(). - */ + /** + * Head-based sampling ratio. Intentionally fixed at 1.0 (sample + * everything) and NOT read from config. A per-node ratio would let + * nodes make divergent keep/drop decisions for the same distributed + * trace, producing broken/partial traces. The ratio sampler is wrapped + * in a ParentBasedSampler (see Telemetry.cpp) so spans inheriting a + * remote parent honor the upstream sampled flag. Volume reduction is + * delegated to the collector's tail sampling; for node-local post-hoc + * dropping see SpanGuard::discard(). + */ static constexpr double samplingRatio = 1.0; - /** Maximum number of spans per batch export. */ + /** + * Maximum number of spans per batch export. + */ std::uint32_t batchSize = 512; - /** Delay between batch exports. */ + /** + * Delay between batch exports. + */ std::chrono::milliseconds batchDelay = std::chrono::milliseconds{5000}; - /** Maximum number of spans queued before dropping. */ + /** + * Maximum number of spans queued before dropping. + */ std::uint32_t maxQueueSize = 2048; - /** Network identifier, added as an OTel resource attribute. */ + /** + * Network identifier, added as an OTel resource attribute. + */ std::uint32_t networkId = 0; - /** Network type label (e.g. "mainnet", "testnet", "devnet"). */ + /** + * Network type label (e.g. "mainnet", "testnet", "devnet"). + */ std::string networkType = "mainnet"; - /** Enable tracing for transaction processing. */ + /** + * Enable tracing for transaction processing. + */ bool traceTransactions = true; - /** Enable tracing for consensus rounds. */ + /** + * Enable tracing for consensus rounds. + */ bool traceConsensus = true; - /** Enable tracing for RPC request handling. */ + /** + * Enable tracing for RPC request handling. + */ bool traceRpc = true; - /** Enable tracing for peer-to-peer messages (enabled by default; - high volume). */ + /** + * Enable tracing for peer-to-peer messages (enabled by default; + * high volume). + */ bool tracePeer = true; - /** Enable tracing for ledger close/accept. */ + /** + * Enable tracing for ledger close/accept. + */ bool traceLedger = true; }; virtual ~Telemetry() = default; - /** Update the service instance ID (OTel resource attribute - `service.instance.id`). - - Must be called before start(). The node public key is not available - when Telemetry is constructed (during the ApplicationImp member - initializer list), so this setter allows Application::setup() to - inject the identity once nodeIdentity_ is known. - - @param id The node's base58-encoded public key or custom identifier. - */ + /** + * Update the service instance ID (OTel resource attribute + * `service.instance.id`). + * + * Must be called before start(). The node public key is not available + * when Telemetry is constructed (during the ApplicationImp member + * initializer list), so this setter allows Application::setup() to + * inject the identity once nodeIdentity_ is known. + * + * @param id The node's base58-encoded public key or custom identifier. + */ virtual void setServiceInstanceId(std::string const& id) { @@ -237,80 +280,97 @@ public: (void)id; } - /** Initialize the tracing pipeline (exporter, processor, provider). - Call after construction. - */ + /** + * Initialize the tracing pipeline (exporter, processor, provider). + * Call after construction. + */ virtual void start() = 0; - /** Flush pending spans and shut down the tracing pipeline. - Call before destruction. - */ + /** + * Flush pending spans and shut down the tracing pipeline. + * Call before destruction. + */ virtual void stop() = 0; - /** @return true if this instance is actively exporting spans. */ + /** + * @return true if this instance is actively exporting spans. + */ [[nodiscard]] virtual bool isEnabled() const = 0; - /** @return true if transaction processing should be traced. */ + /** + * @return true if transaction processing should be traced. + */ [[nodiscard]] virtual bool shouldTraceTransactions() const = 0; - /** @return true if consensus rounds should be traced. */ + /** + * @return true if consensus rounds should be traced. + */ [[nodiscard]] virtual bool shouldTraceConsensus() const = 0; - /** @return true if RPC request handling should be traced. */ + /** + * @return true if RPC request handling should be traced. + */ [[nodiscard]] virtual bool shouldTraceRpc() const = 0; - /** @return true if peer-to-peer messages should be traced. */ + /** + * @return true if peer-to-peer messages should be traced. + */ [[nodiscard]] virtual bool shouldTracePeer() const = 0; - /** @return true if ledger close/accept should be traced. */ + /** + * @return true if ledger close/accept should be traced. + */ [[nodiscard]] virtual bool shouldTraceLedger() const = 0; #ifdef XRPL_ENABLE_TELEMETRY - /** Get or create a named tracer instance. - - @param name Tracer name used to identify the instrumentation library. - @return A shared pointer to the Tracer. - */ + /** + * Get or create a named tracer instance. + * + * @param name Tracer name used to identify the instrumentation library. + * @return A shared pointer to the Tracer. + */ virtual opentelemetry::nostd::shared_ptr getTracer(std::string_view name = kTracerName) = 0; - /** Start a new span on the current thread's context. - - The span becomes a child of the current active span (if any) via - OpenTelemetry's context propagation. - - @param name Span name (typically "rpc.command."). - @param kind The span kind (defaults to kInternal). Possible values: - - kInternal: default, in-process operation - - kServer: incoming synchronous request (e.g. RPC) - - kClient: outgoing synchronous request - - kProducer: async message send (e.g. peer broadcast) - - kConsumer: async message receive - @return A shared pointer to the new Span. - */ + /** + * Start a new span on the current thread's context. + * + * The span becomes a child of the current active span (if any) via + * OpenTelemetry's context propagation. + * + * @param name Span name (typically "rpc.command."). + * @param kind The span kind (defaults to kInternal). Possible values: + * - kInternal: default, in-process operation + * - kServer: incoming synchronous request (e.g. RPC) + * - kClient: outgoing synchronous request + * - kProducer: async message send (e.g. peer broadcast) + * - kConsumer: async message receive + * @return A shared pointer to the new Span. + */ virtual opentelemetry::nostd::shared_ptr startSpan( std::string_view name, opentelemetry::trace::SpanKind kind = opentelemetry::trace::SpanKind::kInternal) = 0; - /** Start a new span with an explicit parent context. - - Use this overload when the parent span is not on the current - thread's context stack (e.g. cross-thread trace propagation). - - @param name Span name. - @param parentContext The parent span's context. - @param kind The span kind (defaults to kInternal). - @return A shared pointer to the new Span. - */ + /** + * Start a new span with an explicit parent context. + * + * Use this overload when the parent span is not on the current + * thread's context stack (e.g. cross-thread trace propagation). + * + * @param name Span name. + * @param parentContext The parent span's context. + * @param kind The span kind (defaults to kInternal). + * @return A shared pointer to the new Span. + */ virtual opentelemetry::nostd::shared_ptr startSpan( std::string_view name, @@ -319,26 +379,28 @@ public: #endif }; -/** Create a Telemetry instance. - - Returns a TelemetryImpl when setup.enabled is true, or a - NullTelemetry no-op stub otherwise. - - @param setup Configuration from the [telemetry] config section. - @param journal Journal for log output during initialization. -*/ +/** + * Create a Telemetry instance. + * + * Returns a TelemetryImpl when setup.enabled is true, or a + * NullTelemetry no-op stub otherwise. + * + * @param setup Configuration from the [telemetry] config section. + * @param journal Journal for log output during initialization. + */ std::unique_ptr makeTelemetry(Telemetry::Setup const& setup, beast::Journal journal); -/** Parse the [telemetry] config section into a Setup struct. - - @param section The [telemetry] config section. - @param nodePublicKey Node public key, used as default instance ID. - @param version Build version string. - @param networkId Network identifier from [network_id] config - (0 = mainnet, 1 = testnet, 2 = devnet). - @return A populated Setup struct with defaults for missing values. -*/ +/** + * Parse the [telemetry] config section into a Setup struct. + * + * @param section The [telemetry] config section. + * @param nodePublicKey Node public key, used as default instance ID. + * @param version Build version string. + * @param networkId Network identifier from [network_id] config + * (0 = mainnet, 1 = testnet, 2 = devnet). + * @return A populated Setup struct with defaults for missing values. + */ Telemetry::Setup makeTelemetrySetup( Section const& section, diff --git a/src/libxrpl/telemetry/NullTelemetry.cpp b/src/libxrpl/telemetry/NullTelemetry.cpp index fc824c2bb8..48d48e557d 100644 --- a/src/libxrpl/telemetry/NullTelemetry.cpp +++ b/src/libxrpl/telemetry/NullTelemetry.cpp @@ -1,14 +1,15 @@ -/** No-op implementation of the Telemetry interface. - - Always compiled (regardless of XRPL_ENABLE_TELEMETRY). Provides the - makeTelemetry() factory when telemetry is compiled out (#ifndef), which - unconditionally returns a NullTelemetry that does nothing. - - When XRPL_ENABLE_TELEMETRY IS defined, the OTel virtual methods - (getTracer, startSpan) return noop tracers/spans. The makeTelemetry() - factory in this file is not used in that case -- Telemetry.cpp provides - its own factory that can return the real TelemetryImpl. -*/ +/** + * No-op implementation of the Telemetry interface. + * + * Always compiled (regardless of XRPL_ENABLE_TELEMETRY). Provides the + * makeTelemetry() factory when telemetry is compiled out (#ifndef), which + * unconditionally returns a NullTelemetry that does nothing. + * + * When XRPL_ENABLE_TELEMETRY IS defined, the OTel virtual methods + * (getTracer, startSpan) return noop tracers/spans. The makeTelemetry() + * factory in this file is not used in that case -- Telemetry.cpp provides + * its own factory that can return the real TelemetryImpl. + */ #include @@ -30,14 +31,17 @@ namespace xrpl::telemetry { namespace { -/** No-op Telemetry that returns immediately from every method. - - Used as the sole implementation when XRPL_ENABLE_TELEMETRY is not - defined, or as a fallback when it is defined but enabled=0. -*/ +/** + * No-op Telemetry that returns immediately from every method. + * + * Used as the sole implementation when XRPL_ENABLE_TELEMETRY is not + * defined, or as a fallback when it is defined but enabled=0. + */ class NullTelemetry : public Telemetry { - /** Retained configuration (unused, kept for diagnostic access). */ + /** + * Retained configuration (unused, kept for diagnostic access). + */ Setup const setup_; public: @@ -123,9 +127,10 @@ public: } // namespace -/** Factory used when XRPL_ENABLE_TELEMETRY is not defined. - Unconditionally returns a NullTelemetry instance. -*/ +/** + * Factory used when XRPL_ENABLE_TELEMETRY is not defined. + * Unconditionally returns a NullTelemetry instance. + */ #ifndef XRPL_ENABLE_TELEMETRY std::unique_ptr makeTelemetry(Telemetry::Setup const& setup, beast::Journal) diff --git a/src/libxrpl/telemetry/Telemetry.cpp b/src/libxrpl/telemetry/Telemetry.cpp index a9891804e5..9704102b05 100644 --- a/src/libxrpl/telemetry/Telemetry.cpp +++ b/src/libxrpl/telemetry/Telemetry.cpp @@ -1,17 +1,18 @@ -/** OpenTelemetry SDK implementation of the Telemetry interface. - - Compiled only when XRPL_ENABLE_TELEMETRY is defined (via CMake - telemetry=ON). Contains: - - - FilteringSpanProcessor: decorator that drops spans marked with - kDiscardedAttr before they enter the batch export queue. - - TelemetryImpl: configures the OTel SDK with an OTLP/HTTP exporter, - FilteringSpanProcessor wrapping a batch span processor, - trace-ID-ratio sampler, and resource attributes. - - NullTelemetryOtel: no-op fallback used when telemetry is compiled in - but disabled at runtime (enabled=0 in config). - - makeTelemetry(): factory that selects the appropriate implementation. -*/ +/** + * OpenTelemetry SDK implementation of the Telemetry interface. + * + * Compiled only when XRPL_ENABLE_TELEMETRY is defined (via CMake + * telemetry=ON). Contains: + * + * - FilteringSpanProcessor: decorator that drops spans marked with + * kDiscardedAttr before they enter the batch export queue. + * - TelemetryImpl: configures the OTel SDK with an OTLP/HTTP exporter, + * FilteringSpanProcessor wrapping a batch span processor, + * trace-ID-ratio sampler, and resource attributes. + * - NullTelemetryOtel: no-op fallback used when telemetry is compiled in + * but disabled at runtime (enabled=0 in config). + * - makeTelemetry(): factory that selects the appropriate implementation. + */ #ifdef XRPL_ENABLE_TELEMETRY @@ -60,39 +61,40 @@ namespace trace_sdk = opentelemetry::sdk::trace; namespace otlp_http = opentelemetry::exporter::otlp; namespace resource = opentelemetry::sdk::resource; -/** SpanProcessor decorator that drops discarded spans. - - Wraps a delegate processor (typically BatchSpanProcessor). In OnEnd(), - calls DiscardScope::isActive(). If the calling thread is inside a - DiscardScope (entered by SpanGuard::discard()), the span is silently - dropped — never entering the batch queue, never sent over the network, - never stored. - - Uses a thread-local flag rather than inspecting Recordable attributes - because the Recordable type varies by exporter (SpanData for simple - exporters, OtlpRecordable for OTLP) and none expose a uniform getter. - The flag is safe because Span::End() calls OnEnd() synchronously on - the same thread. - - All other methods delegate directly to the wrapped processor. - - Dependency diagram: - - +---------------------------+ - | FilteringSpanProcessor | - +---------------------------+ - | - delegate_ : unique_ptr | - | | - +---------------------------+ - | wraps - +---------+-----------+ - | BatchSpanProcessor | - +---------------------+ - - @note Thread safety: OnEnd() may be called concurrently from multiple - threads. The discard flag behind DiscardScope is thread-local, so each - thread's discard state is independent — no synchronization needed. -*/ +/** + * SpanProcessor decorator that drops discarded spans. + * + * Wraps a delegate processor (typically BatchSpanProcessor). In OnEnd(), + * calls DiscardScope::isActive(). If the calling thread is inside a + * DiscardScope (entered by SpanGuard::discard()), the span is silently + * dropped — never entering the batch queue, never sent over the network, + * never stored. + * + * Uses a thread-local flag rather than inspecting Recordable attributes + * because the Recordable type varies by exporter (SpanData for simple + * exporters, OtlpRecordable for OTLP) and none expose a uniform getter. + * The flag is safe because Span::End() calls OnEnd() synchronously on + * the same thread. + * + * All other methods delegate directly to the wrapped processor. + * + * Dependency diagram: + * + * +---------------------------+ + * | FilteringSpanProcessor | + * +---------------------------+ + * | - delegate_ : unique_ptr | + * | | + * +---------------------------+ + * | wraps + * +---------+-----------+ + * | BatchSpanProcessor | + * +---------------------+ + * + * @note Thread safety: OnEnd() may be called concurrently from multiple + * threads. The discard flag behind DiscardScope is thread-local, so each + * thread's discard state is independent — no synchronization needed. + */ class FilteringSpanProcessor : public trace_sdk::SpanProcessor { std::unique_ptr delegate_; @@ -144,15 +146,18 @@ public: } }; -/** No-op implementation used when XRPL_ENABLE_TELEMETRY is defined but - setup.enabled is false at runtime. - - Lives in the anonymous namespace so there is no ODR conflict with the - NullTelemetry in NullTelemetry.cpp. -*/ +/** + * No-op implementation used when XRPL_ENABLE_TELEMETRY is defined but + * setup.enabled is false at runtime. + * + * Lives in the anonymous namespace so there is no ODR conflict with the + * NullTelemetry in NullTelemetry.cpp. + */ class NullTelemetryOtel : public Telemetry { - /** Retained configuration (unused, kept for diagnostic access). */ + /** + * Retained configuration (unused, kept for diagnostic access). + */ Setup const setup_; public: @@ -230,27 +235,32 @@ public: } }; -/** Full OTel SDK implementation that exports trace spans via OTLP/HTTP. - - Configures an OTLP/HTTP exporter, batch span processor, - TraceIdRatioBasedSampler, and resource attributes on start(). -*/ +/** + * Full OTel SDK implementation that exports trace spans via OTLP/HTTP. + * + * Configures an OTLP/HTTP exporter, batch span processor, + * TraceIdRatioBasedSampler, and resource attributes on start(). + */ class TelemetryImpl : public Telemetry { - /** Configuration from the [telemetry] config section. - Non-const so setServiceInstanceId() can update the instance ID - before start() creates the OTel resource. - */ + /** + * Configuration from the [telemetry] config section. + * Non-const so setServiceInstanceId() can update the instance ID + * before start() creates the OTel resource. + */ Setup setup_; - /** Journal used for log output during start/stop. */ + /** + * Journal used for log output during start/stop. + */ beast::Journal const journal_; - /** The SDK TracerProvider that owns the export pipeline. - - Held as std::shared_ptr so we can call ForceFlush() on shutdown. - Wrapped in a nostd::shared_ptr when registered as the global provider. - */ + /** + * The SDK TracerProvider that owns the export pipeline. + * + * Held as std::shared_ptr so we can call ForceFlush() on shutdown. + * Wrapped in a nostd::shared_ptr when registered as the global provider. + */ std::shared_ptr sdkProvider_; public: diff --git a/src/libxrpl/telemetry/TelemetryConfig.cpp b/src/libxrpl/telemetry/TelemetryConfig.cpp index af9d30d85f..e18a8d4a97 100644 --- a/src/libxrpl/telemetry/TelemetryConfig.cpp +++ b/src/libxrpl/telemetry/TelemetryConfig.cpp @@ -1,11 +1,12 @@ -/** Parser for the [telemetry] section of xrpld.cfg. - - Reads configuration values from the config file and populates a - Telemetry::Setup struct. All options have sensible defaults so the - section can be minimal or omitted entirely. - - See cfg/xrpld-example.cfg for the full list of available options. -*/ +/** + * Parser for the [telemetry] section of xrpld.cfg. + * + * Reads configuration values from the config file and populates a + * Telemetry::Setup struct. All options have sensible defaults so the + * section can be minimal or omitted entirely. + * + * See cfg/xrpld-example.cfg for the full list of available options. + */ #include #include @@ -18,13 +19,14 @@ namespace xrpl::telemetry { namespace { -/** Config key names for the [telemetry] section. - - Each must match the corresponding option documented in - cfg/xrpld-example.cfg verbatim. Defined as `char const*` so they - pass to Section::valueOr() (which takes `std::string const&`) - without an explicit conversion, exactly as a literal would. -*/ +/** + * Config key names for the [telemetry] section. + * + * Each must match the corresponding option documented in + * cfg/xrpld-example.cfg verbatim. Defined as `char const*` so they + * pass to Section::valueOr() (which takes `std::string const&`) + * without an explicit conversion, exactly as a literal would. + */ namespace key { constexpr char const* enabled = "enabled"; constexpr char const* serviceName = "service_name"; @@ -42,13 +44,14 @@ constexpr char const* tracePeer = "trace_peer"; constexpr char const* traceLedger = "trace_ledger"; } // namespace key -/** Default values applied when a key is absent from the config. - - @note serviceName mirrors SystemParameters' systemName() ("xrpld") but - is duplicated here as a literal: the telemetry module deliberately does - not link xrpl.libxrpl.protocol, so including SystemParameters.h would - introduce an undeclared cross-module dependency. -*/ +/** + * Default values applied when a key is absent from the config. + * + * @note serviceName mirrors SystemParameters' systemName() ("xrpld") but + * is duplicated here as a literal: the telemetry module deliberately does + * not link xrpl.libxrpl.protocol, so including SystemParameters.h would + * introduce an undeclared cross-module dependency. + */ namespace dflt { constexpr char const* serviceName = "xrpld"; constexpr char const* endpoint = "http://localhost:4318/v1/traces"; @@ -57,10 +60,11 @@ constexpr std::uint32_t batchDelayMs = 5000u; constexpr std::uint32_t maxQueueSize = 2048u; } // namespace dflt -/** Derive a human-readable network type label from the numeric network ID. - @param networkId The network identifier from [network_id] config. - @return "mainnet", "testnet", "devnet", or "unknown" for other values. -*/ +/** + * Derive a human-readable network type label from the numeric network ID. + * @param networkId The network identifier from [network_id] config. + * @return "mainnet", "testnet", "devnet", or "unknown" for other values. + */ std::string networkTypeFromId(std::uint32_t networkId) { diff --git a/src/xrpld/app/main/GRPCServer.h b/src/xrpld/app/main/GRPCServer.h index 2e00fe9b54..d8b19234e9 100644 --- a/src/xrpld/app/main/GRPCServer.h +++ b/src/xrpld/app/main/GRPCServer.h @@ -197,7 +197,9 @@ private: std::vector const& secureGatewayIPs_; - /// Human-readable name for telemetry spans (e.g. "GetLedger"). + /** + * Human-readable name for telemetry spans (e.g. "GetLedger"). + */ std::string_view name_; public: diff --git a/src/xrpld/app/main/GrpcSpanNames.h b/src/xrpld/app/main/GrpcSpanNames.h index 83f4f11f57..2eb2f44ca2 100644 --- a/src/xrpld/app/main/GrpcSpanNames.h +++ b/src/xrpld/app/main/GrpcSpanNames.h @@ -1,6 +1,7 @@ #pragma once -/** Compile-time span name constants for the gRPC subsystem. +/** + * Compile-time span name constants for the gRPC subsystem. * * All span prefixes, operation names, and attribute keys used by gRPC * tracing call sites are defined here. Built on the StaticStr/join() @@ -28,19 +29,27 @@ namespace xrpl::telemetry::grpc_span { // ===== Span prefixes ======================================================= namespace prefix { -/// "grpc" — root prefix for gRPC transport spans. The full span name is -/// formed at the call site as `grpc.` (see GRPCServer.cpp). +/** + * "grpc" — root prefix for gRPC transport spans. The full span name is + * formed at the call site as `grpc.` (see GRPCServer.cpp). + */ inline constexpr auto grpc = makeStr("grpc"); } // namespace prefix // ===== Attribute keys ====================================================== namespace attr { -/// "method" — gRPC method name (e.g. GetLedger). +/** + * "method" — gRPC method name (e.g. GetLedger). + */ inline constexpr auto method = makeStr("method"); -/// "grpc_role" — Domain-qualified: collides with rpc_role. +/** + * "grpc_role" — Domain-qualified: collides with rpc_role. + */ inline constexpr auto grpcRole = makeStr("grpc_role"); -/// "grpc_status" — Domain-qualified: avoids OTel reserved span status. +/** + * "grpc_status" — Domain-qualified: avoids OTel reserved span status. + */ inline constexpr auto grpcStatus = makeStr("grpc_status"); } // namespace attr diff --git a/src/xrpld/rpc/ServerHandler.h b/src/xrpld/rpc/ServerHandler.h index 2b9701a6b4..fbe487654e 100644 --- a/src/xrpld/rpc/ServerHandler.h +++ b/src/xrpld/rpc/ServerHandler.h @@ -192,10 +192,11 @@ private: void processSession(std::shared_ptr const&, std::shared_ptr coro); - /** Process an RPC request and write the reply to `output`. - @return false if the request resulted in an error response, true - otherwise. Lets the caller's enclosing span reflect the outcome. - */ + /** + * Process an RPC request and write the reply to `output`. + * @return false if the request resulted in an error response, true + * otherwise. Lets the caller's enclosing span reflect the outcome. + */ bool processRequest( Port const& port, diff --git a/src/xrpld/rpc/detail/PathFindSpanNames.h b/src/xrpld/rpc/detail/PathFindSpanNames.h index 71eb805ea3..65ce81bb96 100644 --- a/src/xrpld/rpc/detail/PathFindSpanNames.h +++ b/src/xrpld/rpc/detail/PathFindSpanNames.h @@ -1,6 +1,7 @@ #pragma once -/** Compile-time span name constants for PathFind tracing. +/** + * Compile-time span name constants for PathFind tracing. * * Covers the path_find and ripple_path_find RPC handlers, the * PathRequest computation engine, and the Pathfinder graph exploration. @@ -48,7 +49,9 @@ namespace xrpl::telemetry::pathfind_span { // ===== Span prefixes ======================================================= namespace prefix { -/// "pathfind" — root prefix for path finding spans. +/** + * "pathfind" — root prefix for path finding spans. + */ inline constexpr auto pathfind = makeStr("pathfind"); } // namespace prefix @@ -68,25 +71,43 @@ inline constexpr auto discover = makeStr("discover"); // `fast` or `num_paths` that other subsystems may introduce. namespace attr { -/// "pathfind_source_account" — originating account for path search. +/** + * "pathfind_source_account" — originating account for path search. + */ inline constexpr auto sourceAccount = makeStr("pathfind_source_account"); -/// "pathfind_dest_account" — destination account. +/** + * "pathfind_dest_account" — destination account. + */ inline constexpr auto destAccount = makeStr("pathfind_dest_account"); -/// "pathfind_fast" — whether fast pathfinding mode enabled. +/** + * "pathfind_fast" — whether fast pathfinding mode enabled. + */ inline constexpr auto fast = makeStr("pathfind_fast"); -/// "pathfind_search_level" — depth of graph exploration. +/** + * "pathfind_search_level" — depth of graph exploration. + */ inline constexpr auto searchLevel = makeStr("pathfind_search_level"); -/// "pathfind_num_paths" — total paths produced across the per-source-asset -/// loop in PathRequest::findPaths (sum of getBestPaths().size() per asset). +/** + * "pathfind_num_paths" — total paths produced across the per-source-asset + * loop in PathRequest::findPaths (sum of getBestPaths().size() per asset). + */ inline constexpr auto numPaths = makeStr("pathfind_num_paths"); -/// "pathfind_num_requests" — snapshot size of requests_ at update_all start -/// (may include weak_ptrs that subsequently expire during processing). +/** + * "pathfind_num_requests" — snapshot size of requests_ at update_all start + * (may include weak_ptrs that subsequently expire during processing). + */ inline constexpr auto numRequests = makeStr("pathfind_num_requests"); -/// "pathfind_ledger_index" — pathfind target ledger index. +/** + * "pathfind_ledger_index" — pathfind target ledger index. + */ inline constexpr auto ledgerIndex = makeStr("pathfind_ledger_index"); -/// "pathfind_dest_currency" — destination currency code. +/** + * "pathfind_dest_currency" — destination currency code. + */ inline constexpr auto destCurrency = makeStr("pathfind_dest_currency"); -/// "pathfind_num_source_assets" — candidate source assets count. +/** + * "pathfind_num_source_assets" — candidate source assets count. + */ inline constexpr auto numSourceAssets = makeStr("pathfind_num_source_assets"); } // namespace attr diff --git a/src/xrpld/rpc/detail/RpcSpanNames.h b/src/xrpld/rpc/detail/RpcSpanNames.h index 88fd299f29..07202a7592 100644 --- a/src/xrpld/rpc/detail/RpcSpanNames.h +++ b/src/xrpld/rpc/detail/RpcSpanNames.h @@ -1,6 +1,7 @@ #pragma once -/** Compile-time span name constants for the RPC subsystem. +/** + * Compile-time span name constants for the RPC subsystem. * * All span prefixes, operation names, and attribute keys used by RPC * tracing call sites are defined here. Built on the StaticStr/join() @@ -116,9 +117,13 @@ namespace xrpl::telemetry::rpc_span { // ===== Span prefixes ======================================================= namespace prefix { -/// "rpc" — root prefix for transport-level spans. +/** + * "rpc" — root prefix for transport-level spans. + */ inline constexpr auto rpc = seg::rpc; -/// "rpc.command" — prefix for individual RPC command spans. +/** + * "rpc.command" — prefix for individual RPC command spans. + */ inline constexpr auto command = join(seg::rpc, makeStr("command")); } // namespace prefix @@ -134,21 +139,37 @@ inline constexpr auto process = makeStr("process"); // ===== Attribute keys ====================================================== namespace attr { -/// "command" — RPC method name. +/** + * "command" — RPC method name. + */ inline constexpr auto command = makeStr("command"); -/// "version" — api_version per request. +/** + * "version" — api_version per request. + */ inline constexpr auto version = makeStr("version"); -/// "rpc_role" — admin|user. Domain-qualified: collides with grpc_role. +/** + * "rpc_role" — admin|user. Domain-qualified: collides with grpc_role. + */ inline constexpr auto rpcRole = makeStr("rpc_role"); -/// "rpc_status" — success|error. Domain-qualified: avoids OTel reserved span status. +/** + * "rpc_status" — success|error. Domain-qualified: avoids OTel reserved span status. + */ inline constexpr auto rpcStatus = makeStr("rpc_status"); -/// "request_payload_size" — bytes of inbound request payload. +/** + * "request_payload_size" — bytes of inbound request payload. + */ inline constexpr auto requestPayloadSize = makeStr("request_payload_size"); -/// "is_batch" — whether request is a JSON-RPC batch. +/** + * "is_batch" — whether request is a JSON-RPC batch. + */ inline constexpr auto isBatch = makeStr("is_batch"); -/// "batch_size" — number of sub-requests in a batch. +/** + * "batch_size" — number of sub-requests in a batch. + */ inline constexpr auto batchSize = makeStr("batch_size"); -/// "load_type" — resource cost category after execution. +/** + * "load_type" — resource cost category after execution. + */ inline constexpr auto loadType = makeStr("load_type"); } // namespace attr @@ -160,7 +181,9 @@ using telemetry::attr_val::success; inline constexpr auto admin = makeStr("admin"); inline constexpr auto user = makeStr("user"); inline constexpr auto unknownCommand = makeStr("unknown"); -/// "invalid_json" — WS message parse failure or oversize. +/** + * "invalid_json" — WS message parse failure or oversize. + */ inline constexpr auto invalidJson = makeStr("invalid_json"); } // namespace val