Skip to content

How to Capture System Metrics Programmatically in Python

Learn how to monitor CPU, memory, disk, and network metrics in Python using the psutil library to build custom performance tools and health checks.

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 psutil

Method 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/s

Method 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:

  1. CPU: Use psutil.cpu_percent(interval=1) to measure load over time.
  2. Memory: Use psutil.virtual_memory() to check RAM limits.
  3. Disk: Use psutil.disk_usage('/') to prevent storage overflow.
  4. Network: Calculate the difference between psutil.net_io_counters() snapshots to determine speed.
Navigation