mirror of
https://github.com/XRPLF/rippled.git
synced 2026-09-28 07:48:01 +00:00
Comments across the sync-diagnostic work described earlier revisions of the same change, or cited identifiers a reader of the merged tree cannot resolve. Prior-state comparisons rewritten in the present tense: - MetricsRegistry.cpp carried two adjacent paragraphs prescribing opposite behaviour for a disabled quorum, one publishing int64 max and one omitting the series. The code omits it; the superseded paragraph is gone and the surviving reason SIZE_MAX must not be cast is kept. - MallocTrim, LedgerMaster, LedgerReplayTask, TransactionAcquire, Application: say what the signal is the only record of, rather than what was 'previously trace-only', 'not logged at all here' or 'used to sit inside if (debug())'. - LedgerMaster.h and SpanGuardScope: without an explicit join each ledger's spans WOULD be separate traces -- not that they were 'before this'. - Handshake: the message is forwarded byte for byte, not 'byte-identical to the previous behaviour', and the helper throws rather than 'throws as before'. - MetricNames: quorum_disabled is a separate boolean rather than a sentinel, stated without what the state 'used to be encoded by'. - LedgerMaster.cpp no longer claims to mirror the unl_quorum gauge; it does not. That gauge omits the series while this stores int64 max. - 'Split out of' / 'Split from' become 'Kept separate from' in five places. Plan-internal identifiers removed: - All 24 WP-Ax / WP-Bx work-package labels across the telemetry tests, the collector configs, tempo.yaml and the expected_* inventories. They are defined in no file in the repo, so they resolve nowhere once merged. - The two references to OpenTelemetryPlan/, which does not reach develop, now point at docs/telemetry-glossary.md 'Fresh-node sync diagnostics'. Comments and JSON note strings only, no behaviour change.
150 lines
6.2 KiB
YAML
150 lines
6.2 KiB
YAML
# Grafana Tempo configuration for xrpld telemetry stack.
|
|
#
|
|
# Runs in single-binary mode for local development.
|
|
# Receives traces via OTLP/gRPC from the OTel Collector and stores
|
|
# them locally. Queryable via Grafana Explore using the Tempo datasource.
|
|
#
|
|
# Search filters are configured on the Grafana datasource side
|
|
# (grafana/provisioning/datasources/tempo.yaml). Tempo auto-indexes
|
|
# all span attributes for search in single-binary mode.
|
|
#
|
|
# For production, replace local storage with S3/GCS backend and adjust
|
|
# retention via the compactor settings. See:
|
|
# https://grafana.com/docs/tempo/latest/configuration/
|
|
|
|
stream_over_http_enabled: true
|
|
|
|
server:
|
|
http_listen_port: 3200
|
|
|
|
# Raise the TraceQL metrics query range limit. The default
|
|
# query_frontend.metrics.max_duration is 3h, so a dashboard set to a longer
|
|
# window (e.g. 6h/12h) fails with "range exceeds 3h0m0s". 168h matches the
|
|
# search max_duration and gives dashboards generous headroom.
|
|
query_frontend:
|
|
metrics:
|
|
max_duration: 168h
|
|
|
|
distributor:
|
|
receivers:
|
|
otlp:
|
|
protocols:
|
|
grpc:
|
|
endpoint: 0.0.0.0:4317
|
|
|
|
ingester:
|
|
max_block_duration: 5m
|
|
|
|
compactor:
|
|
compaction:
|
|
block_retention: 1h
|
|
|
|
# Enable metrics generator for service graph, span metrics, and the
|
|
# local-blocks processor. Produces RED metrics (rate, errors, duration) per
|
|
# service/span for the service map, and keeps recent trace blocks queryable so
|
|
# TraceQL metrics queries (quantile_over_time, count_over_time, etc. via
|
|
# /api/metrics/query_range) work.
|
|
metrics_generator:
|
|
registry:
|
|
external_labels:
|
|
source: tempo
|
|
storage:
|
|
path: /var/tempo/generator/wal
|
|
# Uncomment and add a Prometheus service to docker-compose.yml
|
|
# to enable remote_write for service graph metrics:
|
|
# remote_write:
|
|
# - url: http://prometheus:9090/api/v1/write
|
|
# Separate WAL the local-blocks processor flushes traces to for metrics
|
|
# queries. Required when flush_to_storage is true.
|
|
traces_storage:
|
|
path: /var/tempo/generator/traces
|
|
processor:
|
|
local_blocks:
|
|
# xrpld consensus/transaction spans are SPAN_KIND_INTERNAL. By default
|
|
# local-blocks keeps only server spans for TraceQL metrics, so attribute
|
|
# aggregations over internal spans return nothing. Keep all spans.
|
|
filter_server_spans: false
|
|
# Flush recent blocks to traces_storage so query_range can read them.
|
|
flush_to_storage: true
|
|
|
|
overrides:
|
|
defaults:
|
|
metrics_generator:
|
|
processors:
|
|
- service-graphs
|
|
- span-metrics
|
|
- local-blocks
|
|
|
|
storage:
|
|
trace:
|
|
backend: local
|
|
wal:
|
|
path: /var/tempo/wal
|
|
local:
|
|
path: /var/tempo/blocks
|
|
block:
|
|
# Give the highest-value span attributes their own Parquet columns so
|
|
# TraceQL scopes a search to one ledger without scanning the generic
|
|
# attribute list. Tempo indexes every attribute for search regardless;
|
|
# a dedicated column only changes the cost of filtering on it.
|
|
#
|
|
# ledger_hash is here rather than in the collector's spanmetrics
|
|
# `dimensions:` on purpose: it is a per-ledger value, so as a metric
|
|
# dimension it would mint one series per ledger acquired (unbounded
|
|
# cardinality). As a trace column it gives the same per-ledger lookup at
|
|
# zero metric cost -- which is how a single stuck or abandoned
|
|
# ledger.acquire is found: {name="ledger.acquire" && span.outcome=
|
|
# "abandoned" && span.ledger_hash="<hash>"}.
|
|
#
|
|
# txset_hash and remote_endpoint are here for the same reason and by the
|
|
# same rule: a tx-set root hash is one value per consensus round and a
|
|
# peer endpoint is one value per address dialled, so either as a
|
|
# spanmetrics dimension would mint an unbounded number of metric series.
|
|
# As trace columns they answer the per-object questions the metrics
|
|
# cannot -- which proposed set stalled a round:
|
|
# {name="txset.acquire" && span.outcome="timeout" &&
|
|
# span.txset_hash="<hash>"}
|
|
# and which peer a dial keeps failing against:
|
|
# {name="peer.dial" && span.outcome="tcp_fail" &&
|
|
# span.remote_endpoint="10.0.0.5:51235"}
|
|
#
|
|
# missing_nodes, served_nodes and duration_ms are deliberately NOT given
|
|
# columns. They are unbounded integers, so they are useless as equality
|
|
# filters; Tempo indexes every attribute for search regardless, so they
|
|
# remain queryable by range (e.g. span.missing_nodes > 0) at no
|
|
# storage cost, which is how they are actually read.
|
|
#
|
|
# The txset.acquire `round.request` event attributes get no column either,
|
|
# and cannot: this Tempo (2.9.4, docker-compose.yml) queries them via
|
|
# event:name / event.<attr>, but a dedicated column accepts only
|
|
# scope: span or scope: resource -- never event. Those event filters
|
|
# therefore scan rather than index, which is fine for the per-span lookup
|
|
# they are used for; do not add an event-scoped column to the list below.
|
|
#
|
|
# The ledger_hash column below carries a second job as of the per-ledger
|
|
# trace join, which is why it stays the highest-value column here.
|
|
# Every span for one ledger -- ledger.acquire, consensus.validation.accept,
|
|
# ledger.validate, ledger.store -- now derives its TRACE ID from that same
|
|
# ledger hash, so the whole story of one slow ledger is one trace:
|
|
# {span.ledger_hash="<hash>"}
|
|
# returns all of them across the three threads that produced them. The
|
|
# column is what makes that lookup cheap; it also stays the way a reader
|
|
# confirms two spans really are the same ledger rather than a trace-id
|
|
# coincidence, since the attribute holds the full 32 bytes while the trace
|
|
# id is only the leading 16.
|
|
#
|
|
# validation_status and accept_gated get no column: both are small closed
|
|
# value sets promoted to spanmetrics dimensions instead (see the collector
|
|
# configs), so the aggregate question is answered by a metric query and no
|
|
# per-value trace lookup is needed.
|
|
parquet_dedicated_columns:
|
|
- name: ledger_hash
|
|
type: string
|
|
scope: span
|
|
- name: txset_hash
|
|
type: string
|
|
scope: span
|
|
- name: remote_endpoint
|
|
type: string
|
|
scope: span
|