Every citation below was checked against the file it names: - LedgerMaster.cpp:463 is fixIndex, not the ledger.store span; that guard is at :470 and the insert it wraps at :476 - LedgerMaster.cpp:987 is the tvc assignment, which sits BEFORE the tvc < minVal return at :988; the ledger.validate span opens at :1003 - ServerHandler.cpp:705 is inside makeJsonError; processRequest is at :718 - docker-compose.yml:71 and :75 are comments in the collector's volume block; the loki service is at :112 and its config command at :116 Two claims were also wrong rather than merely stale. Log-trace correlation is gated in CI, because the workflow passes no --skip-loki, and the separate check in integration-test.sh is run by no workflow at all. The Loki label note described the Grafana Cloud collector config rather than the local one: only the cloud variant sets job=xrpld, and the local config's own comment says to select on service_name. The dashboards carry 35 Loki queries, not 38.
13 KiB
Phase 10: Synthetic Workload Generation & Telemetry Validation — Task List
Status: Future Enhancement
Goal: Build tools that generate realistic XRPL traffic to validate the full Phases 1-9 telemetry stack end-to-end — all spans, attributes, metrics, dashboards, and log-trace correlation — under controlled load.
Scope: Python/shell test harness + multi-node docker-compose environment + automated validation scripts + performance benchmarks.
Branch:
pratik/otel-phase10-workload-validation(frompratik/otel-phase9-metric-gap-fill)Depends on: Phase 9 (internal metric gap fill) — validates the full metric surface
Related Plan Documents
| Document | Relevance |
|---|---|
| 06-implementation-phases.md | Phase 10 plan: motivation, architecture, exit criteria (§6.8.3) |
| 09-data-collection-reference.md | Defines the full inventory of spans/metrics to validate |
| Phase9_taskList.md | Prerequisite — all internal metrics must be emitting |
Why This Phase Exists
Before Phases 1-9 can be considered production-ready, we need proof that:
- Every emitted span fires with its required attributes under real transaction
workloads (the "16 spans / 22 attributes" figures below are stale; the harness
derives both totals from
expected_spans.json) - All 255+ StatsD metrics + ~50 Phase 9 metrics appear in Prometheus with non-zero values
- Log-trace correlation (Phase 8) produces clickable trace_id links in Loki
- The 14 harness-asserted Grafana dashboards render meaningful data (no empty panels); 15 are on disk
- Performance overhead stays within bounds (< 3% CPU, < 5MB memory)
- The telemetry stack survives sustained load without data loss or queue backpressure
Task 10.1: Multi-Node Test Harness
Objective: Create a docker-compose environment with 3-5 validator nodes that produces real consensus rounds.
What to do:
-
Create
docker/telemetry/docker-compose.workload.yaml— as shipped this file holds only the observability backend:otel-collector,tempo,prometheus,loki,grafana. It contains no xrpld services.- Shared network (
workload-net) with service discovery
- Shared network (
-
The 5 validators are native
xrpldprocesses, not containers.docker/telemetry/workload/run-full-validation.sh(NUM_NODES=5) generates keys, writes a per-nodexrpld.cfg, and launches each node on127.0.0.1with sequential RPC / WS / peer ports. Each node:- Gets its validator key from
generate-validator-keys.sh - Lists the other 4 nodes in
ips_fixed - Has all telemetry enabled:
[telemetry] enabled=1,[insight] server=otel - Enables all trace categories including
trace_peer=1 - Writes logs to a file tailed by the OTel Collector filelog receiver
- Gets its validator key from
-
❌
make telemetry-workload-up/make telemetry-workload-downwere never implemented. There is noMakefileanywhere in the repository. The entry point isrun-full-validation.sh(with--profile,--nodes,--skip-loki,--skip-regression,--with-benchmark). The node-count flag is spelled--nodes, not--num-nodes—run-full-validation.sh:80(usage) and:100(thecasearm).NUM_NODESis the internal shell variable it assigns to.
Key files:
- New:
docker/telemetry/docker-compose.workload.yaml(backend only) - New:
docker/telemetry/workload/generate-validator-keys.sh - New:
docker/telemetry/workload/run-full-validation.sh— writes each node's cfg inline via a heredoc atrun-full-validation.sh:242(cat >"$NODE_DIR/xrpld.cfg" <<EOCFG) - New:
docker/telemetry/workload/xrpld-validator.cfg.template(96 lines) — it was created and is tracked on the Phase 10 branch, but it is unused: nothing reads it, and its{{NODE_INDEX}}/{{RPC_PORT}}/{{OTEL_ENDPOINT}}placeholders are never substituted, because the inline heredoc above supersedes it. Either wire the script to the template or delete the template — keeping both guarantees they drift.
Task 10.2: RPC Load Generator
Objective: Configurable tool that fires all traced RPC commands at controlled rates.
What to do:
-
Create
docker/telemetry/workload/rpc_load_generator.py:- Connects to one or more xrpld WebSocket endpoints
- Fires all RPC commands that have trace spans:
server_info,ledger,tx,account_info,account_lines,fee,submit, etc. - Configurable parameters: rate (RPS), duration, command distribution weights
- Injects
traceparentHTTP headers to test W3C context propagation - Logs progress and errors to stdout
-
Command distribution should match realistic production ratios:
- 40%
server_info/fee(health checks) - 30%
account_info/account_lines/account_objects(wallet queries) - 15%
ledger/ledger_data(explorer queries) - 10%
tx/account_tx(transaction lookups) - 5%
book_offers/amm_info(DEX queries)
- 40%
Key files:
- New:
docker/telemetry/workload/rpc_load_generator.py - New:
docker/telemetry/workload/requirements.txt
Task 10.3: Transaction Submitter
Objective: Generate diverse transaction types to exercise tx.* and ledger.* spans.
What to do:
-
Create
docker/telemetry/workload/tx_submitter.py:- Pre-funds test accounts from genesis account
- Submits a mix of transaction types:
Payment(XRP and issued currencies) — exercisestx.process,tx.applyOfferCreate/OfferCancel— DEX activityTrustSet— trust line creation for issued currenciesNFTokenMint/NFTokenCreateOffer/NFTokenAcceptOffer— NFT activityEscrowCreate/EscrowFinish— escrow lifecycleAMMCreate/AMMDeposit/AMMWithdraw— AMM pool operations (if amendment enabled)
- Configurable: TPS target, transaction mix weights, duration
- Monitors submission results and tracks success/failure rates
-
The transaction mix ensures the telemetry captures the full range of ledger activity that third parties care about.
Key files:
- New:
docker/telemetry/workload/tx_submitter.py - New:
docker/telemetry/workload/test_accounts.json(pre-generated keypairs)
Task 10.4: Telemetry Validation Suite
Objective: Automated scripts that verify all expected telemetry data exists after a workload run.
What to do:
-
Create
docker/telemetry/workload/validate_telemetry.py:Span validation (queries Tempo API):
- Assert every span name in
expected_spans.jsonappears in traces - Assert each span has its required attributes
- Assert parent-child relationships are correct.
rpc.requestno longer exists — it split intorpc.http_request(HTTP) andrpc.ws_message(WebSocket) (RpcSpanNames.h:135,:133). The two live trees are:- HTTP:
rpc.http_request→rpc.process→rpc.command.* - WebSocket:
rpc.ws_message→rpc.command.*— there is norpc.processon the WS path.rpc.processis created only inServerHandler::processRequest()(ServerHandler.cpp:718), reached fromprocessSession(Session, coro), i.e. HTTP only. Under WS-only loadrpc.processnever appears, andrpc.command.*parents directly torpc.ws_message.
- HTTP:
- Assert span durations are reasonable (> 0, < 60s)
Metric validation (queries Prometheus API):
- Assert all SpanMetrics-derived metrics are non-zero:
span_calls_total,span_duration_milliseconds_bucket(the connector'snamespaceisspan, nottraces_span_metrics—otel-collector-config.yaml:113-114) - Assert the insight-sourced metrics are non-zero:
ledgermaster_validated_ledger_age,peer_finder_active_{inbound,outbound}_peers, etc. — all lowercase, noxrpld_prefix (77f35c03dbremoved the prefix and lowercased names) - Assert all Phase 9 metrics are non-zero:
nodestore_state,cache_metrics,txq_metrics,rpc_method_{started,finished,errored}_total,object_count,load_factor_metrics - Assert metric label cardinality is within bounds
Log-trace correlation validation (queries Loki API):
- Assert logs contain
trace_id=andspan_id=fields - Pick a random trace_id from Tempo → query Loki for matching logs → assert results exist
- Assert Grafana derived field links are functional
Dashboard validation:
- For each dashboard, query the dashboard API and assert no panels show "No
data". There are 15 dashboards on disk; the harness asserts 14 —
log-derived-insightsis provisioned but unasserted.
- Assert every span name in
-
Output: JSON report with pass/fail per check, suitable for CI.
Key files:
- New:
docker/telemetry/workload/validate_telemetry.py - New:
docker/telemetry/workload/expected_spans.json(span inventory for validation) - New:
docker/telemetry/workload/expected_metrics.json(metric inventory for validation)
Task 10.5: Performance Benchmark Suite
Objective: Measure CPU/memory/latency overhead of the telemetry stack.
What to do:
-
Create
docker/telemetry/workload/benchmark.sh:- Baseline run: Start cluster with
[telemetry] enabled=0, run transaction workload for 5 minutes, record metrics - Telemetry run: Start cluster with full telemetry enabled, run identical workload, record metrics
- Comparison: Calculate deltas for:
- CPU usage (per-node average)
- Memory RSS (per-node peak)
- RPC p99 latency
- Transaction throughput (TPS)
- Consensus round time p95
- Ledger close time p95
- Baseline run: Start cluster with
-
Output: Markdown table comparing baseline vs. telemetry, with pass/fail against targets:
- CPU overhead < 3%
- Memory overhead < 5MB
- RPC latency impact < 2ms p99
- Throughput impact < 5%
- Consensus impact < 1%
-
Store results in
docker/telemetry/workload/benchmark-results/for historical tracking.
Key files:
- New:
docker/telemetry/workload/benchmark.sh - New:
docker/telemetry/workload/collect_system_metrics.sh
Task 10.6: CI Integration
Objective: Wire the validation suite into CI for regression detection.
What to do:
-
Create a CI workflow (GitHub Actions or equivalent) that:
- Builds xrpld with
-DXRPL_ENABLE_TELEMETRY=ON - Starts the multi-node workload harness
- Runs the RPC load generator + transaction submitter for 2 minutes
- Runs the validation suite
- Runs the benchmark suite
- Fails the build if any validation check fails or benchmark exceeds thresholds
- Archives the validation report and benchmark results as artifacts
- Builds xrpld with
-
This should be a separate workflow (not part of the main CI), triggered manually or on telemetry-related branch changes.
Key files:
- New:
.github/workflows/telemetry-validation.yml - New:
docker/telemetry/workload/run-full-validation.sh(orchestrator script)
Task 10.7: Documentation
Objective: Document the workload tools and validation process.
What to do:
-
Create
docker/telemetry/workload/README.md:- Quick start guide for running workload harness
- Configuration options for load generator and tx submitter
- How to read validation reports
- How to run benchmarks and interpret results
-
Update
docs/telemetry-runbook.md:- Add "Validating Telemetry Stack" section
- Add "Performance Benchmarking" section
-
Update
OpenTelemetryPlan/09-data-collection-reference.md:- Add "Validation" section with expected metric/span counts
Exit Criteria
- 5-node validator cluster starts and reaches consensus — as native
xrpldprocesses driven byrun-full-validation.sh, not from docker-compose - RPC load generator fires all traced RPC commands at configurable rates
- Transaction submitter generates 6+ transaction types at configurable TPS
- Validation suite confirms the full span / attribute / metric inventory
(totals computed dynamically from
expected_spans.json/expected_metrics.json, not the stale 16 / 22 figures) - Log-trace correlation validated end-to-end (Loki ↔ Tempo) — implemented,
and gated in CI: the workflow passes no
--skip-loki, sovalidate_telemetry.pybuilds and runs both log-correlation checks - All 14 harness-asserted Grafana dashboards render data (no empty panels); 15 on disk
- Benchmark shows < 3% CPU overhead, < 5MB memory overhead
- CI workflow runs validation on telemetry branch changes
- Validation report output is CI-parseable (JSON with exit codes)