How to monitor Proxmox ve with vmgr.nsm in agent config

Started by kavirondo, January 21, 2026, 08:59:00 PM

Previous topic - Next topic

kavirondo

Hello,

Quoting from the manual:

"NetXMS has subagents that allow to monitor hypervisors. " But it doesnt say which hypervisors.

I see some configs for ESX, but what about Xen, HyperV, QEMU etc? Proxmox?

Can I / How Can I monitor Proxmox VE / QEMU with this subagent?

Thank you,

Alex


Alex Kirhenshtein


kavirondo

#2
Thank you,

I have now discovered that unfortunately proxmox does not use libvirt and installing it on the host is risky as it can clash with the underlying qemu lxc tech that proxmox uses. Proxmox strongly advises against doing this.

So at this point we can say that NetXMS does NOT support Proxmox monitoring using the documented Hypervisor monitoring methods.

It may be possible to do via the proxmox API which is the proxmox approved method.

The netxms agent does monitor the usual proxmox host details just fine, but I am looking to collect the metrics about the vms / containers etc.

The documentation should be updated to reflect this, and also note that there seems to be a separate subagent package for Xen.

kavirondo

#3
For completeness here is a config that I have tried, on the pve host:

apt install netxms-agent-vmgr
 apt install netxms-agent-vmgr
The following packages were automatically installed and are no longer required:
  libsnmp-base  libsnmp40t64  proxmox-kernel-6.17.2-2-pve-signed
Use 'apt autoremove' to remove them.

Installing:
  netxms-agent-vmgr

Installing dependencies:
  libvirt-common  libvirt-l10n  libvirt0

Summary:
  Upgrading: 0, Installing: 4, Removing: 0, Not Upgrading: 5
  Download size: 4,810 kB
  Space needed: 29.9 MB / 15.7 GB available

Continue? [Y/n] y
Get:2 http://deb.debian.org/debian trixie/main amd64 libvirt-common amd64 11.3.0-3+deb13u2 [215 kB]
Get:3 http://deb.debian.org/debian trixie/main amd64 libvirt0 amd64 11.3.0-3+deb13u2 [1,605 kB]
Get:4 http://deb.debian.org/debian trixie/main amd64 libvirt-l10n all 11.3.0-3+deb13u2 [2,932 kB]
Get:1 https://packages.netxms.org/debian trixie/main amd64 netxms-agent-vmgr amd64 5.2.8-1+trixie [56.8 kB]
Fetched 4,810 kB in 3s (1,517 kB/s)                                             
Selecting previously unselected package libvirt-common.
(Reading database ... 76467 files and directories currently installed.)
Preparing to unpack .../libvirt-common_11.3.0-3+deb13u2_amd64.deb ...
Unpacking libvirt-common (11.3.0-3+deb13u2) ...
Selecting previously unselected package libvirt0:amd64.
Preparing to unpack .../libvirt0_11.3.0-3+deb13u2_amd64.deb ...
Unpacking libvirt0:amd64 (11.3.0-3+deb13u2) ...
Selecting previously unselected package libvirt-l10n.
Preparing to unpack .../libvirt-l10n_11.3.0-3+deb13u2_all.deb ...
Unpacking libvirt-l10n (11.3.0-3+deb13u2) ...
Selecting previously unselected package netxms-agent-vmgr:amd64.
Preparing to unpack .../netxms-agent-vmgr_5.2.8-1+trixie_amd64.deb ...
Unpacking netxms-agent-vmgr:amd64 (5.2.8-1+trixie) ...
Setting up libvirt-common (11.3.0-3+deb13u2) ...
Setting up libvirt0:amd64 (11.3.0-3+deb13u2) ...
Setting up netxms-agent-vmgr:amd64 (5.2.8-1+trixie) ...
Setting up libvirt-l10n (11.3.0-3+deb13u2) ...
Processing triggers for libc-bin (2.41-12+deb13u1) ...
root@pve01:~#

#============================================================================
# NetXMS Agent Configuration File for Proxmox VE Hypervisor Monitoring
#============================================================================
[vmgr]
host = pve01

[vmgr:pve01]
Url = qemu:///system

Log file
2026.01.23 14:45:55.950 *E* [vmgr               ] Failed to connect socket to '/var/run/libvirt/libvirt-sock': No such file or directory
2026.01.23 14:45:55.950 *W* [vmgr               ] Unable to add host connection "pve01" with URL "qemu:///system"
2026.01.23 14:45:55.950 *W* [vmgr               ] No connections defined, VMGR subagent will not start

Yes I see that the libvirt process is not running but I am reluctant to run it due to the various comments out there about libvirt issues with proxmox

Alex Kirhenshtein

You are right, and the documentation is what failed you here. vmgr reaches hypervisors only through libvirt, so a Proxmox host is out of scope regardless of configuration — PVE does not use libvirt, and Proxmox advise against installing it on a node, so nothing ever answers on qemu:///system. Filed as https://github.com/netxms/netxms-doc/issues/59 so the hypervisor monitoring page says this instead of leaving it to be found in the agent log.

The PVE REST API is the route that works today, with no new code needed. Create a web service definition against

https://pve01:8006/api2/json/cluster/resources?type=vm
That returns every VM and LXC container in the cluster in one response, each with status, cpu, mem, maxmem, disk and maxdisk, so a single definition plus instance discovery over vmid covers all guests. For the host itself use /nodes/{node}/status, and /nodes/{node}/rrddata if you want the same series the GUI graphs draw from.

