mirror of
https://github.com/XRPLF/rippled.git
synced 2026-09-27 15:28:03 +00:00
merge: bring the review fixes forward from otel-phase8-log-correlation
This commit is contained in:
@@ -317,7 +317,9 @@ namespace event {
|
||||
*/
|
||||
inline constexpr auto disputeResolve = join(makeStr("dispute"), makeStr("resolve"));
|
||||
/**
|
||||
* "tx.included"
|
||||
* "tx.included" — one per transaction of the agreed consensus set, recorded
|
||||
* before the ledger is built. A transaction that then fails to apply still
|
||||
* has an event, so this is a superset of the accepted ledger's contents.
|
||||
*/
|
||||
inline constexpr auto txIncluded = join(makeStr("tx"), makeStr("included"));
|
||||
|
||||
|
||||
@@ -103,6 +103,7 @@
|
||||
|
||||
#ifdef XRPL_ENABLE_TELEMETRY
|
||||
#include <opentelemetry/context/context.h>
|
||||
#include <opentelemetry/exporters/otlp/otlp_http_exporter_options.h>
|
||||
#include <opentelemetry/metrics/meter.h>
|
||||
#include <opentelemetry/nostd/shared_ptr.h>
|
||||
#include <opentelemetry/trace/span.h>
|
||||
@@ -150,6 +151,69 @@ inline constexpr auto kDefaultMetricExportInterval = std::chrono::milliseconds{1
|
||||
*/
|
||||
inline constexpr auto kDefaultMetricExportTimeout = std::chrono::milliseconds{500};
|
||||
|
||||
/**
|
||||
* How a consensus round span picks its trace id.
|
||||
*
|
||||
* consensus_trace_strategy (xrpld.cfg)
|
||||
* |
|
||||
* v
|
||||
* makeTelemetrySetup() ──> Setup::consensusTraceStrategy
|
||||
* |
|
||||
* v
|
||||
* RCLConsensus::Adaptor::startRoundTracing()
|
||||
* |
|
||||
* +-- Deterministic ──> SpanGuard::hashSpan(prev ledger hash)
|
||||
* +-- Random ──> SpanGuard::span() / linkedSpan()
|
||||
*
|
||||
* Deterministic is the strategy in use. Every validator of a round hashes the
|
||||
* same previous ledger id, so all of them land in one trace.
|
||||
*
|
||||
* Random is experimental and not used. Each node would invent its own trace
|
||||
* id, so one round would arrive as one trace per node, joinable only by the
|
||||
* `consensus_ledger_id` attribute.
|
||||
*
|
||||
* @code
|
||||
* // Branch on the strategy rather than on a string.
|
||||
* if (telemetry.getConsensusTraceStrategy() == ConsensusTraceStrategy::Random)
|
||||
* span = SpanGuard::span(TraceCategory::Consensus, seg::consensus, op::round);
|
||||
* else
|
||||
* span = SpanGuard::hashSpan(TraceCategory::Consensus, name, id.data(), id.kBytes);
|
||||
*
|
||||
* // Edge case: the value also goes on a span attribute, so it needs its
|
||||
* // config spelling back.
|
||||
* span.setAttribute(attr::traceStrategy, strategyName(ConsensusTraceStrategy::Random));
|
||||
* @endcode
|
||||
*
|
||||
* @note Adding an enumerator means adding a spelling to strategyName() below
|
||||
* and to the parser in TelemetryConfig.cpp. Both switch without a default, so
|
||||
* the compiler catches a missed one.
|
||||
*/
|
||||
enum class ConsensusTraceStrategy : std::uint8_t { Deterministic, Random };
|
||||
|
||||
/**
|
||||
* Config spelling of a consensus trace strategy.
|
||||
*
|
||||
* This is the same text `consensus_trace_strategy` accepts, and it is what
|
||||
* goes on the `trace_strategy` span attribute, so the two cannot drift.
|
||||
*
|
||||
* @param strategy Strategy to name.
|
||||
* @return "deterministic" or "random", pointing at a string literal.
|
||||
*/
|
||||
[[nodiscard]] constexpr char const*
|
||||
strategyName(ConsensusTraceStrategy strategy)
|
||||
{
|
||||
switch (strategy)
|
||||
{
|
||||
case ConsensusTraceStrategy::Deterministic:
|
||||
return "deterministic";
|
||||
case ConsensusTraceStrategy::Random:
|
||||
return "random";
|
||||
}
|
||||
// The switch covers every enumerator. This return only satisfies the
|
||||
// compiler, which cannot rule out a value outside the enumeration.
|
||||
return "deterministic";
|
||||
}
|
||||
|
||||
class Telemetry
|
||||
{
|
||||
/**
|
||||
@@ -338,12 +402,12 @@ public:
|
||||
bool traceLedger = true;
|
||||
|
||||
/**
|
||||
* Strategy for cross-node consensus trace correlation.
|
||||
* "deterministic" — derive trace_id from ledger hash so all
|
||||
* validators in the same round share the same trace_id.
|
||||
* "attribute" — random trace_id, correlate via ledger_id attribute.
|
||||
* How a consensus round span picks its trace id.
|
||||
*
|
||||
* Read from `consensus_trace_strategy`. Deterministic is the strategy
|
||||
* in use; Random is experimental. See ConsensusTraceStrategy.
|
||||
*/
|
||||
std::string consensusTraceStrategy = "deterministic";
|
||||
ConsensusTraceStrategy consensusTraceStrategy = ConsensusTraceStrategy::Deterministic;
|
||||
};
|
||||
|
||||
virtual ~Telemetry() = default;
|
||||
@@ -433,9 +497,9 @@ public:
|
||||
shouldTraceLedger() const = 0;
|
||||
|
||||
/**
|
||||
* @return The configured consensus trace correlation strategy.
|
||||
* @return How a consensus round span picks its trace id.
|
||||
*/
|
||||
[[nodiscard]] virtual std::string const&
|
||||
[[nodiscard]] virtual ConsensusTraceStrategy
|
||||
getConsensusTraceStrategy() const = 0;
|
||||
|
||||
#ifdef XRPL_ENABLE_TELEMETRY
|
||||
@@ -527,10 +591,12 @@ makeTelemetry(Telemetry::Setup const& setup, beast::Journal journal);
|
||||
* @return A populated Setup struct with defaults for missing values.
|
||||
* @throws std::runtime_error If `enabled` is set and the mutual TLS (mTLS)
|
||||
* settings contradict each other: only one of `tls_client_cert`/`tls_client_key`
|
||||
* is given, or a client certificate is given while `use_tls` is 0. Also if
|
||||
* is given, a client certificate is given while `use_tls` is 0, or a client
|
||||
* certificate is given while `traces_endpoint` is not an `https://` URL — which
|
||||
* includes leaving `traces_endpoint` at its plain-HTTP default. Also if
|
||||
* `enabled` and `use_tls` are both set and a non-empty `tls_ca_cert`,
|
||||
* `tls_client_cert` or `tls_client_key` cannot be read; an empty path is skipped,
|
||||
* so an empty `tls_ca_cert` still means "use the system CA store". All three
|
||||
* so an empty `tls_ca_cert` still means "use the system CA store". All four
|
||||
* checks are skipped when `enabled` is 0. Also if `metric_export_interval_ms`
|
||||
* or `metric_export_timeout_ms` is unreadable, is not positive, or the timeout
|
||||
* is not below the interval. Those three run whether telemetry is on or off.
|
||||
@@ -558,4 +624,46 @@ makeTelemetrySetup(
|
||||
[[nodiscard]] std::string
|
||||
networkTypeFromId(std::uint32_t networkId);
|
||||
|
||||
#ifdef XRPL_ENABLE_TELEMETRY
|
||||
/**
|
||||
* Build the OTLP/HTTP trace exporter options that Setup asks for.
|
||||
*
|
||||
* Telemetry::Setup ──> makeTraceExporterOptions() ──> OtlpHttpExporterOptions
|
||||
* |
|
||||
* v
|
||||
* OtlpHttpExporterFactory::Create
|
||||
*
|
||||
* Named and declared here rather than left inline in start() so the mapping
|
||||
* from config to exporter options can be asserted directly. A swapped
|
||||
* certificate and key, or a CA path written to the wrong field, is invisible
|
||||
* from outside a running exporter.
|
||||
*
|
||||
* TLS fields are set only when `use_tls` is on. Whether the transport is
|
||||
* actually encrypted is decided by the scheme of the URL, not by this function;
|
||||
* makeTelemetrySetup() is what rejects a client certificate on a plain-HTTP
|
||||
* endpoint.
|
||||
*
|
||||
* @code
|
||||
* // Primary use: one-way TLS with a custom CA bundle.
|
||||
* Telemetry::Setup setup;
|
||||
* setup.useTls = true;
|
||||
* setup.tlsCertPath = "/etc/ssl/ca.pem";
|
||||
* auto const opts = makeTraceExporterOptions(setup); // ssl_ca_cert_path set
|
||||
*
|
||||
* // Edge case: use_tls off leaves every ssl_ field empty, even when paths
|
||||
* // are configured.
|
||||
* setup.useTls = false;
|
||||
* auto const plain = makeTraceExporterOptions(setup); // ssl_ca_cert_path empty
|
||||
* @endcode
|
||||
*
|
||||
* @param setup Parsed [telemetry] configuration.
|
||||
* @return Options carrying `traces_endpoint` as the URL, plus the TLS paths
|
||||
* when `use_tls` is on. Every other field keeps its SDK default.
|
||||
* @note Pure: reads `setup` and touches no global state, so it is safe to call
|
||||
* from any thread.
|
||||
*/
|
||||
[[nodiscard]] opentelemetry::exporter::otlp::OtlpHttpExporterOptions
|
||||
makeTraceExporterOptions(Telemetry::Setup const& setup);
|
||||
#endif
|
||||
|
||||
} // namespace xrpl::telemetry
|
||||
|
||||
Reference in New Issue
Block a user