added comments and docs

Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
This commit is contained in:
Pratik Mankawde
2026-02-23 17:26:36 +00:00
parent 75332cf366
commit 37331f39b5
13 changed files with 598 additions and 18 deletions

View File

@@ -1,5 +1,17 @@
#pragma once
/** RAII guard for OpenTelemetry trace spans.
Wraps an OTel Span and Scope together. On construction, the span is
activated on the current thread's context (via Scope). On destruction,
the span is ended and the previous context is restored.
Used by the XRPL_TRACE_* macros in TracingInstrumentation.h. Can also
be stored in std::optional for conditional tracing (move-constructible).
Only compiled when XRPL_ENABLE_TELEMETRY is defined.
*/
#ifdef XRPL_ENABLE_TELEMETRY
#include <opentelemetry/trace/span.h>
@@ -13,18 +25,34 @@
namespace xrpl {
namespace telemetry {
/** RAII wrapper that activates a span on construction and ends it on
destruction. Non-copyable but move-constructible so it can be held
in std::optional for conditional tracing.
*/
class SpanGuard
{
/** The OTel span being guarded. Set to nullptr after move. */
opentelemetry::nostd::shared_ptr<opentelemetry::trace::Span> span_;
/** Scope that activates span_ on the current thread's context stack. */
opentelemetry::trace::Scope scope_;
public:
/** Construct a guard that activates @p span on the current context.
@param span The span to guard. Ended in the destructor.
*/
explicit SpanGuard(
opentelemetry::nostd::shared_ptr<opentelemetry::trace::Span> span)
: span_(std::move(span)), scope_(span_)
{
}
/** Non-copyable. Move-constructible to support std::optional.
The move constructor creates a new Scope from the transferred span,
because Scope is not movable.
*/
SpanGuard(SpanGuard const&) = delete;
SpanGuard& operator=(SpanGuard const&) = delete;
SpanGuard(SpanGuard&& other) noexcept
@@ -40,24 +68,32 @@ public:
span_->End();
}
/** @return A mutable reference to the underlying span. */
opentelemetry::trace::Span&
span()
{
return *span_;
}
/** @return A const reference to the underlying span. */
opentelemetry::trace::Span const&
span() const
{
return *span_;
}
/** Mark the span status as OK. */
void
setOk()
{
span_->SetStatus(opentelemetry::trace::StatusCode::kOk);
}
/** Set an explicit status code on the span.
@param code The OTel status code.
@param description Optional human-readable status description.
*/
void
setStatus(
opentelemetry::trace::StatusCode code,
@@ -66,6 +102,11 @@ public:
span_->SetStatus(code, std::string(description));
}
/** Set a key-value attribute on the span.
@param key Attribute name (e.g. "xrpl.rpc.command").
@param value Attribute value (string, int, bool, etc.).
*/
template <typename T>
void
setAttribute(std::string_view key, T&& value)
@@ -75,12 +116,21 @@ public:
std::forward<T>(value));
}
/** Add a named event to the span's timeline.
@param name Event name.
*/
void
addEvent(std::string_view name)
{
span_->AddEvent(std::string(name));
}
/** Record an exception as a span event following OTel semantic
conventions, and mark the span status as error.
@param e The exception to record.
*/
void
recordException(std::exception const& e)
{
@@ -92,6 +142,11 @@ public:
opentelemetry::trace::StatusCode::kError, e.what());
}
/** Return the current OTel context.
Useful for creating child spans on a different thread by passing
this context to Telemetry::startSpan(name, parentContext).
*/
opentelemetry::context::Context
context() const
{

View File

@@ -1,5 +1,23 @@
#pragma once
/** Abstract interface for OpenTelemetry distributed tracing.
Provides the Telemetry base class that all components use to create trace
spans. Two implementations exist:
- 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.
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.
*/
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/basics/BasicConfig.h>
@@ -21,55 +39,134 @@ namespace telemetry {
class Telemetry
{
public:
/** 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. */
bool enabled = false;
/** OTel resource attribute `service.name`. */
std::string serviceName = "rippled";
/** OTel resource attribute `service.version` (set from BuildInfo). */
std::string serviceVersion;
/** OTel resource attribute `service.instance.id` (defaults to node
public key). */
std::string serviceInstanceId;
/** Exporter type: currently only "otlp_http" is supported. */
std::string exporterType = "otlp_http";
/** OTLP/HTTP endpoint URL where spans are sent. */
std::string exporterEndpoint = "http://localhost:4318/v1/traces";
/** Whether to use TLS for the exporter connection. */
bool useTls = false;
/** Path to a CA certificate bundle for TLS verification. */
std::string tlsCertPath;
/** Head-based sampling ratio in [0.0, 1.0]. 1.0 = trace everything. */
double samplingRatio = 1.0;
/** Maximum number of spans per batch export. */
std::uint32_t batchSize = 512;
/** Delay between batch exports. */
std::chrono::milliseconds batchDelay{5000};
/** Maximum number of spans queued before dropping. */
std::uint32_t maxQueueSize = 2048;
/** Network identifier, added as an OTel resource attribute. */
std::uint32_t networkId = 0;
/** Network type label (e.g. "mainnet", "testnet", "devnet"). */
std::string networkType = "mainnet";
/** Enable tracing for transaction processing. */
bool traceTransactions = true;
/** Enable tracing for consensus rounds. */
bool traceConsensus = true;
/** Enable tracing for RPC request handling. */
bool traceRpc = true;
/** Enable tracing for peer-to-peer messages (disabled by default
due to high volume). */
bool tracePeer = false;
/** Enable tracing for ledger close/accept. */
bool traceLedger = true;
};
virtual ~Telemetry() = default;
/** 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.
*/
virtual void stop() = 0;
/** @return true if this instance is actively exporting spans. */
virtual bool isEnabled() const = 0;
/** @return true if transaction processing should be traced. */
virtual bool shouldTraceTransactions() const = 0;
/** @return true if consensus rounds should be traced. */
virtual bool shouldTraceConsensus() const = 0;
/** @return true if RPC request handling should be traced. */
virtual bool shouldTraceRpc() const = 0;
/** @return true if peer-to-peer messages should be traced. */
virtual bool shouldTracePeer() 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.
*/
virtual opentelemetry::nostd::shared_ptr<opentelemetry::trace::Tracer>
getTracer(std::string_view name = "rippled") = 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.<cmd>").
@param kind The span kind (defaults to kInternal).
@return A shared pointer to the new Span.
*/
virtual opentelemetry::nostd::shared_ptr<opentelemetry::trace::Span>
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.
*/
virtual opentelemetry::nostd::shared_ptr<opentelemetry::trace::Span>
startSpan(
std::string_view name,
@@ -79,9 +176,24 @@ 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.
*/
std::unique_ptr<Telemetry>
make_Telemetry(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.
@return A populated Setup struct with defaults for missing values.
*/
Telemetry::Setup
setup_Telemetry(
Section const& section,