Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.novacula.io/llms.txt

Use this file to discover all available pages before exploring further.

The node detail page renders a snapshot of every metric the executor reports on its reporter loop. This page maps each visible panel to its underlying source so you know what’s authoritative, what’s derived, and how often it refreshes.

How metrics flow

Every executor runs a reporter loop (default 10s):
  1. For each node it owns, scrape the per-process metrics endpoint declared by the chain adapter (metricsMapping).
  2. Build an ObservedNodeState carrying per-process status + the metrics block.
  3. Push it to the control plane via syncExecutor.
The control plane stores the most recent observation on the Node row’s observed JSON column, with observedAt as the freshness timestamp. The UI reads from there — it never talks to the executor directly.

Status badge

The colored badge at the top of the detail page is a derived phase computed from desired state, observed status across all processes, and revision drift. See Node lifecycle for the phase set.

Sync progress

Each chain adapter declares a syncProgress metric (when the underlying client exposes one):
ChainSource
Bitcoinbitcoind JSON-RPC getblockchaininfo.verificationprogress
BSC / Ethereum ELclient eth_syncing + metrics endpoint
Ethereum CLbeacon /eth/v1/node/syncing
IgrapostScrape against the public Igra explorer’s eth_blockNumber (the L2 has no native p2p tip)
Inkop-node + op-geth metrics
Monadmonad-execution + monad-rpc exporters via the local OTEL collector
Suisui-node Prometheus exporter
Tronjava-tron Prometheus exporter
Rendered as a percentage with the height of the latest imported block.

Peers

Per-process peer counts. Useful for diagnosing network isolation: a process at zero peers is the most common cause of a stalled sync.

Disk usage

The executor’s resource snapshot includes total + available bytes for the disk(s) backing this node. The UI shows used percentage and total size, plus a warning band when usage exceeds the disk_usage alert threshold (default 85% — see Alert rules).

CPU and memory

Per-process CPU (millicores) and memory (bytes). Source:
  • OperatorcAdvisor / metrics-server numbers from the pod.
  • Agent/proc/<pid> for the systemd unit’s main PID.
These are point-in-time samples taken on each reporter tick; not historical time series.

Last block / chain head

Where the underlying client publishes one, the reporter records the height of the most recently imported block. Compared against the executor’s last-known network head (where available) to compute lag.

Liveness

Two layers:
  • Per-processObservedNodeStatus (starting / running / syncing / stopped / error) reported per process.
  • Per-node freshnessobservedAt timestamp on the Node row. If the observation is stale (executor offline), the UI grays the metrics out and surfaces a warning that figures may not reflect reality.

Per-chain extras

Chains expose chain-specific metrics through the adapter’s metricsMapping.extras map. The set differs per chain and per client choice within a chain:
ChainExtras (sample)
Bitcoindifficulty, hash_rate, mempool_bytes, mempool_usage_bytes, uptime_seconds
BSCGo-ethereum process / chain / txpool counters
EthereumCL client extras (beacon-chain / fork-choice / engine-API gauges) + EL client extras (p2p + chain counters)
SuiNone today — the adapter passes only height / peers / syncProgress*
Tronjava-tron JVM + chain counters
IgraEL extras + kaspad sidecar metrics (kaspad_is_synced, kaspad_virtual_daa_score, kaspad_block_count, kaspad_header_count, kaspad_server_version)
Inkop-node rollup metrics + op-geth metrics
Monad18 extras — consensus_committed_blocks, consensus_local_timeouts, raptorcast_messages_received, raptorcast_recv_errors, blocksync_request_timeout, wireauth_transport_sessions, execution_ledger_*, statesync_*, rpcActiveRequests, …
Extras are stored on Node.observed.details but not rendered by any built-in UI tile today — they are available via the GraphQL API for ad-hoc inspection and for future per-chain dashboards. The same Prometheus metric can be a common per-node field on one chain and an extra on another; what matters is whether the adapter wired it to the typed metricsMapping or to the extras bag.

What’s not here

  • Historical metrics. The control plane stores only the latest observation per node; there is no time-series history. For a Grafana-style dashboard over time, scrape the underlying client metrics endpoints directly with your own Prometheus and feed your own dashboards.
  • Log-based metrics. Anything you’d extract from log lines is in the Logs tab, not here.