mirror of
https://github.com/XRPLF/rippled.git
synced 2026-09-27 23:38:08 +00:00
Eighteen conflict regions across nine files. Resolved by asking, per region, which side is the better final state rather than by taking a branch wholesale. Telemetry.cpp keeps phase-9's two resource builders. phase-8 offered a single makeResource() with no node identity; phase-9 splits it into makeTracerResource() and makeMetricsResource() because the metrics provider is built in the constructor, before setNodeId() runs, so xrpl.node.id can only be stamped unconditionally on the tracer side. Collapsing them would have dropped that attribute, which is what keeps per-node traces from folding into one identity. Telemetry.h and the config test compose both sides: phase-9's nodeId member and its assertion, plus the renamed endpoint. xrpld-telemetry.cfg keeps phase-9's devnet identity and its metrics_endpoint, renames the traces key, and drops exporter=otlp_http. Nothing reads an `exporter` key on any branch in the chain: it was a real Setup member in the first phase-1b implementation, removed when only OTLP/HTTP was wired up, and already deleted from TESTING.md once on the same grounds. The cfg line was the last carrier. The docs keep phase-9's versions, which are both fuller and more accurate: the incoming runbook listed the consensus strategy values as "random" where the code compares against "attribute". OTelCollector.cpp had five comment-only regions in a file phase-7 owns, so those take the upstream side. MetricsRegistry.h's usage example named a member that no longer exists and the wrong arity; it now matches the real three-argument call and says where the endpoint comes from.
194 lines
7.4 KiB
C++
194 lines
7.4 KiB
C++
#pragma once
|
|
|
|
/**
|
|
* Compile-time string concatenation utility and shared telemetry constants.
|
|
*
|
|
* Provides StaticStr<N> — 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
|
|
* 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
|
|
* concatenation support. boost::static_string is not constexpr.
|
|
* StaticStr<N> exists specifically for compile-time dot-join composition.
|
|
*
|
|
* Naming conventions (see spec 2026-05-13-span-attr-naming-design):
|
|
* - Per-span attribute keys: bare field name (span name carries the domain).
|
|
* - Collision qualifier: <domain>_<field> when bare name collides across
|
|
* domains or with OTel reserved `status` (e.g. rpc_status, grpc_status).
|
|
* - Shared cross-span attributes: <domain>_<field> (underscore) form
|
|
* (e.g. tx_hash, peer_id, ledger_seq, consensus_round).
|
|
* - Resource attribute keys: xrpl.<subsystem>.<field> (dotted) form is
|
|
* RESERVED for process-identity attributes set once at startup on the
|
|
* OTel resource (e.g. xrpl.network.id, xrpl.network.type). Do not use
|
|
* this form for span attributes — it parses awkwardly in TraceQL and
|
|
* blurs the resource/span scope distinction.
|
|
* - Span prefixes: <subsystem>[.<component>].
|
|
*/
|
|
|
|
#include <cstddef>
|
|
#include <string_view>
|
|
|
|
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.
|
|
*/
|
|
template <std::size_t N>
|
|
struct StaticStr
|
|
{
|
|
char data[N + 1]{};
|
|
static constexpr std::size_t size = N;
|
|
|
|
constexpr StaticStr() = default;
|
|
|
|
constexpr explicit StaticStr(char const (&str)[N + 1])
|
|
{
|
|
for (std::size_t i = 0; i <= N; ++i)
|
|
data[i] = str[i];
|
|
}
|
|
|
|
constexpr
|
|
operator std::string_view() const noexcept
|
|
{
|
|
return {data, N};
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Deduction guide: StaticStr from string literal.
|
|
*/
|
|
template <std::size_t N>
|
|
StaticStr(char const (&)[N]) -> StaticStr<N - 1>;
|
|
|
|
/**
|
|
* Create a StaticStr from a string literal.
|
|
*/
|
|
template <std::size_t N>
|
|
constexpr auto
|
|
makeStr(char const (&str)[N])
|
|
{
|
|
return StaticStr<N - 1>(str);
|
|
}
|
|
|
|
/**
|
|
* Concatenate two StaticStr values with a dot separator.
|
|
*/
|
|
template <std::size_t A, std::size_t B>
|
|
constexpr auto
|
|
join(StaticStr<A> const& lhs, StaticStr<B> const& rhs)
|
|
{
|
|
constexpr std::size_t len = A + 1 + B; // lhs + '.' + rhs
|
|
StaticStr<len> result;
|
|
std::size_t pos = 0;
|
|
for (std::size_t i = 0; i < A; ++i)
|
|
result.data[pos++] = lhs.data[i];
|
|
result.data[pos++] = '.';
|
|
for (std::size_t i = 0; i < B; ++i)
|
|
result.data[pos++] = rhs.data[i];
|
|
result.data[pos] = '\0';
|
|
return result;
|
|
}
|
|
|
|
// ===== Shared root segments ================================================
|
|
|
|
namespace seg {
|
|
inline constexpr auto xrpl = makeStr("xrpl");
|
|
inline constexpr auto rpc = makeStr("rpc");
|
|
inline constexpr auto tx = makeStr("tx");
|
|
inline constexpr auto consensus = makeStr("consensus");
|
|
inline constexpr auto peer = makeStr("peer");
|
|
inline constexpr auto ledger = makeStr("ledger");
|
|
inline constexpr auto network = makeStr("network");
|
|
inline constexpr auto node = makeStr("node");
|
|
inline constexpr auto link = makeStr("link");
|
|
} // namespace seg
|
|
|
|
// ===== Shared attribute keys (used across modules) =========================
|
|
|
|
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"));
|
|
|
|
/**
|
|
* Resource attribute `xrpl.node.id` — the node's base58 public key.
|
|
*
|
|
* Dotted form, like its siblings above, because it is a process-identity
|
|
* value stamped once on the OTel resource rather than a per-span attribute.
|
|
* It gives traces and metrics a stable per-node key alongside
|
|
* `service.instance.id`.
|
|
*/
|
|
inline constexpr auto nodeId = join(join(seg::xrpl, seg::node), makeStr("id"));
|
|
|
|
/**
|
|
* Canonical shared attrs (rule 5 — <domain>_<field> underscore form).
|
|
*
|
|
* Per the naming convention header note: shared cross-span attribute
|
|
* keys use the underscore form, reserving the dotted xrpl.<domain>.<field>
|
|
* form for resource attributes set on the OTel resource at startup.
|
|
* Defined once here, aliased by domain-specific headers. These are
|
|
* literal underscore-joined names, not dot-joined via `join()`, since
|
|
* `join()` always inserts `.` between its arguments.
|
|
*/
|
|
inline constexpr auto txHash = makeStr("tx_hash");
|
|
inline constexpr auto peerId = makeStr("peer_id");
|
|
inline constexpr auto ledgerSeq = makeStr("ledger_seq");
|
|
|
|
/**
|
|
* Shared close-time attrs — bare names, reused by consensus and ledger.
|
|
*
|
|
* `closeTimeRippleEpochS` carries a NetClock reading: whole seconds since the
|
|
* XRP Ledger epoch (2000-01-01T00:00:00Z), never the Unix epoch. The key names
|
|
* both the unit and the epoch because neither is recoverable from the value.
|
|
* A consumer rendering it as wall-clock time must first add kEpochOffset
|
|
* (946684800 seconds, see basics/chrono.h); read as a Unix timestamp instead,
|
|
* it lands roughly 30 years early.
|
|
*
|
|
* `closeResolutionMs` is a duration, not an instant — the granularity the
|
|
* close time is rounded to. NetClock resolution is whole seconds, so this
|
|
* value is always a multiple of 1000.
|
|
*/
|
|
inline constexpr auto closeTimeRippleEpochS = makeStr("close_time_ripple_epoch_s");
|
|
inline constexpr auto closeTimeCorrect = makeStr("close_time_correct");
|
|
inline constexpr auto closeResolutionMs = makeStr("close_resolution_ms");
|
|
/**
|
|
* Shared validation attrs — reused by the consensus and peer validation
|
|
* spans. Same concept, same key on every span; the span name tells them
|
|
* apart, so neither is emitter-prefixed. `ledgerHash` is a ledger-object
|
|
* property (bare, like ledgerSeq); `fullValidation` is the is-full-validation
|
|
* flag. Never the dotted xrpl. form (reserved for resource attrs).
|
|
*/
|
|
inline constexpr auto ledgerHash = makeStr("ledger_hash");
|
|
inline constexpr auto fullValidation = makeStr("full_validation");
|
|
|
|
/**
|
|
* Shared "ledger being worked on" attrs — the open/tentative or in-flight
|
|
* consensus-build ledger a transaction is applied into, NOT an established or
|
|
* validated ledger (that is `ledgerSeq`, set on ledger.build / consensus.round).
|
|
* Named after the RPC field `ledger_current_index` and the `currentLedgerSeq`
|
|
* log usage. Reused by the tx lifecycle, apply-pipeline, and TxQ spans so a
|
|
* transaction's work can be correlated to the ledger it targeted.
|
|
* `currentLedgerHash` is the current view's parent-ledger hash, which equals the
|
|
* consensus.round deterministic trace-id seed on the consensus-build path.
|
|
*/
|
|
inline constexpr auto currentLedgerSeq = makeStr("current_ledger_seq");
|
|
inline constexpr auto currentLedgerHash = makeStr("current_ledger_hash");
|
|
} // namespace attr
|
|
|
|
// ===== Shared attribute values =============================================
|
|
|
|
namespace attr_val {
|
|
inline constexpr auto success = makeStr("success");
|
|
inline constexpr auto error = makeStr("error");
|
|
} // namespace attr_val
|
|
|
|
} // namespace xrpl::telemetry
|