A real-time system monitoring tool built in Python and C++ that reads
directly from Linux kernel interfaces, no external libraries, no
abstractions. Raw /proc filesystem parsing.
Reads live system metrics every second:
- CPU usage % — parsed from
/proc/statusing time-delta calculation - Memory usage % — parsed from
/proc/meminfousingMemAvailable - Network bandwidth (MB/s) — parsed from
/proc/net/devusing byte-delta calculation - Top processes by memory — C++ binary reads
/proc/[pid]/statusdirectly
/proc is a virtual filesystem exposed by the Linux kernel. It doesn't
exist on disk, the kernel generates its contents in memory on every read.
Tools like htop, top, and ps all read from /proc under the hood.
This project does the same thing directly, without going through those tools.
systems-monitor/
├── monitor/
│ ├── __init__.py
│ ├── cpu.py # reads /proc/stat, calculates CPU delta
│ ├── memory.py # reads /proc/meminfo, calculates usage %
│ ├── network.py # reads /proc/net/dev, calculates MB/s delta
│ └── monitor.py # orchestrates all modules + calls C++ binary
├── cpp/
│ └── process_list.cpp # reads /proc/[pid]/status for each running PID
├── scripts/
│ └── run_monitor.sh # bash daemon — start/stop/status
├── tests/
│ └── test_monitor.py # 21 pytest tests across all modules
└── README.md
cpu 1957 125 990 66371 236 0 72 0 0 0
user nice sys idle iowait irq softirq
CPU usage cannot be calculated from a single snapshot, these are cumulative counters since boot. The module takes two readings separated by 1 second and calculates:
usage % = (1 - idle_delta / total_delta) * 100
idle_delta includes both idle and iowait, time the CPU was waiting
for I/O counts as idle time. This is the same formula htop uses.
MemTotal: 3991132 kB
MemAvailable: 3534344 kB
The module uses MemAvailable not MemFree. The difference:
MemFree— RAM with absolutely nothing in itMemAvailable— RAM available for new processes, includes reclaimable cache
MemFree is always misleadingly low because Linux deliberately fills
RAM with filesystem cache. MemAvailable is what actually matters.
used % = (MemTotal - MemAvailable) / MemTotal * 100
eth0: 119373906 95459 0 0 0 0 0 0 1122931 15786 ...
rx_bytes pkts ... tx_bytes pkts
Like CPU, a single snapshot only gives total bytes since boot, not current bandwidth. The module takes two readings and calculates:
bandwidth (MB/s) = (bytes_2 - bytes_1) / interval / (1024 * 1024)
Loopback (lo) is excluded, it counts traffic twice and is not
real network I/O.
/proc exposes a directory for every running process named by its PID.
The C++ binary:
- Opens
/procand iterates over all numeric directory names (PIDs) - Reads
/proc/[pid]/statusfor each PID - Extracts
Name:andVmRSS:fields - Filters out kernel threads (VmRSS = 0)
- Handles race conditions — processes can die mid-read
VmRSS (Virtual Memory Resident Set Size) is the actual physical RAM
a process is using right now, not virtual memory, not reserved memory.
The Python orchestrator calls this binary via subprocess for clean
language interop between the two layers.
- Linux (or Lima VM on macOS)
- Python 3.8+
- g++ compiler
cd cpp && g++ -o process_list process_list.cpp && cd ..python3 -m monitor.monitorpython3 -m monitor.monitor --watch./scripts/run_monitor.sh start # start
./scripts/run_monitor.sh status # check
./scripts/run_monitor.sh stop # stoppytest tests/test_monitor.py -v=======================================================
LINUX SYSTEM MONITOR
=======================================================
CPU Usage: 0.75%
Memory:
Total: 3897.6 MB
Used: 479.2 MB
Available: 3418.4 MB
Usage: 12.3%
Network:
eth0:
RX: 0.0 MB/s
TX: 0.0 MB/s
Top Processes (by memory):
PID Name Memory
-------- -------------------- ----------
7859 containerd 40852 kB
7983 buildkitd 40044 kB
1021 unattended-upgr 28600 kB
1787 lima-guestagent 27300 kB
1 systemd 14652 kB
=======================================================
- Process dies between PID listing and file open →
is_open()check - Process dies mid-read → empty name/zero memory filtered out
/procfails to open → explicit error with non-zero exit code- Kernel threads → filtered by
VmRSS == 0 - Permission denied on some PIDs → handled by
is_open()check - Division by zero in CPU calculation → explicit guard clause
- Network interface disappears between readings → interface membership check
- Linux
/procvirtual filesystem internals - CPU usage calculation via time-delta (same algorithm as
htop) MemAvailablevsMemFree- why the distinction matters- Network bandwidth as bytes-per-second delta
- C++ and Python interop via subprocess
- RAII in C++ - automatic resource cleanup
- TOCTOU race conditions in systems programming
- Bash daemon patterns - PID files,
nohup, signal handling