Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Status observability

Rings Node exposes operator observations through its existing authenticated status route:

TOKEN="$(tr -d '\r\n' < ~/.rings/api-token)"
curl --fail --header "Authorization: Bearer ${TOKEN}" \
  'http://127.0.0.1:50000/status?view=observability'

The compact projection is available on both the internal and external listeners because both already serve /status. It inherits their existing Bearer-token requirement. This change adds no new HTTP route and no unauthenticated surface.

Why the projection is separate from the default body

GET /status keeps its existing response shape for compatibility. That legacy response is a full inspection: besides peers and DHT topology, it serializes every persistent and cache storage value. Its size is therefore data-dependent and may approach the configured storage capacity; the default native data-storage capacity is 200,000,000 bytes before JSON overhead. Do not poll the full view as a lightweight health check.

GET /status?view=observability avoids the full storage inspection. It returns only the node version plus a bounded observability object. The largest collections are capped at 32 recent message records and 32 peer-rating records. A conservative maximum-width production fixture is about 18 KiB and is kept below 32 KiB by a regression test. This makes the projection suitable for periodic polling without adding the storage payload or performing the legacy full status serialization.

Polling interval and request cost

Poll GET /status?view=observability at most once every 60 seconds per node. Do not use it for high-frequency polling, do not start a new request while the previous request is still running, and avoid having multiple independent collectors poll the same node. Configure a client timeout so a slow request cannot accumulate overlapping work.

The response size is bounded, but the work needed to assemble a current snapshot is not constant. Each request walks the live persistent DHT storage view to count mailbox carriers and held messages; the walk reads and decodes stored entries and retires expired entries. Snapshot assembly also projects the current retained peer measurements. Its CPU, storage I/O, allocation, and lock-hold costs therefore grow with the node’s stored data and retained peer state. The 60-second interval is an operational recommendation intended to limit this work; it is not a claim that the endpoint has constant-time cost.

Do not periodically poll the default GET /status response. It additionally serializes every persistent and cache storage value and is intended for explicit inspection rather than monitoring.

The JSON object’s schema_version is the compatibility boundary. Fields may be added within the current version; incompatible meaning or removal requires a schema-version increment.

Scope and privacy

Message and lookup counters are node-local and begin when the current process starts. They are not topic totals, network totals, or durable accounting. Recent message activity retains the last 32 completed operations in memory. Each record contains only sequence, time, action, finite traffic category, compile-time message class, and outcome. Payloads, application topic strings, DIDs, transaction IDs, transport addresses, delegation identifiers, and key material are excluded.

Peer DIDs appear only in the authenticated peer_ratings array, which is sorted and capped at 32 records. Use the existing paginated listPeerMeasurements RPC when every retained peer is needed. Lookup correlation identifiers and mailbox identifiers are never exported.

Values and alert semantics

FieldKindMeaning
messagescountersSuccessful sent, received, forwarded, and stored operations plus aggregate failures during this process. A send or forward succeeds when its next hop accepts the logical transfer.
recent_messagesbounded recordsOldest-first completion records for the last 32 message operations. message_class is a protocol variant, not an application-controlled topic.
session_keygauges and countersActive delegation validity, creation, expiry, and remaining time. Runtime rotation is currently unsupported and its counters remain zero; a replacement delegation is loaded on restart. A native daemon exits 25 s before expires_at_ms, when no frame can leave any more (see Delegations and keys).
mailboxesgauges and counterLive relay-inbox carriers and held messages retained by this node, plus successful offline-message holds during this process.
dht_lookupscounters, gauge, histogramSuccessor and storage lookup rounds observed locally, split into success, explicit failure, and 30-second timeout, with bounded in-flight state and cumulative latency buckets.
peer_ratingsbounded recordsUp to 32 DID-sorted local assessments with recent send/receive evidence and local byte-credit score inputs. Use listPeerMeasurements for the paginated complete set. These are advisory local assessments, not network-wide reputation.
health.process_api_healthygaugeThe authenticated handler answered and assembled its dependencies.
health.overlay_readygaugeConservative overlay readiness: at least one admitted peer and one DHT successor are present, and the node’s own delegation is more than 25 s from its expiry, so its frames still leave. It is deliberately distinct from process/API health.

counter_scope is node_local_process_lifetime, and process_started_at_ms makes resets explicit. Use deltas or rates over cumulative counters because every process restart resets them. Mailbox counts come from the live DHT storage view, which retires expired entries before counting them.