Five signals that explain why a node is not advancing toward full, none of
which were observable before:
- state_changes_total now carries {from,to} mode labels, emitted at
setMode using the existing strOperatingMode helper. A bare count could
not distinguish a healthy climb from a node flapping between tracking
and connected. Removes the now-unused incrementStateChanges wrapper.
- sync_state{initial_full_duration_us}: time to first reach full, which
StateAccounting already computed but exposed only in server_info.
- sync_state{network_ledger_gate}: whether the node is still refusing to
build ledgers because it has no network ledger.
- sync_state{server_stall_seconds} and server_stall_events_total: how
long the main thread has been unresponsive. LoadManager computed this
and only logged it, so a stall was invisible until the fatal threshold.
The episode rule is a pure function so it can be tested without adding
a test-only mutator to LoadManager.
- sync_state{ledgers_behind}: how far our validated sequence trails the
best sequence any peer advertises, read from already-cached peer ranges
so no extra network traffic is added.
Also fixes the naming checker: it derived only the first label of a
multi-label instrument, so a dashboard querying the second label was
wrongly rejected.
Note: the clang-tidy hook cannot run in this worktree (no build
directory); the remaining pre-commit hooks, the naming check, dashboard
schema and harness syntax all pass.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- PerfLogImp::rpcEnd(): return after the requestId-not-found UNREACHABLE
so a stale (now - epoch) duration is no longer recorded to the counter
and histogram in release builds.
- MetricsRegistry peer-version gauge: compare versions numerically via
BuildInfo::encodeSoftwareVersion() instead of a lexicographic string
compare, stripping the non-digit prefix so peer 'rippled-X.Y.Z' lines
up with our bare 'X.Y.Z'. Fixes every peer counting as higher-version.
- MetricsRegistry::stop(): call Shutdown() before ForceFlush() before
reset() so the reader thread stops before teardown and no gauge
callback fires during shutdown.
- MetricsRegistry::start(): extract initExporterAndProvider() and
initSyncInstruments() helpers to keep each function under the line
limit; no behavior change.
- time_in_current_state_seconds: read NetworkOPs::getServerStateDurationUs()
(a lightweight accessor over StateAccounting) and convert microseconds
to seconds, replacing the hardcoded 0.0.