Proxmox Monitor Agent - Coletando Metricas do Host com Bash
Proxmox Monitor Agent - Coletando Metricas do Host com Bash
Este post e o segundo de uma serie de quatro partes sobre o Proxmox Monitor Agent e a integracao com o Home Assistant.
- Parte 1 - Quando o Host Esquenta e o Home Assistant Nao Ve
- Parte 2 - Coletando Metricas do Host com Bash (voce esta aqui)
- Parte 3 - Integrando com o Home Assistant
- Parte 4 - Alertas no Home Assistant e Proximos Passos
Por que Bash
Quando comecei a pensar no agent, a primeira decisao foi onde ele deveria rodar. Para enxergar temperatura, discos, storage, VMs, LXCs e rede fisica, ele precisava estar no host Proxmox. Rodar de fora, via VM, me colocaria de novo no mesmo ponto cego que motivou o projeto.
Mas eu tambem nao queria instalar uma aplicacao pesada no host. Proxmox e infraestrutura. Quanto menos coisa rodando ali, melhor. O agent precisava ser simples, facil de auditar e dependente do minimo possivel.
Por isso ele nasceu em Bash.
Bash nao e glamouroso, mas nesse caso faz sentido. O host Proxmox ja tem Linux, systemd e varias ferramentas que sabem consultar o que eu preciso. O agent so organiza essas chamadas, normaliza o resultado e emite um JSON previsivel.
Quando disponiveis, ele aproveita ferramentas como:
pvesh, para dados do Proxmox.lsblk, para discos e dispositivos de bloco.findmnt, para filesystems.ip, para interfaces de rede.sensors, para temperaturas, fans, voltagens e energia.smartctlenvme, para informacoes de discos quando instaladas.zpoolezfs, para ambientes com ZFS.qmepct, para VMs e containers LXC.
Nem todo host tem tudo isso instalado ou disponivel. O agent nao deve quebrar inteiro so porque uma ferramenta opcional nao existe. Quando algo esta faltando, isso aparece em capabilities.missing_tools ou em collection.errors. O snapshot pode ficar parcial, mas continua util.
Instalacao
O repositorio do agent esta publico em:
https://github.com/mauricioj/proxmox-monitor-agent
A instalacao principal e via script direto do GitHub:
curl -fsSL https://raw.githubusercontent.com/mauricioj/proxmox-monitor-agent/main/install.sh | sudo bash
Se preferir revisar o codigo antes de instalar, clone o repositorio e rode o instalador localmente:
git clone https://github.com/mauricioj/proxmox-monitor-agent.git
cd proxmox-monitor-agent
bash install.sh
O instalador e interativo porque eu nao queria assumir tudo pelo usuario. Em um host Proxmox, cada pessoa tem um nivel diferente de tolerancia para instalar dependencias, criar timers e abrir portas.
Por padrao, ele copia o agent para:
/opt/proxmox-monitor-agent
E cria o comando:
/usr/local/bin/pma-metrics
Durante a instalacao, ele pergunta coisas como:
- Diretorio de instalacao.
- Se deve verificar dependencias ausentes.
- Se pode instalar dependencias via
apt. - Se deve criar o symlink
pma-metrics. - Se deve instalar o timer systemd.
- Qual intervalo de coleta usar, com padrao de 60 segundos.
- Se deve instalar o HTTP snapshot server.
- Qual endereco e porta usar para o HTTP server, com porta padrao
9782. - Se deve rodar uma coleta de teste ao final.

Essa abordagem deixa a instalacao flexivel. Da para usar o agent so como comando local, sem HTTP. Da para instalar o timer sem expor endpoint. Ou da para habilitar o caminho completo para consumidores na rede local.
O primeiro snapshot
Depois de instalado, o teste mais direto e rodar:
pma-metrics | jq .
Esse comando imprime um snapshot JSON no stdout.

O detalhe importante e a palavra snapshot. O agent nao esta criando uma base historica. Ele nao calcula tendencia, nao guarda amostras antigas, nao desenha grafico e nao dispara alerta. Ele olha para o host naquele momento e escreve um estado estruturado.
Isso e intencional. Historico, graficos e alertas sao responsabilidades melhores para consumidores. No meu caso, o consumidor principal e o Home Assistant. Em outro ambiente, poderia ser Grafana, uma bridge Prometheus, MQTT, Node-RED ou um script interno.
Um snapshot simplificado tem esta ideia:
{
"schema": {
"name": "pma.metrics",
"version": 1
},
"collection": {
"status": "ok",
"generated_at": "2026-07-13T12:00:00Z",
"duration_ms": 420,
"errors": []
},
"host": {},
"cpu": {},
"memory": {},
"sensors": {},
"virtualization": {}
}
O JSON real e bem mais completo, mas essa estrutura mostra a ideia: um contrato unico, versionado e previsivel.
Timer e arquivo de snapshot
Para uso continuo, o caminho normal e instalar o timer systemd. Com ele habilitado, o agent escreve o ultimo snapshot em:
/run/pma/metrics.json
O intervalo padrao e 60 segundos. Para verificar o timer:
systemctl status pma-metrics.timer --no-pager
Para disparar uma coleta manual pelo service:
systemctl start pma-metrics.service
E para conferir rapidamente se a coleta esta saudavel:
jq '.collection.status, .collection.errors' /run/pma/metrics.json

