diff --git a/scripts/gpu-rocm.sh b/scripts/gpu-rocm.sh index 9103140..29fd96e 100755 --- a/scripts/gpu-rocm.sh +++ b/scripts/gpu-rocm.sh @@ -1,20 +1,46 @@ #!/usr/bin/env bash # gpu-rocm.sh — AMD-GPU-Metriken via rocm-smi im Influx-Format. -# Wird vom Telegraf-exec-Input gpu.conf aufgerufen (nur wenn rocm-smi existiert). -set -eu -command -v rocm-smi >/dev/null 2>&1 || exit 0 +# +# Aufruf durch Telegraf (inputs.exec). Wirft Zeilen der Form +# gpu_,gpu= value= +# aus, z. B. gpu_utilization_gpu,gpu=card0 value=37 +# +# Robust gegen unterschiedliche rocm-smi-Ausgaben: wirft pro Karte EINE +# CSV-Zeile aus und sucht die Werte anhand ihrer Einheit (%, °C, W, MB/GB), +# nicht anhand der Spaltenposition. -# rocm-smi --showuse --showtemp --showpower --showmeminfo vram --csv -rocm-smi --showuse --showtemp --showpower --showmeminfo vram --csv 2>/dev/null \ -| awk -F, ' - NR == 1 { next } - { - gsub(/^ +| +$/, "", $1); gsub(/^ +| +$/, "", $2); gsub(/^ +| +$/, "", $3); gsub(/^ +| +$/, "", $4); - card = $1 - for (i = 2; i <= NF; i++) { - if ($i ~ /%/) { g = $i; gsub(/%/, "", g); printf "gpu,gpu=%s,metric=utilization_gpu value=%s\n", card, g } - if ($i ~ /c$/) { t = $i; gsub(/c/, "", t); printf "gpu,gpu=%s,metric=temperature_gpu value=%s\n", card, t } - if ($i ~ /W$/) { p = $i; gsub(/W/, "", p); printf "gpu,gpu=%s,metric=power_draw value=%s\n", card, p } - if ($i ~ /^[0-9]+$/) { printf "gpu,gpu=%s,metric=memory_used value=%s\n", card, $i } - } - }' 2>/dev/null || true +set -eu + +if ! command -v rocm-smi >/dev/null 2>&1; then + echo "# rocm-smi nicht gefunden" >&2 + exit 0 +fi + +TMP="$(mktemp)"; trap 'rm -f "$TMP"' EXIT + +rocm-smi --showuse --showtemp --showpower --showmeminfo vram --showproductname --csv \ + > "$TMP" 2>/dev/null || true +[ -s "$TMP" ] || exit 0 + +awk -F, ' +function num(s) { gsub(/[^0-9.]/, "", s); return s } +function emit(name, val, card) { + if (val != "" && val != "N/A") printf "gpu_%s,gpu=%s value=%s\n", name, card, val +} +NR == 1 { next } # Kopfzeile: Spaltennamen merken +{ + card = $1 + gsub(/^[ \t]+|[ \t]+$/, "", card) + if (card == "") next + for (i = 2; i <= NF; i++) { + v = $i + gsub(/^[ \t]+|[ \t]+$/, "", v) + if (v == "" || v == "N/A" || v ~ /^\[/) continue + if (v ~ /%/) { emit("utilization_gpu", num(v), card); continue } + if (v ~ /c$|C$/) { emit("temperature_gpu", num(v), card); continue } + if (v ~ /W$/) { emit("power_draw", num(v), card); continue } + # rocm-smi liefert VRAM entweder als "1.0 GB"/"512 MB" oder roh in Bytes + if (v ~ /[KMG]i?B/) { emit("memory_used", num(v), card); continue } + if (v ~ /^[0-9]{6,}$/) { emit("memory_used", num(v) / 1048576, card); continue } + } +}' "$TMP"