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.


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.
  • smartctl e nvme, para informacoes de discos quando instaladas.
  • zpool e zfs, para ambientes com ZFS.
  • qm e pct, 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.

Instalador interativo do Proxmox Monitor Agent

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.

Saida do pma-metrics formatada com jq

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

Status do pma-metrics.timer

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'

Resposta do endpoint health

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.

Trecho de sensors.temperatures no JSON do PMA

Trecho de virtualization.vms no JSON do PMA

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.

Parte 3 - Integrando com o Home Assistant