Esse desenho evita uma armadilha comum: coletar tudo a cada request HTTP. Alguns comandos podem demorar, alguns sensores podem responder mais devagar, e voce nao quer que cada consulta do Home Assistant dispare uma varredura completa no host.
Em vez disso, o timer atualiza o arquivo em background. O HTTP server apenas serve o ultimo snapshot disponivel.
HTTP snapshot server
O HTTP server e opcional e usa systemd socket activation. Ele expoe dois endpoints:
GET /health
GET /metrics.json
Para testar no proprio host:
curl -fsS http://127.0.0.1:9782/health | jq .
curl -fsS http://127.0.0.1:9782/metrics.json | jq '.schema, .host.hostname, .collection.status'
Para testar de outra maquina na LAN:
curl -fsS http://<proxmox-ip>:9782/health | jq .
curl -fsS http://<proxmox-ip>:9782/metrics.json | jq '.host.hostname, .collection.status'

O /health e leve. Ele informa se existe snapshot, qual arquivo esta sendo servido e qual intervalo de coleta esta configurado. Isso e util para uma integracao descobrir se o agent esta vivo antes de tentar parsear o snapshot completo.
O /metrics.json retorna o ultimo snapshot. Se ainda nao existe snapshot, o endpoint pode responder 503. Isso e melhor do que retornar lixo ou um JSON incompleto fingindo que esta tudo bem.
O que entra no schema
O Schema v1 do PMA e organizado para ser previsivel para consumidores.
Na raiz, ele traz:
schema, com nome e versao do contrato.collection, com status da coleta, horario, duracao e erros estruturados.capabilities, com ferramentas e features disponiveis.host, com identidade e informacoes do host.cluster, com status de cluster Proxmox quando disponivel.cpu, com informacoes de CPU, uso atual e load average.memory, com memoria e swap.network, com interfaces fisicas do host.filesystems, com mounts relevantes.storage, com storages do Proxmox e status local.disks, com dispositivos de bloco.sensors, com temperaturas, fans, voltagens e energia normalizadas.virtualization, com VMs e containers LXC.


Algumas decisoes no schema sao pequenas, mas importantes.
A lista network[] filtra interfaces virtuais do Proxmox, como vmbr*, tap*, veth* e interfaces auxiliares de firewall. Isso evita gerar um monte de entidade ruidosa no consumidor.
A lista filesystems[] tambem filtra mounts de runtime e pseudo-filesystems, como /proc, /sys, /dev, /run e similares. O objetivo e mostrar o que importa para operacao, nao despejar tudo que o kernel enxerga.
Temperaturas usam Celsius. Tamanhos e contadores usam bytes, exceto quando documentado de outra forma. Duracoes usam segundos, com excecao de collection.duration_ms. Quando um valor escalar nao pode ser coletado, ele tende a vir como null. Quando uma lista nao pode ser coletada, ela vem vazia.
Essas regras deixam o consumidor mais simples. Ele nao precisa adivinhar se um campo sumiu porque deu erro, se veio uma string vazia, ou se o tipo mudou.
Separando coleta de acao
Uma tentacao comum em projetos de monitoramento e colocar tudo no mesmo lugar: coleta, historico, alerta, dashboard e automacao. Para esse projeto, eu escolhi o caminho oposto.
O Proxmox Monitor Agent coleta. So isso.
Ele nao guarda historico porque o host Proxmox nao precisa virar banco de metricas. Ele nao dispara alerta porque cada ambiente tem seu proprio canal de notificacao. Ele nao liga exaustor, nao reinicia VM e nao toma acao em nome do usuario.
Isso fica para os consumidores.
No Home Assistant, eu ja tenho historico, entidades, notificacoes e automacoes. No Grafana, eu teria dashboards. Em uma bridge Prometheus, eu teria series temporais. Em Node-RED, eu teria fluxos. O agent nao precisa conhecer nenhum desses mundos para ser util.
Essa separacao tambem ajuda na seguranca e na manutencao. O host expoe um endpoint simples na rede local. O consumidor decide o que fazer. Se eu mudar a automacao no Home Assistant, nao preciso tocar no Proxmox. Se eu quiser outro consumidor no futuro, o contrato JSON continua sendo o mesmo.
Proximo passo
Com o agent rodando, o ponto cego do host comeca a virar dado. Agora existe um lugar onde buscar temperatura, CPU, memoria, storage, VMs e LXCs.
Mas dado bruto em JSON ainda nao e a experiencia que eu quero no dia a dia. Eu quero isso dentro do Home Assistant, como devices e entidades, com historico e alertas.
E isso que entra no proximo post: a custom integration que consome o endpoint do PMA e transforma o snapshot do Proxmox em entidades dentro do Home Assistant.