Monitoring system metrics (such as CPU usage, memory consumption, disk I/O, and network traffic) is essential for building health checks, performance profilers, and dashboarding tools. While operating systems provide command-line tools like top or Task Manager, accessing this data programmatically allows developers to build custom alerting systems and automated resource managers.
This guide explains how to capture these metrics in Python using the cross-platform psutil library.
Setting Up the Environment
Python does not have built-in modules that cover deep system metrics across all operating systems. The industry standard library for this task is psutil (process and system utilities).
Installation:
pip install psutilMethod 1: Capturing CPU and Memory Metrics
The two most critical health indicators are the processor load and RAM availability.
CPU Metrics
psutil.cpu_percent() calculates the current CPU utilization as a percentage. It compares system clock ticks between intervals.
Memory Metrics
psutil.virtual_memory() returns an object containing statistics about system memory usage.
import psutil
def get_core_metrics():
cpu_usage = psutil.cpu_percent(interval=1)
cpu_freq = psutil.cpu_freq()
ram = psutil.virtual_memory()
print(f"--- System Snapshot ---")
print(f"CPU Usage: {cpu_usage}%")
print(f"CPU Frequency: {cpu_freq.current:.2f} Mhz")
print(f"Total RAM: {ram.total / (1024**3):.2f} GB")
print(f"Available RAM: {ram.available / (1024**3):.2f} GB")
print(f"RAM Usage: {ram.percent}%")
if __name__ == "__main__":
get_core_metrics()Output:
--- System Snapshot ---
CPU Usage: 12.5%
CPU Frequency: 3600.00 Mhz
Total RAM: 16.00 GB
Available RAM: 8.45 GB
RAM Usage: 47.2%Method 2: Monitoring Disk and Network I/O
Disk and network metrics are vital for identifying I/O bottlenecks.
Disk Usage
psutil.disk_usage(path) return usage statistics for the partition containing the given path.
Network Stats
psutil.net_io_counters() provides total bytes sent and received. Since these are cumulative counters (total bytes since boot), calculating the current speed requires taking two snapshots and finding the difference.
import psutil
import time
def get_io_metrics():
disk = psutil.disk_usage('/')
print(f"--- Disk & Network ---")
print(f"Disk Total: {disk.total / (1024**3):.2f} GB")
print(f"Disk Used: {disk.percent}%")
print("Calculating network speed (sampling for 1 second)...")
net1 = psutil.net_io_counters()
time.sleep(1)
net2 = psutil.net_io_counters()
bytes_sent = net2.bytes_sent - net1.bytes_sent
bytes_recv = net2.bytes_recv - net1.bytes_recv
print(f"Upload Speed: {bytes_sent / 1024:.2f} KB/s")
print(f"Download Speed: {bytes_recv / 1024:.2f} KB/s")
if __name__ == "__main__":
get_io_metrics()Output:
--- Disk & Network ---
Disk Total: 465.63 GB
Disk Used: 65.4%
Calculating network speed (sampling for 1 second)...
Upload Speed: 12.05 KB/s
Download Speed: 340.10 KB/sMethod 3: Building a Continuous Monitor
For real-world applications, you usually need to collect metrics periodically and output them in a structured format (like JSON) for logging or dashboards.
import psutil
import time
import json
from datetime import datetime
def monitor_system(interval=5):
print(f"Starting monitoring (Ctrl+C to stop)... Interval: {interval}s")
try:
while True:
metrics = {
"timestamp": datetime.now().isoformat(),
"cpu_percent": psutil.cpu_percent(interval=None),
"memory_percent": psutil.virtual_memory().percent,
"disk_percent": psutil.disk_usage('/').percent
}
print(json.dumps(metrics))
time.sleep(interval)
except KeyboardInterrupt:
print("\nMonitoring stopped.")
if __name__ == "__main__":
psutil.cpu_percent(interval=None)
monitor_system()Conclusion
Programmatic system monitoring in Python is straightforward with psutil:
- CPU: Use
psutil.cpu_percent(interval=1)to measure load over time. - Memory: Use
psutil.virtual_memory()to check RAM limits. - Disk: Use
psutil.disk_usage('/')to prevent storage overflow. - Network: Calculate the difference between
psutil.net_io_counters()snapshots to determine speed.