fix(gpu-amd): Parser ueber Spaltenkopf statt Einheitensuffix (rocm-smi liefert Einheiten nur im Header); VRAM, Junction-/Memory-Temp

This commit is contained in:
mm committed 2026-09-13 20:25:47 +02:00
1 parent 0674360563
commit 1a3205b31a
1 file changed
+26 -17
+26 -17
View File
@@ -1,13 +1,15 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# gpu-rocm.sh — AMD-GPU-Metriken via rocm-smi im Influx-Format. # gpu-rocm.sh — AMD-GPU-Metriken via rocm-smi im Influx-Format.
# #
# Aufruf durch Telegraf (inputs.exec). Wirft Zeilen der Form # Aufruf durch Telegraf (inputs.exec). Ausgabe:
# gpu_<metrik>,gpu=<karte> value=<zahl> # gpu_<metrik>,gpu=<karte> value=<zahl>
# aus, z. B. gpu_utilization_gpu,gpu=card0 value=37 # z. B. gpu_utilization_gpu,gpu=card0 value=25
# #
# Robust gegen unterschiedliche rocm-smi-Ausgaben: wirft pro Karte EINE # WICHTIG: rocm-smi liefert je nach Version MIT oder OHNE Einheitensuffix
# CSV-Zeile aus und sucht die Werte anhand ihrer Einheit (%, °C, W, MB/GB), # alt: card0,37%,52c,45W
# nicht anhand der Spaltenposition. # neu: card0,51.0,54.0,47.0,25 (Einheit nur im Spaltenkopf!)
# Deshalb wird hier die KOPFZEILE geparst und die Spalte ueber ihren Namen
# zugeordnet — nicht ueber Position oder Suffix. Das ist versionstolerant.
set -eu set -eu
@@ -18,29 +20,36 @@ fi
TMP="$(mktemp)"; trap 'rm -f "$TMP"' EXIT TMP="$(mktemp)"; trap 'rm -f "$TMP"' EXIT
rocm-smi --showuse --showtemp --showpower --showmeminfo vram --showproductname --csv \ rocm-smi --showuse --showtemp --showpower --showmeminfo vram --csv > "$TMP" 2>/dev/null || true
> "$TMP" 2>/dev/null || true
[ -s "$TMP" ] || exit 0 [ -s "$TMP" ] || exit 0
awk -F, ' awk -F, '
function num(s) { gsub(/[^0-9.]/, "", s); return s } # Spaltenkopf -> Metrikname. Reihenfolge egal, unbekannte Spalten werden ignoriert.
function emit(name, val, card) { function metric_for(header, h) {
if (val != "" && val != "N/A") printf "gpu_%s,gpu=%s value=%s\n", name, card, val h = tolower(header)
if (h ~ /gpu use|gpu_use|utilization/) return "utilization_gpu"
if (h ~ /sensor edge|edge/) return "temperature_edge"
if (h ~ /sensor junction|junction/) return "temperature_junction"
if (h ~ /sensor memory|memory.*\(c\)/) return "temperature_memory"
if (h ~ /power/) return "power_draw"
if (h ~ /vram total used|used memory/) return "memory_used"
if (h ~ /vram total|total memory/) return "memory_total"
return ""
}
function num(s) { gsub(/[^0-9.eE+-]/, "", s); return s }
NR == 1 {
for (i = 1; i <= NF; i++) col[i] = metric_for($i)
next
} }
NR == 1 { next } # Kopfzeile: Spaltennamen merken
{ {
card = $1 card = $1
gsub(/^[ \t]+|[ \t]+$/, "", card) gsub(/^[ \t]+|[ \t]+$/, "", card)
if (card == "") next if (card == "") next
for (i = 2; i <= NF; i++) { for (i = 2; i <= NF; i++) {
if (col[i] == "") continue
v = $i v = $i
gsub(/^[ \t]+|[ \t]+$/, "", v) gsub(/^[ \t]+|[ \t]+$/, "", v)
if (v == "" || v == "N/A" || v ~ /^\[/) continue if (v == "" || v == "N/A" || v ~ /^\[/) continue
if (v ~ /%/) { emit("utilization_gpu", num(v), card); continue } printf "gpu_%s,gpu=%s value=%s\n", col[i], card, num(v)
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" }' "$TMP"