Two-level Enable
The module has a master Enabled switch, and the Prometheus tab has its own Enabled switch. When either one is off, scrapes get a 503 response.
Exposes Proxmox VE metrics over a Prometheus-compatible HTTP endpoint, ready to be scraped and shown in Grafana or any compatible monitoring stack. Each enabled cluster has its own scrape endpoint. Each collector is a switch with its own cache, and collectors run in parallel.
The module has a master Enabled switch, and the Prometheus tab has its own Enabled switch. When either one is off, scrapes get a 503 response.
Each cluster has its own token. It is stored encrypted at rest and validated with CryptographicOperations.FixedTimeEquals at every scrape. You can change it at any time from the settings page.
Three presets, one click each: Fast (essentials only, low API impact), Standard (sensible default), Full (everything on). After a preset is loaded, each collector can still be changed.
Max parallel requests (default 5) sets how many per-node and per-guest fetches run at the same time. Lower it on small or slow clusters. Raise it on big clusters with fast APIs.
Every collector has its own Cache seconds TTL. Slow collectors such as S.M.A.R.T. or Subscription can be cached for minutes, while fast ones (Node Status) stay fresh.
Optional. Exports counters and histograms about the calls from cv4pve-admin to the PVE API (latency, errors). Useful to spot a cluster that misbehaves.
Hot reload: Saving the settings clears the cached engines of all clusters and resets the request counters of the Status page. The next scrape rebuilds the engine with the new configuration, so no service restart is needed. The counters are kept in memory: they also restart from zero when the application restarts.
Why this exporter when PVE already has metrics?
One endpoint covers the cluster, every node and every guest. Prometheus does not need to query each PVE node.
Disk SMART, replication, HA, balloon memory: each is a switch with its own cache TTL. You pay for what you actually scrape.
Each cluster has its own token, validated in constant time. Your Prometheus configuration holds no PVE API token, and there are no certificates to rotate.
Standard Prometheus text format with # HELP and # TYPE lines on every metric: your existing dashboards keep working.
GET /module/*/metrics-exporter/prometheus/<clusterName>?token=<TOKEN><clusterName>: name of the configured Proxmox VE cluster<TOKEN>: per-cluster token defined in the module settingsThe token can also travel in the Authorization: Bearer <TOKEN> header instead of the query string, so it does not end up in the logs of a proxy. In Prometheus:
scrape_configs: - job_name: cv4pve metrics_path: "/module/*/metrics-exporter/prometheus/<clusterName>" authorization: credentials: <TOKEN> static_configs: - targets: ['cv4pve-admin:8080']| Response | Meaning |
|---|---|
401 |
The token is wrong or missing, no token is configured, or the cluster name is unknown or disabled |
503 |
Only with the right token: the module or the Prometheus exporter is disabled, or the collection from the cluster failed (the body holds the error) |
Grab the URL from the UI: The Open metrics link in the Status page points to the scrape URL of the current cluster, token included. Copy the link address from there instead of building it by hand.
Collectors are grouped by scope. Each collector has its own switch and its own cache TTL.
Some metrics are always exported, whatever the collectors:
cv4pve_cluster_*)cv4pve_up, with the labels id and type)cv4pve_guest_*, cv4pve_storage_*)cv4pve_scrape_duration_seconds, cv4pve_scrape_errors_total)| Collector | What it exposes |
|---|---|
| High Availability | HA state of cluster manager, groups and resources |
| Backup info | Guests not covered by any backup job |
| Collector | What it exposes |
|---|---|
| Status | Memory, swap, load average, uptime, root file system, CPU cores and memory assigned to running guests, node version |
| Subscription | License status and tier per node (Community / Basic / Standard / Premium / None) |
| Replication | Per-VM replication jobs, sync status and lag |
| Disk S.M.A.R.T. | S.M.A.R.T. attributes per physical disk (one more API call per node: keep cached) |
| Collector | What it exposes |
|---|---|
| QEMU balloon memory | Current balloon size: memory actually assigned to the guest |
The balloon size is read from the QEMU monitor info balloon, only on QEMU VMs with the balloon driver enabled.
Minimal prometheus.yml scrape job:
scrape_configs: - job_name: cv4pve-admin metrics_path: "/module/*/metrics-exporter/prometheus/my-cluster" params: token: ['REPLACE_WITH_YOUR_TOKEN'] static_configs: - targets: ['cv4pve-admin.example.com']Quote the metrics_path: The literal * in the URL is a wildcard for the “all clusters” routing context and must be kept as it is. Quote metrics_path: without quotes some YAML parsers treat * as a special character.
If you have multiple clusters, add one scrape job per cluster (or a single job with __metrics_path__ relabeling from a static list).
All metrics are prefixed with cv4pve_ and grouped by scope. Examples:
cv4pve_cluster_quorate, cv4pve_cluster_nodescv4pve_node_cpu_assigned_cores, cv4pve_node_memory_total_bytes, cv4pve_node_disk_health, cv4pve_node_disk_wearoutcv4pve_guest_cpu_usage_ratio, cv4pve_guest_memory_usage_bytes, cv4pve_guest_disk_size_bytes, cv4pve_guest_uptime_seconds, cv4pve_guest_network_receive_bytes_totalcv4pve_ha_state, cv4pve_ha_node_state, cv4pve_ha_quoratecv4pve_guests_not_backed_upcv4pve_api_request_duration_seconds, cv4pve_api_request_errors_total (when API instrumentation is on)For the full and current catalogue, scrape the endpoint above: every metric carries its own # HELP and # TYPE line in the response.
The default preset on a new module is Fast. Each collector has its own switch and Cache seconds TTL (0 = no cache, collect at every scrape).
The Fast, Standard and Full buttons in the Prometheus tab replace every Prometheus setting with the values of the preset, including Enabled (on) and Max parallel requests (5). The settings can only be saved with a Token.
Module
| Setting | Default | Purpose |
|---|---|---|
| Enabled | off | Master on/off switch for the module on the cluster |
| Token | empty (required) | Per-cluster token (stored encrypted, validated with constant-time compare) |
Prometheus (Fast preset)
| Setting | Default | Purpose |
|---|---|---|
| Enabled | on | Enable the Prometheus scrape endpoint |
| Max parallel requests | 5 | Max concurrent per-node / per-guest fetches (1 = sequential) |
| API instrumentation | off in Fast (on in Standard / Full) | Export counters and histograms about the underlying PVE API calls (latency, errors) |
Cluster collectors
| Collector | Default in Fast | Default in Standard | Default in Full |
|---|---|---|---|
High Availability (Ha) |
on, cache 0s | on, cache 0s | on, cache 30s |
| Backup info | on, cache 0s | on, cache 600s | on, cache 600s |
Node collectors
| Collector | Default in Fast | Default in Standard | Default in Full |
|---|---|---|---|
| Status (memory, swap, load, uptime) | off | on, cache 0s | on, cache 0s |
| Subscription | off | on, cache 3600s | on, cache 3600s |
| Replication | off | on, cache 0s | on, cache 60s |
| Disk S.M.A.R.T. | off | off | on, cache 600s |
Guest collectors
| Collector | Default in Fast | Default in Standard | Default in Full |
|---|---|---|---|
| QEMU balloon memory | off | off | on, cache 0s |
| Permission | Key | Grants |
|---|---|---|
| Metrics Exporter | MetricsExporter.Link |
Access to the module and to its Overview page |
| Status | MetricsExporter.Link.status |
Status page |
| Edit Settings | MetricsExporter.EditOptions |
The settings button of the module |
The built-in role Admin for module Metrics Exporter includes all of them. Roles and permissions are assigned in Admin Area → Security EE.
The scrape endpoint does not use these permissions: it is protected by the per-cluster token only.
Proxmox VE privileges: the base (PVEAuditor) is enough.
The base and the rules common to all modules are in Proxmox VE Permissions.