| |
| import curses |
| import psutil |
| import time |
| from datetime import datetime |
|
|
| |
| try: |
| import GPUtil |
| GPU_OK = True |
| except ImportError: |
| GPU_OK = False |
|
|
| def format_bytes(b): |
| for u in ['B','KB','MB','GB','TB']: |
| if b < 1024.0: |
| return f"{b:.1f}{u}" |
| b /= 1024.0 |
| return f"{b:.1f}PB" |
|
|
| def main(stdscr): |
| curses.curs_set(0) |
| stdscr.nodelay(1) |
| last_net = psutil.net_io_counters() |
| last_time = time.time() |
|
|
| while True: |
| |
| try: |
| if stdscr.getkey() == 'q': |
| break |
| except: |
| pass |
|
|
| |
| cpu_percent = psutil.cpu_percent(interval=0) |
| mem = psutil.virtual_memory() |
| disk = psutil.disk_usage('/') |
| net_io = psutil.net_io_counters() |
| now = time.time() |
| rx_rate = (net_io.bytes_recv - last_net.bytes_recv) / (now - last_time) |
| tx_rate = (net_io.bytes_sent - last_net.bytes_sent) / (now - last_time) |
| last_net, last_time = net_io, now |
|
|
| |
| procs = [] |
| for p in psutil.process_iter(['pid','name','cpu_percent']): |
| try: |
| if p.info['cpu_percent']: |
| procs.append((p.info['pid'], p.info['name'], p.info['cpu_percent'])) |
| except: |
| pass |
| procs.sort(key=lambda x: x[2], reverse=True) |
| top5 = procs[:5] |
|
|
| |
| gpu_line = "" |
| if GPU_OK: |
| try: |
| gpus = GPUtil.getGPUs() |
| if gpus: |
| g = gpus[0] |
| gpu_line = f"GPU: {g.load*100:.0f}% {g.temperature}°C mem:{g.memoryUsed}/{g.memoryTotal}MB" |
| except: |
| pass |
|
|
| |
| height, width = stdscr.getmaxyx() |
| lines = [ |
| f"=== MONITEUR SYSTÈME (auto-refresh 2s) - {datetime.now():%Y-%m-%d %H:%M:%S} ===", |
| f"CPU : {cpu_percent:5.1f}% | RAM : {mem.percent:5.1f}% ({mem.used//1024**2}/{mem.total//1024**2} MB)", |
| f"DISK : {disk.percent:5.1f}% ({disk.used//1024**3}/{disk.total//1024**3} GB)", |
| f"NET : ⬇️ {format_bytes(rx_rate)}/s ⬆️ {format_bytes(tx_rate)}/s", |
| gpu_line if gpu_line else "GPU : non détecté", |
| "", |
| "TOP 5 PROCESSUS (CPU) :", |
| ] |
| for i, (pid, name, cpu) in enumerate(top5, 1): |
| lines.append(f"{i:2}. {pid:6} {name[:20]:20} {cpu:5.1f}%") |
| lines.append("") |
| lines.append("Appuyez sur 'q' pour quitter") |
|
|
| |
| stdscr.clear() |
| for y, line in enumerate(lines[:height-1]): |
| if y < height: |
| try: |
| stdscr.addstr(y, 0, line[:width-1]) |
| except: |
| pass |
| stdscr.refresh() |
| time.sleep(2) |
|
|
| if __name__ == "__main__": |
| |
| curses.wrapper(main) |