Prometheus exporter
The vastnfs-exporter is an optional HTTP server that exposes VastNFS RPC
transport statistics for Prometheus. It runs on NFS client hosts (the host
that mounts VastNFS exports) and reads kernel debugfs/sysfs — the NFS server is
out of scope.
The exporter mirrors the discovery logic of vastnfs-ctl: it walks VastNFS mount
RPC transports and publishes per-operation counters (same source as
rpc-transports-stats),
live per-transport queue depths (same sysfs fields as
rpc-transports), transport
state flags, and per-mount config (vastnfs_mount_info).
Default listen address: 0.0.0.0:9001. Endpoints:
| Path | Description |
|---|---|
/metrics | Prometheus text exposition |
/ | Minimal health/index body |
Build (optional)
Default package builds omit the exporter. Include it when building packages:
./build.sh bin --with-exporter
With --with-exporter, packages add python3 and python3-prometheus-client
(>= 0.16) as runtime dependencies and install the exporter files listed below.
See Building packages for other build.sh bin flags.
The exporter source must be committed before ./build.sh src — the packaging
scripts use git archive HEAD, which ships only committed files.
Install paths
After installing a package built with --with-exporter:
| File | RPM path | DEB path |
|---|---|---|
Python modules (exporter.py, metrics.py, discovery.py, version) | /usr/share/vastnfs-exporter/ | /usr/share/vastnfs-exporter/ |
| Wrapper script | /usr/bin/vastnfs-exporter | /usr/bin/vastnfs-exporter |
| systemd unit | /usr/lib/systemd/system/vastnfs-exporter.service | /lib/systemd/system/vastnfs-exporter.service |
The wrapper executes python3 /usr/share/vastnfs-exporter/exporter.py "$@".
The service unit is installed but not auto-enabled. After package install:
sudo systemctl enable --now vastnfs-exporter
Verify:
curl -s localhost:9001/metrics | head
Prerequisites
The exporter reads kernel debugfs and sysfs, not /proc mountstats.
debugfs must be mounted at /sys/kernel/debug. Most distributions mount it at
boot; verify with:
mount | grep debugfs
ls /sys/kernel/debug/vastnfs
If debugfs is not mounted, RPC metrics stay empty and
vastnfs_exporter_vastnfs_present is 0. Mount manually if needed:
sudo mount -t debugfs none /sys/kernel/debug
Paths the exporter uses:
| Path | Filesystem | Role |
|---|---|---|
/sys/kernel/debug/vastnfs/nfs_sb/* | debugfs | Identify VastNFS mounts (not present in upstream Linux NFS) |
/sys/kernel/debug/vastnfs/nfs_clnt/* | debugfs | Map NFS clients to rpc_clnt IDs |
/sys/kernel/debug/sunrpc/rpc_xprt/*/extra | debugfs | Per-operation RPC counters (per-op stats) |
/sys/kernel/debug/sunrpc/rpc_xprt/*/info | debugfs | Transport id, netid, addr, port labels |
/sys/kernel/sunrpc/rpc-clients/, xprt-switches/ | sysfs | Traverse RPC client → xprt-switch → transport IDs |
/sys/kernel/sunrpc/xprt-switches/*/xprt*/xprt_state | sysfs | Transport state flags (CONNECTED, BOUND, etc.) |
/sys/kernel/sunrpc/xprt-switches/*/xprt*/xprt_info | sysfs | Live queue depths (binding_q_len, sending_q_len, etc.) |
Discovery walks VastNFS NFS clients, resolves each to an RPC client and its transports via sysfs, then reads per-op counters from debugfs and queue depths and state flags from sysfs for those transports only.
Debugfs files are root-owned and often mode 0400; /sys/kernel/debug itself
is often mode 700. The packaged service runs as unprivileged vastnfs-exporter
with the capabilities needed to traverse and read these paths (same requirement
as sudo vastnfs-ctl).
systemd
The vastnfs-exporter service runs as a dedicated unprivileged user
(vastnfs-exporter) with systemd hardening enabled. The unit declares
RequiresMountsFor=/sys/kernel/debug so the service does not start until
debugfs is mounted.
Manual run
Packaged binary
sudo systemctl stop vastnfs-exporter # if running as a service
sudo vastnfs-exporter # listens on 0.0.0.0:9001
curl -s localhost:9001/metrics
Flags
| Flag | Default | Description |
|---|---|---|
--host | 0.0.0.0 | Listen address |
--port | 9001 | Listen port |
--shutdown-timeout | 5 | Grace period after SIGTERM/SIGINT before exit (seconds) |
Manual runs need root (or CAP_SYS_ADMIN + CAP_DAC_READ_SEARCH) to read
debugfs, same as vastnfs-ctl.
Metrics
The exporter uses a private Prometheus registry (no default python_* or
process_* series).
Labels
Per-transport labels used across RPC metrics:
| Label | Description | Example |
|---|---|---|
xprt_id | Kernel RPC transport ID | 2 |
netid | RPC network ID | tcp, rdma |
addr | Remote endpoint | 192.168.23.11:2049 |
RPC counter metrics add op (RPC operation name, e.g. READ, WRITE,
GETATTR). Queue length gauges and vastnfs_rpc_xprt_state use only
xprt_id, netid, and addr (state gauges also add state; see below).
Exporter-level state and self-observability metrics have no transport labels.
RPC counters (per transport, per operation)
Each counter is a cumulative total with labels xprt_id, netid, addr, and
op. All-zero per-op rows are omitted (same filter as
vastnfs-ctl rpc-transports-stats).
| Metric | Description |
|---|---|
vastnfs_rpc_xprt_ops_total | Total RPC operations |
vastnfs_rpc_xprt_trans_total | Total RPC transmissions |
vastnfs_rpc_xprt_timeouts_total | Total RPC timeouts |
vastnfs_rpc_xprt_bytes_sent_total | Total bytes sent |
vastnfs_rpc_xprt_bytes_received_total | Total bytes received |
vastnfs_rpc_xprt_queue_milliseconds_total | Cumulative queue wait time (ms); per-op q_ms column in rpc-transports-stats — not an instantaneous queue depth |
vastnfs_rpc_xprt_rtt_milliseconds_total | Total round-trip time (ms) |
vastnfs_rpc_xprt_execute_milliseconds_total | Total execute time (ms) |
vastnfs_rpc_xprt_errors_total | Total RPC errors |
Queue length gauges (per transport)
Instantaneous queue depths for each VastNFS mount transport. These are
Prometheus gauges (current depth), not cumulative counters. Source: sysfs
xprt_info (key=value lines), matching the binding_q_len, sending_q_len,
and related fields printed by vastnfs-ctl rpc-transports.
Do not confuse these with vastnfs_rpc_xprt_queue_milliseconds_total above —
that counter is cumulative wait time from debugfs per-op stats (q_ms).
| Metric | Sysfs field | Description |
|---|---|---|
vastnfs_rpc_xprt_binding_queue_length | binding_q_len | Tasks waiting for bind/rpcbind |
vastnfs_rpc_xprt_sending_queue_length | sending_q_len | Tasks waiting to send |
vastnfs_rpc_xprt_pending_queue_length | pending_q_len | Tasks in flight (awaiting reply) |
vastnfs_rpc_xprt_backlog_queue_length | backlog_q_len | Tasks waiting for a free request slot |
vastnfs_rpc_xprt_tasks_queue_length | tasks_queuelen | Total tasks associated with this transport |
Labels: xprt_id, netid, addr.
One series set per mount transport each scrape. Queue gauges are omitted when
xprt_info is unreadable or the kernel reports <closed> (disconnected
transports). Switch-level queue_len from rpc-switches is not exported.
During reconnection a transport may show state flags (e.g. CONNECTING) in
vastnfs_rpc_xprt_state while queue gauges are absent — the kernel does not
expose xprt_info queue fields until the transport is connected.
Transport state
vastnfs_rpc_xprt_state is a gauge set to 1 for each active state flag on a
transport. A transport in CONNECTED BOUND emits two series (one per flag).
Common state values: CONNECTED, BOUND, CONNECTING, CLOSE, DISCONN.
Labels: xprt_id, netid, addr, state.
Mount configuration
vastnfs_mount_info — gauge 1 per mount. Labels: nfs_id, mountpoint,
proto (effective transport), options (NFS mount options from
/proc/self/mountinfo, joined to nfs_sb via sb_id). Independent of xprt metrics.
State gauges (always emitted)
| Metric | Values | Description |
|---|---|---|
vastnfs_exporter_vastnfs_present | 0 or 1 | 1 when /sys/kernel/debug/vastnfs exists |
vastnfs_exporter_mount_count | non-negative integer | Number of VastNFS mounts exported this scrape |
vastnfs_exporter_xprt_count | non-negative integer | Number of VastNFS mount transports exported this scrape |
These gauges are emitted on every scrape, including when RPC collection fails
(xprt_count → 0; mount_count follows mount discovery).
Self-observability
| Metric | Type | Description |
|---|---|---|
vastnfs_exporter_build_info | info | Build version (version label) |
vastnfs_exporter_scrape_duration_seconds | gauge | Wall-clock time of the last collection |
vastnfs_exporter_collection_errors_total | counter | Failed collection attempts |
Behavior when VastNFS or debugfs is absent
The exporter process stays up. /metrics always returns HTTP 200 — never
5xx for collection failures.
When VastNFS is not loaded, debugfs is not mounted, or VastNFS is loaded but
there are no mounts yet, the scrape contains no vastnfs_rpc_xprt_* series.
State gauges are still emitted so operators can tell why the scrape is empty:
| Condition | vastnfs_exporter_vastnfs_present | vastnfs_exporter_xprt_count | RPC metrics |
|---|---|---|---|
| debugfs not mounted / vastnfs not loaded | 0 | 0 | absent |
| vastnfs loaded, no mounts | 1 | 0 | absent |
| vastnfs loaded, mounts active | 1 | > 0 | present |
See also
vastnfs-ctl rpc-transports-stats— per-op counter sourcevastnfs-ctl rpc-transports— queue depth fields on the CLI- Mount and transport state — debugfs background
- Building packages —
--with-exporterflag
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5