One non-obvious detail on authentication: do not use the Bearer authentication type. It sends Authorization: Bearer <token>, and Proxmox uses its own scheme. Set authentication to None and add the header explicitly instead:

Authorization: PVEAPIToken=monitoring@pve!netxms=<uuid>
Create the token under Datacenter - Permissions - API Tokens and give it a read-only role; PVEAuditor is enough.

There is a second route worth knowing about that does not work yet. PVE 9 can push metrics on its own — Datacenter - Metric Server - OpenTelemetry, sent by pvestatd every 10 seconds — and NetXMS has had OTLP metric ingestion since 6.1. The two do not meet at the moment: PVE sends OTLP encoded as JSON, our receiver accepts protobuf only. Filed as https://github.com/netxms/netxms/issues/3482. An OpenTelemetry Collector in between will transcode it if you want that shape now, but for the same data the REST API above is far less machinery.

On the Xen subagent you spotted: it exists, but it is built on Xen's own libxl, so it is no help for Proxmox either.


gmonk63

Just curious would installing the netxms agent cause any issues if we want to run api commands localty via pvesh from the agent and create DCI's from that. Not sure if the agent has any advantage over just using the rest api.


Thanks

Alex Kirhenshtein

Hi,

No problems, and running pvesh from the agent works fine. On the second question the choice isn't quite what it looks like though, because with NetXMS the REST API route is itself an agent feature.

pvesh works from the agent for a reason worth knowing about: it invokes API functions directly without going through the REST/HTTPS server, and it requires root. The packaged agent runs as root - the systemd unit does not drop privileges, and the agent changes uid only if you pass -u/-g or set UserId/GroupId in nxagentd.conf. So it works with no extra setup, which also means anyone who can add a DCI can make the agent fork a root command on the hypervisor. Worth deciding that deliberately rather than finding it out later.

What will actually bite you is process spawning. ExternalParameter (ExternalMetric in current naming) forks a process per metric per poll, and pvesh is a Perl program that loads the PVE API modules on every invocation. One metric per guest on a 60 second interval turns into a continuous stream of interpreter startups on the host. The default execution timeout is 5 seconds (ExecTimeout, or ExternalMetricTimeout for these specifically), and a slow pvesh call will hit it and get killed.

Use ExternalDataProvider instead - added in 5.2.0. It runs the command once per polling interval, caches the output, and serves any number of metrics out of the cached document with jq queries, evaluated inside the agent so there is no jq binary to install:

[ExternalDataProvider/PVE]
Command = ["/usr/bin/pvesh", "get", "/cluster/resources", "--type", "vm", "--output-format", "json"]
PollingInterval = 60
Timeout = 30000

[ExternalDataProvider/PVE/Metrics]
PVE.Guest.Status(*) = .[] | select(.vmid == $1) | .status
PVE.Guest.CPU(*) = .[] | select(.vmid == $1) | .cpu
PVE.Guest.CPU(*).dataType = float
PVE.Guest.Memory(*) = .[] | select(.vmid == $1) | .mem
PVE.Guest.Memory(*).dataType = uint64

[ExternalDataProvider/PVE/Lists]
PVE.Guests = .[] | .vmid

That is one pvesh call a minute for the whole cluster no matter how many DCIs you build on top, and PVE.Guests gives you instance discovery over vmid. Two details: Timeout here is in milliseconds, and metrics with parameters ($1) need agent 6.0 or newer - on 5.2 define each metric with a fixed query instead.

On agent versus REST: there is no version of the REST route that doesn't involve an agent. Web service DCIs are executed by an agent acting as web service proxy - the server never makes the HTTP request itself. If the node has no web service proxy configured it falls back to the zone proxy, and finally to the management server node, so "just using the REST API" in practice means "the server's own agent makes the call". The choice is which agent and where it sits, not whether there is one.

Consequences:

  • Responses are cached per URL for the retention time set on the web service definition, so every DCI reading out of the same document costs one HTTP request. Against /cluster/resources that is a single call per interval covering every guest in the cluster.
  • The extraction is identical either way - web service DCIs and ExternalDataProvider share the same jq-based extractor, so the queries you write don't change with the route.
  • Only an agent on the PVE host can reach 8006 on localhost, which matters if that port isn't open to the server. Poll from an agent elsewhere and you install nothing on the hypervisor at all.

So the real trade is narrow. pvesh saves you managing an API token, at the price of forking a root-privileged Perl process on the hypervisor. The web service route costs you a token and gives you a read-only credential in exchange (PVEAuditor is enough), one HTTP call per interval, and the freedom to poll from an agent that isn't on the PVE host. I'd take the REST API as the default and keep pvesh for anything the HTTP API doesn't expose.

One thing has changed since my post above. The OTLP route I said didn't work now does - the receiver accepted protobuf only, which is why PVE 9's OpenTelemetry metric server couldn't reach it, and that is fixed in 6.2.3 (https://github.com/netxms/netxms/issues/3482), released on 9 August. On 6.2.3 or later you can point Datacenter - Metric Server - OpenTelemetry straight at the NetXMS web API and have PVE push guest metrics on its own: no collector in between, no polling, and no agent on the host. It needs an auth token passed through the otel-headers option, and the receiver is loaded as a server module (Module = otlp in netxmsd.conf). None of the ingestion side is documented yet - https://github.com/netxms/netxms-doc/issues/67 covers that.