mirror of
https://github.com/XRPLF/rippled.git
synced 2026-06-06 18:26:51 +00:00
The tx.transactor span covered only the apply stage; preflight and preclaim had no telemetry, so a transaction that hard-failed those stages produced no apply-pipeline span and per-stage latency/failure was invisible. Add tx.preflight and tx.preclaim spans in applySteps.cpp via a makeStageSpan() helper using SpanGuard::hashSpan, so all three stages share a deterministic trace_id derived from txID[0:16] even though they run sequentially and often cross-thread. Each span carries stage, tx_type, and ter_result; exceptions are recorded as tefEXCEPTION before the public wrappers map them. The type lookup is guarded behind the span-active check so it costs nothing when tracing is off. Add a stage="apply" attribute to the tx.transactor span and move its three hardcoded attribute strings to a new library-safe header include/xrpl/tx/detail/TxApplySpanNames.h, which mirrors the daemon-side TxSpanNames.h strings so the collector spanmetrics connector aggregates both span sets under one dimension set. A constants-contract test pins the span-name, attribute-key, and stage-value strings; span content stays covered by the docker integration test, as the rest of the telemetry suite is. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
53 lines
2.2 KiB
C++
53 lines
2.2 KiB
C++
#include <xrpl/tx/detail/TxApplySpanNames.h>
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#include <string_view>
|
|
|
|
/** Contract tests for the transaction apply-pipeline span constants.
|
|
*
|
|
* The span names and attribute keys in TxApplySpanNames.h are a cross-component
|
|
* contract: the collector spanmetrics connector aggregates on these exact
|
|
* strings (dimensions tx_type, ter_result, stage) and the Grafana
|
|
* transaction-overview dashboard queries them. A silent rename here would
|
|
* break per-stage metrics with no compile error, so these tests pin the
|
|
* literal values. They need no telemetry runtime and run in every build.
|
|
*/
|
|
|
|
using namespace xrpl::telemetry;
|
|
|
|
TEST(TxApplySpanNames, span_names_are_dot_qualified)
|
|
{
|
|
// Full span names feed SpanGuard::hashSpan() in applySteps.cpp.
|
|
EXPECT_EQ(std::string_view(tx_apply_span::preflight), "tx.preflight");
|
|
EXPECT_EQ(std::string_view(tx_apply_span::preclaim), "tx.preclaim");
|
|
}
|
|
|
|
TEST(TxApplySpanNames, operation_suffixes)
|
|
{
|
|
// Suffix used with SpanGuard::span(cat, seg::tx, suffix) in Transactor.cpp.
|
|
EXPECT_EQ(std::string_view(tx_apply_span::op::preflight), "preflight");
|
|
EXPECT_EQ(std::string_view(tx_apply_span::op::preclaim), "preclaim");
|
|
EXPECT_EQ(std::string_view(tx_apply_span::op::transactor), "transactor");
|
|
}
|
|
|
|
TEST(TxApplySpanNames, attribute_keys_match_collector_dimensions)
|
|
{
|
|
// These keys MUST match docker/telemetry/otel-collector-config.yaml
|
|
// spanmetrics dimensions and TxSpanNames.h (so both span sets aggregate
|
|
// under one dimension).
|
|
EXPECT_EQ(std::string_view(tx_apply_span::attr::stage), "stage");
|
|
EXPECT_EQ(std::string_view(tx_apply_span::attr::txType), "tx_type");
|
|
EXPECT_EQ(std::string_view(tx_apply_span::attr::terResult), "ter_result");
|
|
EXPECT_EQ(std::string_view(tx_apply_span::attr::applied), "applied");
|
|
}
|
|
|
|
TEST(TxApplySpanNames, stage_values_are_the_three_pipeline_stages)
|
|
{
|
|
// The stage attribute carries exactly these three values; they become the
|
|
// spanmetrics `stage` dimension cardinality (3) and the dashboard filter.
|
|
EXPECT_EQ(std::string_view(tx_apply_span::val::preflight), "preflight");
|
|
EXPECT_EQ(std::string_view(tx_apply_span::val::preclaim), "preclaim");
|
|
EXPECT_EQ(std::string_view(tx_apply_span::val::apply), "apply");
|
|
}
|