mirror of
https://github.com/XRPLF/rippled.git
synced 2026-08-21 14:20:56 +00:00
refactor(telemetry): retire the duplicate nodestore_latency gauge
nodestore_latency published six values that nodestore_state already publishes from the same Database accessors, so the two gauges were duplicate readings of the same atomics: write_count -> node_writes getStoreCount() read_count -> node_reads_total getFetchTotalCount() write_duration_us -> node_writes_duration_us getStoreDurationUs() read_duration_us -> node_reads_duration_us getFetchDurationUs() write_mean_us -> write_mean_us store duration / count read_mean_us -> read_mean_us fetch duration / count nodestore_state is kept because its means go through scaledMean(), which saturates at INT64_MAX instead of wrapping and omits a mean when the denominator is zero rather than reporting a misleading 0 us. Removes registerNodeStoreLatencyGauge, its instrument member, the metric::nodestoreLatency constant and the lval::nodestore_latency label namespace. The gauge-over-histogram rationale and the "p99 is not obtainable" consequence are folded into observeNodeStoreTotals' docs. Retargets the gauge-contract test onto nodestore_state rather than deleting it: the scaledMean arithmetic is covered by the static_asserts in tests/libxrpl/telemetry/MetricsRegistry.cpp, but nothing else asserts that these named series multiplex onto one instrument keyed by `metric`. The test now calls the production scaledMean instead of a copy of the division, and its sub-microsecond case asserts scaledMean's actual behaviour (a genuine mean of 0 on a zero numerator with a non-zero count), which differs from the retired gauge's extra numerator guard. Rewrites both ledger-sync-health copies' panel 38/39 queries and drops the obsolete claim that the write numerator was never written: all three concrete store paths call recordStoreDuration, so write_mean_us is live on an ordinary node. The same stale [import_db] caveat is removed from the runbook, the 09 reference row and the workload validator's note.
This commit is contained in:
2
.github/scripts/otel-naming/README.md
vendored
2
.github/scripts/otel-naming/README.md
vendored
@@ -56,7 +56,7 @@ hardcoded allowlist:
|
||||
| D | Every dashboard label resolves to an L1 span attribute, a native-metric label (L6, emitted by MetricsRegistry), or a Prometheus/Grafana builtin. TraceQL scope prefixes (`span.`/`resource.`/…) are stripped before the L1 lookup. |
|
||||
| E | No dotted `xrpl.<domain>.<field>` attribute key in the runbook (only the L1 resource attrs `xrpl.network.*` may be dotted). Span names, filenames, OTel-standard keys, and metric labels are not flagged. |
|
||||
| I | No string literals as **metric** instrument names or label keys — the mirror of Rule F. Applies to the name passed to an `XRPL_METRIC_*` macro or a `meter->Create*` factory and to the label _keys_ in its label set. Label _values_, descriptions, `*MetricNames.h`, `MetricMacros.h` and test files are exempt. Scoped by metric **family** (first underscore segment): declaring a constant opts that family in, so the metric surface can be converted subsystem by subsystem. Unconverted families warn as Rule L. |
|
||||
| J | Metric instrument names follow the suffix conventions: `lower_snake_case`, no `xrpld_`/`xrpl_` prefix (the exporter adds it), a counter ends `_total`, a histogram ends `_us`/`_ms`/`_seconds`, a gauge does not end `_total`. The instrument **kind** is read from the emit site, never guessed from words in the name — so a multi-series gauge carrying units in its label values (e.g. `nodestore_latency` observing `write_mean_us`) is not a violation. |
|
||||
| J | Metric instrument names follow the suffix conventions: `lower_snake_case`, no `xrpld_`/`xrpl_` prefix (the exporter adds it), a counter ends `_total`, a histogram ends `_us`/`_ms`/`_seconds`, a gauge does not end `_total`. The instrument **kind** is read from the emit site, never guessed from words in the name — so a multi-series gauge carrying units in its label values (e.g. `nodestore_state` observing `write_mean_us`) is not a violation. |
|
||||
| K | Every metric named in `docker/telemetry/workload/expected_metrics.json` resolves to a declared constant, so a rename in code cannot leave the workload validator asserting a name nothing emits. PromQL selectors (`m{label="v"}`) and exporter-appended histogram suffixes (`_bucket`/`_count`/`_sum`) are normalized away first; groups fed by another emit path (`statsd_gauges`, `statsd_counters`, `spanmetrics`) are out of scope by design. |
|
||||
|
||||
Rule F runs **unconditionally** (it is a purely syntactic check on the
|
||||
|
||||
@@ -1263,9 +1263,9 @@ def instrument_kinds(root: Path, wire_by_symbol: Dict[str, str]) -> Dict[str, st
|
||||
|
||||
The kind is what decides which suffix is correct, so it must be read from
|
||||
the emit site rather than guessed from the name -- guessing from words like
|
||||
"latency" mislabels a multi-series gauge whose units live in its label
|
||||
VALUES (e.g. `nodestore_latency` observing `write_mean_us`), which is a
|
||||
legitimate shape, not a violation.
|
||||
"latency" or "us" mislabels a multi-series gauge whose units live in its
|
||||
label VALUES (e.g. `nodestore_state` observing `write_mean_us`), which is
|
||||
a legitimate shape, not a violation.
|
||||
|
||||
Returns one of `counter`, `histogram`, `gauge`, `updown` per wire name.
|
||||
A name whose emit site is not found is absent from the result, so Rule J
|
||||
|
||||
@@ -1184,14 +1184,14 @@ class RuleJMetricSuffixes(unittest.TestCase):
|
||||
[],
|
||||
)
|
||||
|
||||
def test_gauge_named_latency_is_not_flagged(self):
|
||||
def test_gauge_with_unit_bearing_label_values_is_not_flagged(self):
|
||||
# The regression this rule's kind-awareness exists for: a multi-series
|
||||
# GAUGE whose units live in its label VALUES (nodestore_latency
|
||||
# GAUGE whose units live in its label VALUES (nodestore_state
|
||||
# observing write_mean_us) must not be read as a mis-suffixed duration.
|
||||
self.assertEqual(
|
||||
self._run(
|
||||
_mc("nodestoreLatency", "nodestore_latency"),
|
||||
'meter_->CreateInt64ObservableGauge(metric::nodestoreLatency, "d");\n',
|
||||
_mc("nodestoreState", "nodestore_state"),
|
||||
'meter_->CreateInt64ObservableGauge(metric::nodestoreState, "d");\n',
|
||||
),
|
||||
[],
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user