Build a System Monitor Dashboard with Python
Imagine staring at a blinking server alert at 2 AM, wondering if it’s a CPU spike, a memory leak, or just a glitch. You could spend hours debugging, or you could have built a real-time dashboard that showed you the problem before it became an emergency. That’s the power of a system monitor: it turns invisible metrics into visible insights, and you can build one in Python today with less than 100 lines of code.
Let’s build a lightweight, web-based System Monitor Dashboard that tracks your CPU, RAM, and Disk usage in real time. No complex frameworks, no cloud dependencies—just pure Python, Flask, and psutil.
Why Build Your Own Monitor?
Most developers rely on pre-built tools like htop or cloud dashboards, but those often lack customization or context for your specific environment. A custom dashboard lets you:
- Track custom thresholds (e.g., alert if CPU > 80%)
- Visualize trends over time
- Integrate with your own workflows (e.g., Slack notifications, logs)
- Run it locally without external services
Plus, building it yourself is a fantastic way to deepen your understanding of system metrics, web sockets, and Python’s psutil library.
Setting Up the Project
First, create a project folder and set up a virtual environment to keep dependencies isolated:
mkdir system_monitor_dashboard
cd system_monitor_dashboard
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
Now install the only two libraries we need:
pip install flask psutil
- Flask: A lightweight web framework to serve our dashboard.
- psutil: A cross-platform library to fetch system metrics (CPU, RAM, Disk).
Creating the Backend (Python)
Create a file named app.py. This will be our Flask server that fetches metrics and sends them to the frontend every few seconds.
from flask import Flask, render_template, jsonify
import psutil
import time
app = Flask(__name__)
def get_system_metrics():
cpu = psutil.cpu_percent(interval=1)
ram = psutil.virtual_memory()
disk = psutil.disk_usage('/')
return {
'cpu': cpu,
'ram_percent': ram.percent,
'disk_percent': disk.percent,
'ram_used_gb': ram.used / (1024**3),
'ram_total_gb': ram.total / (1024**3),
'disk_used_gb': disk.used / (1024**3),
'disk_total_gb': disk.total / (1024**3)
}
@app.route('/')
def index():
return render_template('index.html')
@app.route('/metrics')
def metrics():
return jsonify(get_system_metrics())
if __name__ == '__main__':
app.run(debug=True)
This code:
- Defines
get_system_metrics()to fetch CPU, RAM, and Disk stats. - Serves an HTML template at
/(our dashboard). - Exposes a
/metricsendpoint that returns JSON data every time it’s called. - Runs the Flask app on
localhost:5000.
Building the Frontend (HTML + Chart.js)
Flask expects templates in a templates folder. Create it and add index.html:
mkdir templates
Now create templates/index.html:
<!DOCTYPE html>
<html>
<head>
<title>System Monitor Dashboard</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
body { font-family: Arial; padding: 20px; background: #f4f4f9; }
.chart-container { width: 45%; display: inline-block; margin: 10px; }
h1 { color: #333; }
.metric { font-size: 1.2em; margin: 10px 0; }
</style>
</head>
<body>
<h1>🖥️ Real-Time System Monitor</h1>
<div class="metric">CPU: <span id="cpu">0%</span></div>
<div class="metric">RAM: <span id="ram">0%</span> (<span id="ram_used">0</span> GB / <span id="ram_total">0</span> GB)</div>
<div class="metric">Disk: <span id="disk">0%</span> (<span id="disk_used">0</span> GB / <span id="disk_total">0</span> GB)</div>
<div class="chart-container">
<canvas id="cpuChart"></canvas>
</div>
<div class="chart-container">
<canvas id="ramChart"></canvas>
</div>
<script>
const cpuChart = new Chart(document.getElementById('cpuChart'), {
type: 'line',
data: { labels: [], datasets: [{ label: 'CPU %', data: [], borderColor: 'red', fill: false }] },
options: { scales: { y: { min: 0, max: 100 } }, animation: { duration: 0 } }
});
const ramChart = new Chart(document.getElementById('ramChart'), {
type: 'line',
data: { labels: [], datasets: [{ label: 'RAM %', data: [], borderColor: 'blue', fill: false }] },
options: { scales: { y: { min: 0, max: 100 } }, animation: { duration: 0 } }
});
async function updateMetrics() {
const res = await fetch('/metrics');
const data = await res.json();
document.getElementById('cpu').textContent = data.cpu.toFixed(1) + '%';
document.getElementById('ram').textContent = data.ram_percent.toFixed(1) + '%';
document.getElementById('ram_used').textContent = data.ram_used_gb.toFixed(2);
document.getElementById('ram_total').textContent = data.ram_total_gb.toFixed(2);
document.getElementById('disk').textContent = data.disk_percent.toFixed(1) + '%';
document.getElementById('disk_used').textContent = data.disk_used_gb.toFixed(2);
document.getElementById('disk_total').textContent = data.disk_total_gb.toFixed(2);
const now = new Date().toLocaleTimeString();
cpuChart.data.labels.push(now);
cpuChart.data.datasets[0].data.push(data.cpu);
ramChart.data.labels.push(now);
ramChart.data.datasets[0].data.push(data.ram_percent);
if (cpuChart.data.labels.length > 20) cpuChart.data.labels.shift();
if (cpuChart.data.datasets[0].data.length > 20) cpuChart.data.datasets[0].data.shift();
if (ramChart.data.labels.length > 20) ramChart.data.labels.shift();
if (ramChart.data.datasets[0].data.length > 20) ramChart.data.datasets[0].data.shift();
cpuChart.update();
ramChart.update();
}
setInterval(updateMetrics, 5000); // Update every 5 seconds
</script>
</body>
</html>
This frontend:
- Displays live numeric metrics.
- Uses Chart.js to render real-time line graphs for CPU and RAM.
- Fetches data from
/metricsevery 5 seconds. - Keeps only the last 20 data points to avoid memory bloat.
Running Your Dashboard
Launch the app:
python app.py
Open your browser and navigate to:
http://127.0.0.1:5000/
You’ll see real-time charts updating every 5 seconds, showing your current CPU, RAM, and Disk usage [1][2].
Making It Actionable: Add Alerts
Want to go further? Add a simple alert system. Modify app.py to check thresholds:
def check_alerts(metrics):
alerts = []
if metrics['cpu'] > 80:
alerts.append("⚠️ High CPU usage!")
if metrics['ram_percent'] > 90:
alerts.append("⚠️ RAM nearly full!")
return alerts
Then expose /alerts endpoint and display them in your HTML. This turns your dashboard from passive monitoring into an active warning system.
Next Steps & Customization
You’ve built a working monitor—now make it yours:
-
Add more metrics: Use
psutil.network_connections()for network stats. - Persist data: Save metrics to a CSV or database for historical analysis.
- Deploy it: Run on a Raspberry Pi to monitor a server remotely.
- **Integrate notifications
If you found this helpful, consider buying me a coffee ☕ — it keeps these articles coming!
Also check out my AI tools collection: AI 次元世界 — free AI tools for developers.
💡 Related: **Content Creator Ultimate Bundle (Save 33%)* — $29.99*
Top comments (0)