Add POC for OTel for RPC layer

Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
This commit is contained in:
Pratik Mankawde
2026-02-23 15:10:48 +00:00
parent 441ccd514c
commit 9bb7ea04cb
19 changed files with 1465 additions and 108 deletions

View File

@@ -19,6 +19,9 @@ class Manager;
namespace perf {
class PerfLog;
}
namespace telemetry {
class Telemetry;
}
// This is temporary until we migrate all code to use ServiceRegistry.
class Application;
@@ -205,6 +208,9 @@ public:
virtual perf::PerfLog&
getPerfLog() = 0;
virtual telemetry::Telemetry&
getTelemetry() = 0;
// Configuration and state
virtual bool
isStopping() const = 0;

View File

@@ -0,0 +1,105 @@
#pragma once
#ifdef XRPL_ENABLE_TELEMETRY
#include <opentelemetry/trace/span.h>
#include <opentelemetry/trace/scope.h>
#include <opentelemetry/context/runtime_context.h>
#include <opentelemetry/nostd/shared_ptr.h>
#include <string_view>
#include <exception>
namespace xrpl {
namespace telemetry {
class SpanGuard
{
opentelemetry::nostd::shared_ptr<opentelemetry::trace::Span> span_;
opentelemetry::trace::Scope scope_;
public:
explicit SpanGuard(
opentelemetry::nostd::shared_ptr<opentelemetry::trace::Span> span)
: span_(std::move(span)), scope_(span_)
{
}
SpanGuard(SpanGuard const&) = delete;
SpanGuard& operator=(SpanGuard const&) = delete;
SpanGuard(SpanGuard&& other) noexcept
: span_(std::move(other.span_)), scope_(span_)
{
other.span_ = nullptr;
}
SpanGuard& operator=(SpanGuard&&) = delete;
~SpanGuard()
{
if (span_)
span_->End();
}
opentelemetry::trace::Span&
span()
{
return *span_;
}
opentelemetry::trace::Span const&
span() const
{
return *span_;
}
void
setOk()
{
span_->SetStatus(opentelemetry::trace::StatusCode::kOk);
}
void
setStatus(
opentelemetry::trace::StatusCode code,
std::string_view description = "")
{
span_->SetStatus(code, std::string(description));
}
template <typename T>
void
setAttribute(std::string_view key, T&& value)
{
span_->SetAttribute(
opentelemetry::nostd::string_view(key.data(), key.size()),
std::forward<T>(value));
}
void
addEvent(std::string_view name)
{
span_->AddEvent(std::string(name));
}
void
recordException(std::exception const& e)
{
span_->AddEvent("exception", {
{"exception.type", "std::exception"},
{"exception.message", std::string(e.what())}
});
span_->SetStatus(
opentelemetry::trace::StatusCode::kError, e.what());
}
opentelemetry::context::Context
context() const
{
return opentelemetry::context::RuntimeContext::GetCurrent();
}
};
} // namespace telemetry
} // namespace xrpl
#endif // XRPL_ENABLE_TELEMETRY

View File

@@ -0,0 +1,92 @@
#pragma once
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/basics/BasicConfig.h>
#include <chrono>
#include <memory>
#include <string>
#include <string_view>
#ifdef XRPL_ENABLE_TELEMETRY
#include <opentelemetry/trace/tracer.h>
#include <opentelemetry/trace/span.h>
#include <opentelemetry/context/context.h>
#include <opentelemetry/nostd/shared_ptr.h>
#endif
namespace xrpl {
namespace telemetry {
class Telemetry
{
public:
struct Setup
{
bool enabled = false;
std::string serviceName = "rippled";
std::string serviceVersion;
std::string serviceInstanceId;
std::string exporterType = "otlp_http";
std::string exporterEndpoint = "http://localhost:4318/v1/traces";
bool useTls = false;
std::string tlsCertPath;
double samplingRatio = 1.0;
std::uint32_t batchSize = 512;
std::chrono::milliseconds batchDelay{5000};
std::uint32_t maxQueueSize = 2048;
std::uint32_t networkId = 0;
std::string networkType = "mainnet";
bool traceTransactions = true;
bool traceConsensus = true;
bool traceRpc = true;
bool tracePeer = false;
bool traceLedger = true;
};
virtual ~Telemetry() = default;
virtual void start() = 0;
virtual void stop() = 0;
virtual bool isEnabled() const = 0;
virtual bool shouldTraceTransactions() const = 0;
virtual bool shouldTraceConsensus() const = 0;
virtual bool shouldTraceRpc() const = 0;
virtual bool shouldTracePeer() const = 0;
#ifdef XRPL_ENABLE_TELEMETRY
virtual opentelemetry::nostd::shared_ptr<opentelemetry::trace::Tracer>
getTracer(std::string_view name = "rippled") = 0;
virtual opentelemetry::nostd::shared_ptr<opentelemetry::trace::Span>
startSpan(
std::string_view name,
opentelemetry::trace::SpanKind kind =
opentelemetry::trace::SpanKind::kInternal) = 0;
virtual opentelemetry::nostd::shared_ptr<opentelemetry::trace::Span>
startSpan(
std::string_view name,
opentelemetry::context::Context const& parentContext,
opentelemetry::trace::SpanKind kind =
opentelemetry::trace::SpanKind::kInternal) = 0;
#endif
};
std::unique_ptr<Telemetry>
make_Telemetry(Telemetry::Setup const& setup, beast::Journal journal);
Telemetry::Setup
setup_Telemetry(
Section const& section,
std::string const& nodePublicKey,
std::string const& version);
} // namespace telemetry
} // namespace xrpl