feat: add GPU status logging with state tracking to prevent duplicate log messages and configure NVIDIA runtime in docker-compose
Add graphics_log_state global to track GPU query status and prevent duplicate log messages. Log warning with error_summary() when nvidia-smi is unavailable or returns non-zero exit code. Log info message when GPU status becomes available with GPU count and binary path. Track signature tuples for unavailable/failed/ok states including GPU index/name/temperature/utilization.
This commit is contained in:
@@ -87,6 +87,7 @@ datastore_refresh_lock = threading.Lock()
|
||||
raid_refresh_lock = threading.Lock()
|
||||
datastore_cache = {"stored_at": 0.0, "snapshot": None, "raid": None, "raid_at": 0.0}
|
||||
raid_log_state = None
|
||||
graphics_log_state = None
|
||||
hardware_log_once = set()
|
||||
|
||||
LANG_NAMES = {"de":"Deutsch", "deu":"Deutsch", "ger":"Deutsch", "en":"Englisch", "eng":"Englisch", "ja":"Japanisch", "jpn":"Japanisch", "ko":"Koreanisch", "kor":"Koreanisch", "fr":"Französisch", "fra":"Französisch", "fre":"Französisch", "es":"Spanisch", "spa":"Spanisch", "it":"Italienisch", "ita":"Italienisch", "ru":"Russisch", "rus":"Russisch", "zh":"Chinesisch", "zho":"Chinesisch", "chi":"Chinesisch", "und":"Unbekannt", "":"Unbekannt"}
|
||||
@@ -356,12 +357,22 @@ def io_pressure():
|
||||
|
||||
def graphics_snapshot():
|
||||
"""Read NVIDIA GPU details with short, non-blocking subprocess timeouts."""
|
||||
global graphics_log_state
|
||||
query = "index,name,uuid,serial,pci.bus_id,driver_version,pstate,temperature.gpu,utilization.gpu,utilization.memory,memory.total,memory.used,memory.free,power.draw,power.limit,fan.speed,clocks.current.graphics,clocks.current.memory,clocks.max.graphics,clocks.max.memory,compute_mode"
|
||||
try:
|
||||
result = subprocess.run([NVIDIA_SMI_BIN, f"--query-gpu={query}", "--format=csv,noheader,nounits"], capture_output=True, text=True, timeout=5, check=False)
|
||||
except (OSError, subprocess.SubprocessError):
|
||||
except (OSError, subprocess.SubprocessError) as exc:
|
||||
signature = ("unavailable", str(exc))
|
||||
if signature != graphics_log_state:
|
||||
log.warning("GPU-Abfrage fehlgeschlagen: %s (%s)", NVIDIA_SMI_BIN, error_summary(exc))
|
||||
graphics_log_state = signature
|
||||
return {"available": False, "gpus": [], "processes": [], "error": "NVIDIA SMI nicht verfügbar"}
|
||||
if result.returncode != 0 or not result.stdout.strip():
|
||||
detail = " ".join((result.stderr or result.stdout or "keine Ausgabe").split())[:240]
|
||||
signature = ("failed", result.returncode, detail)
|
||||
if signature != graphics_log_state:
|
||||
log.warning("GPU-Abfrage fehlgeschlagen: %s (Code %s): %s", NVIDIA_SMI_BIN, result.returncode, detail)
|
||||
graphics_log_state = signature
|
||||
return {"available": False, "gpus": [], "processes": [], "error": "Keine NVIDIA-GPU erkannt"}
|
||||
fields = query.split(",")
|
||||
gpus = []
|
||||
@@ -386,6 +397,10 @@ def graphics_snapshot():
|
||||
processes.append({"pid": values[0], "name": values[1], "memory": values[2]})
|
||||
except (OSError, subprocess.SubprocessError):
|
||||
pass
|
||||
signature = ("ok", tuple((gpu.get("index"), gpu.get("name"), gpu.get("temperature.gpu"), gpu.get("utilization.gpu")) for gpu in gpus))
|
||||
if signature != graphics_log_state:
|
||||
log.info("GPU-Status verfügbar: %s NVIDIA-GPU(s) via %s", len(gpus), NVIDIA_SMI_BIN)
|
||||
graphics_log_state = signature
|
||||
return {"available": bool(gpus), "gpus": gpus, "processes": processes, "error": None if gpus else "Keine NVIDIA-GPU erkannt", "updated_at": time.time()}
|
||||
|
||||
def smart_status(device):
|
||||
|
||||
@@ -3,6 +3,7 @@ services:
|
||||
build: .
|
||||
container_name: media-max
|
||||
restart: unless-stopped
|
||||
gpus: all
|
||||
ports:
|
||||
- "8099:8099"
|
||||
devices:
|
||||
@@ -16,6 +17,9 @@ services:
|
||||
- "host.docker.internal:host-gateway"
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
NVIDIA_VISIBLE_DEVICES: ${NVIDIA_VISIBLE_DEVICES:-all}
|
||||
NVIDIA_DRIVER_CAPABILITIES: ${NVIDIA_DRIVER_CAPABILITIES:-compute,utility}
|
||||
volumes:
|
||||
# Host-Pfad deiner Film-Library -> interner Dashboard-Pfad
|
||||
- ${FILM_MEDIA_VOLUME}:/media/filme:ro
|
||||
|
||||
Reference in New Issue
Block a user