Monitoring KVM and libvirt
A KVM host running libvirt is recognised by the installed daemon package, and every guest
it defines is reported within a minute: state, vCPUs, memory, CPU time, and the storage
pools they live on. The agent reads through virsh in read-only mode and never changes a
domain.
How libvirt is recognised
The signed libvirt definition matches a host with the libvirt-daemon package installed.
Once matched, the compiled probe runs every minute with a 15-second budget and executes
three read-only commands, each with the -r flag that forbids any modification:
virsh -r list --allfor every defined domain and its state,virsh -r domstatsfor per-domain counters,virsh -r pool-list --detailsfor storage pools.
Matching on the package rather than the process means the definition keeps matching while
libvirtd is stopped, so a probe failure at that point is reported as exactly that.
What is collected
Guests. Every domain becomes a guest in the host inventory with its state. Per domain the probe reports whether it is running, its current vCPU count, the memory currently assigned through the balloon, and the cumulative CPU time consumed. Two totals give the number of defined and running domains.
Storage pools. For every running pool with a known capacity: capacity, allocation and the percentage used. Pools that are inactive are skipped.
The host inventory lists each guest with kvm as its hypervisor.
| Signal | Metric |
|---|---|
| Domains defined / running | svc.libvirt.domains, svc.libvirt.running |
| Per-domain state | svc.libvirt.guest.running tagged by domain |
| Per-domain vCPUs, memory, CPU time | svc.libvirt.guest.vcpus, svc.libvirt.guest.mem_bytes, svc.libvirt.guest.cpu_time_ns |
| Storage pool capacity, used bytes, used share | svc.libvirt.storage.capacity_bytes, svc.libvirt.storage.used_bytes, svc.libvirt.storage.used_pct tagged by storage |
Names, tags and units are in the metrics reference.
Logs. The logs-libvirt definition matches the libvirtd process and ships the
daemon's journal entries at notice level and above by default. See
Logs.
Alerts out of the box
| Rule | Fires when | Severity | Ships |
|---|---|---|---|
| libvirt storage pool is filling up | a pool is 90% or more used for 15 minutes | warning | on |
| libvirt guest is not running | a defined domain is not running for 5 minutes | warning | off |
A full storage pool stops every guest whose disk lives on it from writing, which is why the pool rule ships on, one incident per pool, and closes only once usage falls back under 85%. The fifteen-minute hold rides out a snapshot or an image copy that is about to be deleted. The guest rule ships off because a stopped guest is normal on most hosts: templates, cold standbys and machines someone shut down on purpose all read as "not running". Enable it per workspace where every defined domain is supposed to be up; it then opens one incident per domain. Thresholds and hysteresis are in the rules catalog.
Limitations
- CPU time per guest is a cumulative counter in nanoseconds, not a percentage; read the chart for the rate.
- Per-guest disk and network IO are not collected, nor is the memory the guest actually uses inside the VM; the memory figure is what the balloon assigns.
- Only running pools with a capacity are reported. An inactive pool, or one whose backend reports no capacity, has no metrics.
- The probe needs the
virshbinary on the host. Some distributions ship it in a separate client package; when it is missing the check reports that plainly and nothing else is collected. - Only the connection
virshuses by default is read. Guests defined under another connection URI, such as a user's session-mode machines, are not seen.
Related
- Monitoring Proxmox VE and Monitoring Hyper-V for the other hypervisors
- Monitoring DRBD and LINSTOR when guest disks are replicated
- Proxmox monitoring on the main site