Get Geeky with Python: Build a System Monitor with Flair
Tags: python, opensource, sysadmin, beginners
Published: 2024-06-12 04:58:40

### Introduction

Hey there, fellow coders! Today, I'm super excited to share an awesome project I recently worked on—a Python System Monitor. This isn't just any ordinary system monitor; it comes with a splash of color and a whole lot of flair! Whether you're a beginner looking to level up your Python skills or an experienced developer wanting to create a handy tool, this project has something for everyone. Plus, I've made it open-source, so feel free to check out the code on my [GitHub repository](https://github.com/Pranjol-Dev/python-system-monitor.git).

I'm new to the development world, and every star on the repo will really motivate me to keep learning and building cool projects!

### What Does It Do?

This Python System Monitor provides detailed information about your system's hardware, including:

- **System Information**: OS, Node Name, Release, Version, Machine, and Processor.
- **CPU Information**: Physical and Logical Cores, Frequency, and Usage.
- **Memory Information**: Total, Available, Used Memory, and Swap.
- **GPU Information**: Load, Free Memory, Used Memory, Total Memory, and Temperature.

### Key Libraries Used

- **os** and **platform**: For basic system information.
- **psutil**: To fetch CPU and memory details.
- **GPUtil**: To get GPU stats.
- **colorama**: To add some colorful flair to the terminal output.
- **tabulate**: To format the output into neat tables.

### Breaking Down the Code

Let's dive into the code and see how it all works.

#### 1. System Information

We start by fetching basic system details using the `platform` library. The `get_system_info` function gathers and formats these details into a table.

```python
import platform
from colorama import Fore, Style

def get_system_info():
    uname = platform.uname()
    system_info = [
        [f"{Fore.YELLOW}System{Style.RESET_ALL}", uname.system],
        [f"{Fore.YELLOW}Node Name{Style.RESET_ALL}", uname.node],
        [f"{Fore.YELLOW}Release{Style.RESET_ALL}", uname.release],
        [f"{Fore.YELLOW}Version{Style.RESET_ALL}", uname.version],
        [f"{Fore.YELLOW}Machine{Style.RESET_ALL}", uname.machine],
        [f"{Fore.YELLOW}Processor{Style.RESET_ALL}", uname.processor]
    ]
    return system_info
```

#### 2. CPU Information

Next, we use `psutil` to get detailed CPU information, including core counts and frequencies.

```python
import psutil
from colorama import Fore, Style

def get_cpu_info():
    cpufreq = psutil.cpu_freq()
    cpu_info = [
        [f"{Fore.CYAN}Physical cores{Style.RESET_ALL}", psutil.cpu_count(logical=False)],
        [f"{Fore.CYAN}Total cores{Style.RESET_ALL}", psutil.cpu_count(logical=True)],
        [f"{Fore.CYAN}Max Frequency{Style.RESET_ALL}", f"{cpufreq.max:.2f}Mhz"],
        [f"{Fore.CYAN}Min Frequency{Style.RESET_ALL}", f"{cpufreq.min:.2f}Mhz"],
        [f"{Fore.CYAN}Current Frequency{Style.RESET_ALL}", f"{cpufreq.current:.2f}Mhz"]
    ]
    for i, percentage in enumerate(psutil.cpu_percent(percpu=True, interval=1)):
        cpu_info.append([f"{Fore.CYAN}Core {i}{Style.RESET_ALL}", f"{percentage}%"])
    cpu_info.append([f"{Fore.CYAN}Total CPU Usage{Style.RESET_ALL}", f"{psutil.cpu_percent()}%"])
    return cpu_info
```

#### 3. Memory Information

Memory details, including swap memory, are fetched and formatted.

```python
from colorama import Fore, Style

def get_memory_info():
    svmem = psutil.virtual_memory()
    swap = psutil.swap_memory()
    memory_info = [
        [f"{Fore.GREEN}Total Memory{Style.RESET_ALL}", f"{get_size(svmem.total)}"],
        [f"{Fore.GREEN}Available Memory{Style.RESET_ALL}", f"{get_size(svmem.available)}"],
        [f"{Fore.GREEN}Used Memory{Style.RESET_ALL}", f"{get_size(svmem.used)}"],
        [f"{Fore.GREEN}Percentage{Style.RESET_ALL}", f"{svmem.percent}%"],
        [f"{Fore.GREEN}Total Swap{Style.RESET_ALL}", f"{get_size(swap.total)}"],
        [f"{Fore.GREEN}Free Swap{Style.RESET_ALL}", f"{get_size(swap.free)}"],
        [f"{Fore.GREEN}Used Swap{Style.RESET_ALL}", f"{get_size(swap.used)}"],
        [f"{Fore.GREEN}Percentage Swap{Style.RESET_ALL}", f"{swap.percent}%"]
    ]
    return memory_info

def get_size(bytes, suffix="B"):
    factor = 1024
    for unit in ["", "K", "M", "G", "T", "P"]:
        if bytes < factor:
            return f"{bytes:.2f}{unit}{suffix}"
        bytes /= factor
```

#### 4. GPU Information

Using `GPUtil`, we gather GPU details and display them in a readable format.

```python
import GPUtil
from colorama import Fore, Style

def get_gpu_info():
    gpus = GPUtil.getGPUs()
    gpu_info = []
    for gpu in gpus:
        gpu_info.append([
            f"{Fore.MAGENTA}GPU ID{Style.RESET_ALL}", gpu.id
        ])
        gpu_info.append([
            f"{Fore.MAGENTA}GPU Name{Style.RESET_ALL}", gpu.name
        ])
        gpu_info.append([
            f"{Fore.MAGENTA}GPU Load{Style.RESET_ALL}", f"{gpu.load * 100}%"
        ])
        gpu_info.append([
            f"{Fore.MAGENTA}GPU Free Memory{Style.RESET_ALL}", f"{gpu.memoryFree}MB"
        ])
        gpu_info.append([
            f"{Fore.MAGENTA}GPU Used Memory{Style.RESET_ALL}", f"{gpu.memoryUsed}MB"
        ])
        gpu_info.append([
            f"{Fore.MAGENTA}GPU Total Memory{Style.RESET_ALL}", f"{gpu.memoryTotal}MB"
        ])
        gpu_info.append([
            f"{Fore.MAGENTA}GPU Temperature{Style.RESET_ALL}", f"{gpu.temperature} °C"
        ])
    return gpu_info
```

#### 5. Displaying the Information

Finally, we use `tabulate` to display all the collected information in a clean, readable format.

```python
from tabulate import tabulate
from colorama import Fore, Style

def display_info():
    system_info = get_system_info()
    cpu_info = get_cpu_info()
    memory_info = get_memory_info()
    gpu_info = get_gpu_info()
    
    print(f"{Fore.YELLOW}{'System Information':^50}{Style.RESET_ALL}")
    print(tabulate(system_info, tablefmt="fancy_grid"))
    print("\n")
    
    print(f"{Fore.CYAN}{'CPU Information':^50}{Style.RESET_ALL}")
    print(tabulate(cpu_info, tablefmt="fancy_grid"))
    print("\n")
    
    print(f"{Fore.GREEN}{'Memory Information':^50}{Style.RESET_ALL}")
    print(tabulate(memory_info, tablefmt="fancy_grid"))
    print("\n")
    
    print(f"{Fore.MAGENTA}{'GPU Information':^50}{Style.RESET_ALL}")
    print(tabulate(gpu_info, tablefmt="fancy_grid"))
    print("\n")

if __name__ == "__main__":
    display_info()
```

### Example Output

Here's what the output looks like when you run the script:

![System Information](https://camo.githubusercontent.com/96a3d8a64d07d51c64a29047b89a51e61f61f8e052d91bd7725935ec704f30c3/68747470733a2f2f692e696d6775722e636f6d2f6e6846587730495f642e776562703f6d617877696474683d37363026666964656c6974793d6772616e64)

![CPU Information](https://camo.githubusercontent.com/9d0071d6871fbdb0c9b0d8ba7e17a80ff399ec4ac9fb7f8bd36744ff241a4767/68747470733a2f2f692e696d6775722e636f6d2f34514156766f585f642e776562703f6d617877696474683d37363026666964656c6974793d6772616e64)

### Wrapping Up

And there you have it! A stylish and functional Python System Monitor that gives you a comprehensive look at your system's performance. Feel free to clone the repository, play around with the code, and customize it to your liking. You can find the full project on my [GitHub](https://github.com/Pranjol-Dev/python-system-monitor.git). 

I'm new to the development world, and every star on the repo will really motivate me to keep learning and building cool projects. Happy coding!