System Monitor Core
Framework-agnostic system monitoring core for CPU, RAM, GPU, and VRAM metrics.
Module: pyqt_reactive.services.system_monitor_core
Overview
SystemMonitorCore provides framework-agnostic system monitoring that can be used in any Python application (Textual TUI, PyQt6, CLI tools, etc.).
It collects metrics for:
CPU: CPU usage percentage
RAM: Memory usage percentage
GPU: GPU usage percentage (if available)
VRAM: GPU memory usage percentage (if available)
Architecture
Framework-Agnostic Design
SystemMonitorCore is intentionally decoupled from any UI framework:
┌─────────────────────────────────────────────────────────┐
│ SystemMonitorCore (Framework-Agnostic) │
│ ┌──────────────────────────────────────────────┐ │
│ │ Metrics Collection (psutil + GPUtil) │ │
│ │ - CPU usage │ │
│ │ - RAM usage │ │
│ │ - GPU/VRAM usage (if available) │ │
│ └──────────────────────────────────────────────┘ │
│ │
│ UI Frameworks (plug into SystemMonitorCore): │
│ - Textual TUI (SystemMonitorTextual) │
│ - PyQt6 (SystemMonitorWidget) │
│ - CLI tools │
└─────────────────────────────────────────────────────────┘
This allows the same monitoring logic to be reused across different UI frameworks.
Usage
Basic Usage
from pyqt_reactive.services.system_monitor_core import SystemMonitorCore
# Create monitor with history length
monitor = SystemMonitorCore(history_length=300)
# Collect metrics
metrics = monitor.collect_metrics()
print(f"CPU: {metrics['cpu_percent']}%")
print(f"RAM: {metrics['ram_percent']}%")
# Get history
cpu_history = monitor.get_cpu_history()
ram_history = monitor.get_ram_history()
Metrics Collection
Metrics are collected using:
psutil: CPU and RAM metrics
GPUtil: GPU and VRAM metrics (if available)
metrics = {
'cpu_percent': float, # CPU usage (0-100)
'ram_percent': float, # RAM usage (0-100)
'gpu_percent': float, # GPU usage (0-100) or None
'vram_percent': float, # VRAM usage (0-100) or None
'timestamp': float, # Unix timestamp
}
GPU Detection
SystemMonitorCore automatically detects available GPUs:
monitor = SystemMonitorCore()
# Check if GPU is available
if monitor.gpu_count > 0:
print(f"Found {monitor.gpu_count} GPU(s)")
gpu_metrics = monitor.collect_metrics()
print(f"GPU: {gpu_metrics['gpu_percent']}%")
else:
print("No GPU detected")
History Management
History Length
The monitor maintains a rolling history of metrics:
# Create monitor with 300-point history (5 minutes at 1-second interval)
monitor = SystemMonitorCore(history_length=300)
# Get current history length
current_length = len(monitor.cpu_history) # Will be ≤ 300
Access History
Access individual metric histories:
# CPU history (list of floats)
cpu_history = monitor.get_cpu_history()
# RAM history (list of floats)
ram_history = monitor.get_ram_history()
# GPU history (list of floats, or None if no GPU)
gpu_history = monitor.get_gpu_history()
# VRAM history (list of floats, or None if no GPU)
vram_history = monitor.get_vram_history()
Current Metrics
Get the most recent metrics:
metrics = monitor.get_current_metrics()
print(f"CPU: {metrics['cpu_percent']}%")
print(f"RAM: {metrics['ram_percent']}%")
Performance Considerations
psutil vs GPUtil
psutil (CPU/RAM): - Fast, lightweight - Cross-platform - Built-in
GPUtil (GPU/VRAM): - Slower, but still fast enough - GPU-specific - Optional import (gracefully degrades if not available)
Lazy Import
GPUtil is imported lazily to avoid blocking:
# GPUtil imported only when needed
try:
import GPUtil
self._gpus = GPUtil.getGPUs()
except ImportError:
self._gpus = [] # Graceful degradation
Thread Safety
SystemMonitorCore is not thread-safe by default. If you need thread-safe access:
import threading
class ThreadSafeSystemMonitor:
def __init__(self):
self._monitor = SystemMonitorCore()
self._lock = threading.Lock()
def collect_metrics(self):
with self._lock:
return self._monitor.collect_metrics()
def update_metrics(self, metrics):
with self._lock:
self._monitor.update(metrics)
Integration with Persistent Monitor
PersistentSystemMonitor wraps SystemMonitorCore with background thread management:
from pyqt_reactive.services.persistent_system_monitor import PersistentSystemMonitor
# Create persistent monitor
monitor = PersistentSystemMonitor(
update_interval=2.0, # Update every 2 seconds
history_length=300, # Keep 300 points
)
# Start background thread
monitor.start()
# Access metrics (thread-safe)
metrics = monitor.get_current_metrics()
# Stop background thread
monitor.stop()
See Also
PyQt6 System Monitor - PyQt6 system monitor widget
Persistent System Monitor - Background thread monitor
GUI Performance Patterns - Performance optimization patterns