refactor(telemetry): replace txSpan with generic hashSpan factory

Replace SpanGuard::txSpan(prefix, name, hash) with the generic
SpanGuard::hashSpan(TraceCategory, name, hash) that accepts a
TraceCategory parameter instead of hardcoding Transactions. This
enables reuse for consensus round spans (Phase 4) and any future
subsystem needing deterministic cross-node trace correlation via
hash-derived trace IDs.

Both overloads are replaced:
- hashSpan(cat, name, hash, size) — standalone with random span_id
- hashSpan(cat, name, hash, size, parentSpanId, parentSize, flags)
  — with remote parent from protobuf context propagation

Add full span name constants (tx_span::receive, tx_span::process)
to TxSpanNames.h following the ConsensusSpanNames.h pattern.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Pratik Mankawde
2026-04-28 12:44:31 +01:00
parent 8afe604aff
commit a05ada89ec
4 changed files with 42 additions and 36 deletions

View File

@@ -20,9 +20,9 @@
#ifdef XRPL_ENABLE_TELEMETRY
#include <xrpl/basics/random.h>
#include <xrpl/telemetry/SpanGuard.h>
#include <xrpl/basics/random.h>
#include <xrpl/telemetry/DiscardFlag.h>
#include <xrpl/telemetry/SpanNames.h>
#include <xrpl/telemetry/Telemetry.h>
@@ -233,11 +233,11 @@ SpanGuard::linkedSpan(std::string_view name, SpanContext const& linkCtx)
opts)));
}
// ===== Transaction span with hash-derived trace ID ========================
// ===== Hash-derived span (category-gated) ==================================
SpanGuard
SpanGuard::txSpan(
std::string_view prefix,
SpanGuard::hashSpan(
TraceCategory cat,
std::string_view name,
std::uint8_t const* hashData,
std::size_t hashSize)
@@ -245,7 +245,7 @@ SpanGuard::txSpan(
if (hashSize < 16)
return {};
auto* tel = Telemetry::getInstance();
if (!tel || !tel->isEnabled() || !tel->shouldTraceTransactions())
if (!tel || !tel->isEnabled() || !isCategoryEnabled(*tel, cat))
return {};
otel_trace::TraceId traceId(opentelemetry::nostd::span<std::uint8_t const, 16>(hashData, 16));
@@ -263,13 +263,12 @@ SpanGuard::txSpan(
opentelemetry::nostd::shared_ptr<otel_trace::Span>(
new otel_trace::DefaultSpan(syntheticCtx)));
auto fullName = std::string(prefix) + "." + std::string(name);
return SpanGuard(std::make_unique<Impl>(tel->startSpan(fullName, parentCtx)));
return SpanGuard(std::make_unique<Impl>(tel->startSpan(std::string(name), parentCtx)));
}
SpanGuard
SpanGuard::txSpan(
std::string_view prefix,
SpanGuard::hashSpan(
TraceCategory cat,
std::string_view name,
std::uint8_t const* hashData,
std::size_t hashSize,
@@ -280,7 +279,7 @@ SpanGuard::txSpan(
if (hashSize < 16 || parentSpanSize != 8)
return {};
auto* tel = Telemetry::getInstance();
if (!tel || !tel->isEnabled() || !tel->shouldTraceTransactions())
if (!tel || !tel->isEnabled() || !isCategoryEnabled(*tel, cat))
return {};
otel_trace::TraceId traceId(opentelemetry::nostd::span<std::uint8_t const, 16>(hashData, 16));
@@ -296,8 +295,7 @@ SpanGuard::txSpan(
opentelemetry::nostd::shared_ptr<otel_trace::Span>(
new otel_trace::DefaultSpan(combinedCtx)));
auto fullName = std::string(prefix) + "." + std::string(name);
return SpanGuard(std::make_unique<Impl>(tel->startSpan(fullName, parentCtx)));
return SpanGuard(std::make_unique<Impl>(tel->startSpan(std::string(name), parentCtx)));
}
// ===== Context capture =====================================================

View File

@@ -35,6 +35,11 @@ inline constexpr auto receive = makeStr("receive");
inline constexpr auto process = makeStr("process");
} // namespace op
// ===== Full span names (prefix.op) =========================================
inline constexpr auto receive = join(prefix::tx, op::receive);
inline constexpr auto process = join(prefix::tx, op::process);
// ===== Attribute keys ======================================================
namespace attr {

View File

@@ -33,9 +33,9 @@ txReceiveSpan(uint256 const& txID, [[maybe_unused]] protocol::TMTransaction cons
auto const& tc = msg.trace_context();
if (tc.has_span_id() && tc.span_id().size() == 8)
{
return SpanGuard::txSpan(
tx_span::prefix::tx,
tx_span::op::receive,
return SpanGuard::hashSpan(
TraceCategory::Transactions,
tx_span::receive,
txID.data(),
txID.bytes,
reinterpret_cast<std::uint8_t const*>(tc.span_id().data()),
@@ -45,7 +45,8 @@ txReceiveSpan(uint256 const& txID, [[maybe_unused]] protocol::TMTransaction cons
}
}
#endif
return SpanGuard::txSpan(tx_span::prefix::tx, tx_span::op::receive, txID.data(), txID.bytes);
return SpanGuard::hashSpan(
TraceCategory::Transactions, tx_span::receive, txID.data(), txID.bytes);
}
/** Create a "tx.process" span for transaction processing in NetworkOPs.
@@ -54,7 +55,8 @@ txReceiveSpan(uint256 const& txID, [[maybe_unused]] protocol::TMTransaction cons
inline SpanGuard
txProcessSpan(uint256 const& txID)
{
return SpanGuard::txSpan(tx_span::prefix::tx, tx_span::op::process, txID.data(), txID.bytes);
return SpanGuard::hashSpan(
TraceCategory::Transactions, tx_span::process, txID.data(), txID.bytes);
}
} // namespace telemetry