# Copyright (c) Microsoft. All rights reserved. from __future__ import annotations import platform import socket from contextlib import suppress from datetime import datetime from typing import Any, Dict, List, cast import psutil from gpustat import GPUStat, GPUStatCollection def system_snapshot(include_gpu: bool = False) -> Dict[str, Any]: """Capture a snapshot of the system's hardware and software information. Args: include_gpu: Whether to include GPU information. Returns: A dictionary containing the system's hardware and software information. """ # CPU cpu = { "cpu_name": platform.processor(), "cpu_cores": psutil.cpu_count(logical=False), "cpu_threads": psutil.cpu_count(logical=True), "cpu_usage_pct": psutil.cpu_percent(0.0), } # Memory vm = psutil.virtual_memory() mem = { "mem_used_gb": round(vm.used / (2**30), 2), "mem_total_gb": round(vm.total / (2**30), 2), "mem_pct": vm.percent, } # Disk du = psutil.disk_usage("/") disk = { "disk_used_gb": round(du.used / (2**30), 2), "disk_total_gb": round(du.total / (2**30), 2), "disk_pct": du.percent, } # GPU (only query if explicitly requested) gpus: List[Dict[str, Any]] = [] if include_gpu: with suppress(Exception): for g in GPUStatCollection.new_query().gpus: # type: ignore g = cast(GPUStat, g) gpus.append( { "gpu": g.name, # type: ignore "util_pct": g.utilization, "mem_used_mb": g.memory_used, "mem_total_mb": g.memory_total, "temp_c": g.temperature, } ) # Network net = psutil.net_io_counters() netinfo = { "bytes_sent_mb": round(net.bytes_sent / (2**20), 2), "bytes_recv_mb": round(net.bytes_recv / (2**20), 2), } # OS / meta return { "timestamp": datetime.now().isoformat(timespec="seconds"), "host": socket.gethostname(), "os": platform.platform(), **cpu, **mem, **disk, **netinfo, **({"gpus": gpus} if include_gpu else {}), }