Files
netbird-telegraf-installer/scripts/proxmox-ve.sh
T

64 lines
2.4 KiB
Bash
Executable File

#!/usr/bin/env bash
# proxmox-ve.sh — VM- und Container-Metriken direkt vom PVE-Host.
#
# Läuft als root auf dem PVE-Knoten und nutzt `pvesh` (lokale API mit vollen
# Rechten). Damit entfällt der API-Token komplett — kein Sys.Audit, keine ACL.
#
# Ausgabe im Prometheus-Format (data_format = "prometheus" in der Telegraf-Conf):
# proxmox_vm_cpu_usage{vmid="1001",name="tunnel",type="qemu",status="running"} 0.42
#
# Aufruf durch Telegraf (inputs.exec) oder manuell zum Testen.
set -eu
command -v pvesh >/dev/null 2>&1 || { echo "# pvesh nicht gefunden — kein PVE-Host" >&2; exit 0; }
TMP="$(mktemp)"; trap 'rm -f "$TMP"' EXIT
pvesh get /cluster/resources --output-format json > "$TMP" 2>/dev/null || true
[ -s "$TMP" ] || exit 0
python3 - "$TMP" <<'PY'
import json, sys, re
def esc(s):
return str(s).replace('\\', '\\\\').replace('"', '\\"').replace('\n', ' ')
try:
data = json.load(open(sys.argv[1]))
except Exception as e:
print(f"# JSON-Fehler: {e}", file=sys.stderr); sys.exit(0)
rows = data.get("data", data) if isinstance(data, dict) else data
if not isinstance(rows, list):
sys.exit(0)
def emit(name, labels, value):
if value is None: return
lab = ",".join(f'{k}="{esc(v)}"' for k, v in labels.items() if v is not None)
print(f"{name}{{{lab}}} {value}")
for r in rows:
typ = r.get("type")
if typ not in ("qemu", "lxc"): # node/storage überspringen
continue
if r.get("template"): # Templates nicht als Gast zählen
continue
if str(r.get("vmid", "")) == "": # nur Gäste mit vmid
continue
L = {"vmid": r.get("vmid"), "name": r.get("name"), "node": r.get("node"),
"type": typ, "status": r.get("status")}
# cpu ist ein Anteil 0..1 der zugewiesenen Kerne
cpu = r.get("cpu")
if cpu is not None:
emit("proxmox_vm_cpu_usage", L, round(float(cpu) * 100, 2))
emit("proxmox_vm_cpu_cores", L, r.get("maxcpu"))
emit("proxmox_vm_mem_bytes", L, r.get("mem"))
emit("proxmox_vm_mem_max_bytes", L, r.get("maxmem"))
emit("proxmox_vm_disk_bytes", L, r.get("disk"))
emit("proxmox_vm_disk_max_bytes", L, r.get("maxdisk"))
emit("proxmox_vm_net_in_bytes", L, r.get("netin"))
emit("proxmox_vm_net_out_bytes", L, r.get("netout"))
emit("proxmox_vm_uptime_seconds", L, r.get("uptime"))
emit("proxmox_vm_running", L, 1 if r.get("status") == "running" else 0)
PY