Building A Real-Time System Monitoring Dashboard With Python
Building A Real-Time System Monitoring Dashboard With Python
with Python
towardsdev.com/building-a-real-time-system-monitoring-dashboard-with-python-6e09ff15e0ff
Let’s create a dashboard using Python that monitors your system’s performance in real-
time. The dashboard will display your PC’s RAM, CPU load and disk space usage.
We will use Dash for the web interface, Plotly for interactive graphs, psutil for system
monitoring.
This will work on both Windows and Linux systems. However, for macOS users or special
configurations, slight modifications may be needed.
1/15
Dash/ Python GIF
Project Setup
system_monitor_dashboard system_monitor_dashboard
For Windows:
2/15
For Linux/Mac:
This will install all the libraries required to build our dashboard.
app.py
3/15
import dash
from dash import dcc, html
from dash.dependencies import Input, Output
import plotly.graph_objs as go
import psutil
import logging
from collections import deque
from datetime import datetime
import sys
# Define fixed-size lists (deque) to store the last 20 data points for RAM, CPU,
Disk usage, and time
history = {
'ram': deque(maxlen=20),
'cpu': deque(maxlen=20),
'disk': deque(maxlen=20),
'time': deque(maxlen=20) # Store timestamps for x-axis
}
4/15
except Exception as e:
logging.error(f"Error fetching system stats: ")
return {}
if mode == 'one':
app.layout = html.Div([
html.H1('System Monitoring Dashboard (Combined Graph)'),
# Update callback to refresh the combined RAM, CPU, and Disk usage graph every
interval
@app.callback()
defupdate_combined_graph(n):
# Fetch system stats (RAM, CPU, and Disk)
data = get_system_stats()
ifnot data:
logging.info("No data fetched")
return {}
# Append the current time, RAM, CPU, and Disk usage to history
current_time = datetime.now().strftime('%H:%M:%S') # Get the current time
as a string
history['ram'].append(data['RAM Usage (%)'])
5/15
history['cpu'].append(data['CPU Usage (%)'])
history['disk'].append(data['Disk Usage (%)'])
history['time'].append(current_time)
return combined_figure
else:
# Layout for multiple graphs (RAM, CPU, Disk each on its own graph)
app.layout = html.Div([
html.H1('System Monitoring Dashboard (Separate Graphs)'),
6/15
# Disk Usage Line Chart
dcc.Graph(id='disk-usage-graph'),
# Update callback to refresh the RAM, CPU, and Disk usage graphs every interval
@app.callback()
defupdate_separate_graphs(n):
# Fetch system stats (RAM, CPU, and Disk)
data = get_system_stats()
ifnot data:
logging.info("No data fetched")
return {}, {}, {}
# Append the current time, RAM, CPU, and Disk usage to history
current_time = datetime.now().strftime('%H:%M:%S') # Get the current time
as a string
history['ram'].append(data['RAM Usage (%)'])
history['cpu'].append(data['CPU Usage (%)'])
history['disk'].append(data['Disk Usage (%)'])
history['time'].append(current_time)
7/15
yaxis=dict(title='Percentage'),
)
}
__name__ == : app.run_server(debug=)
python app.py
3. Run the dashboard with the following command to show three charts each with one
metric:
8/15
python app.py multiple
This will start the application on a local web server. Open your browser and visit:
http:
in percentage
in percentage
in percentage
logging.basicConfig(level=logging.INFO)
This line configures the logging system to show messages at the INFO level or higher,
providing useful feedback during the program's execution.
= dash.Dash(__name__)
This creates a Dash application, which will serve as the basis for the real-time dashboard.
The __name__ parameter helps Dash locate resources correctly.
9/15
The maxlen=20 ensures that only the last 20 values are kept in memory, and older values
are automatically removed. This is particularly useful for real-time graphs, which only
need to show a limited number of recent data points.
defget_system_stats():
try:
# Get memory stats
memory = psutil.virtual_memory()
ram = memory.percent
CPU Usage: The psutil.cpu_percent() function returns the current CPU usage. The
interval=1 argument tells the function to calculate CPU usage over a 1-second period.
Disk Usage: We use psutil.disk_usage('/') to get the disk usage percentage for the
root directory (/).
This function gathers all this data and returns it as a dictionary. If an error occurs, it logs
the error and returns an empty dictionary.
If the argument one is provided when the script is run, the application will combine all the
data into a single graph. If no argument or multiple is provided, separate graphs will be
displayed.
10/15
6. Creating the Layout and Callbacks for Combined Graph Mode
When running in the one mode, the layout contains a single graph, and the data is
refreshed every 5 seconds:
if mode == 'one':
app.layout = html.Div([
html.H1('System Monitoring Dashboard (Combined Graph)'),
dcc.Interval( =, interval=5*1000,
n_intervals=0 ) ])
This layout includes a title (html.H1) and a graph component (dcc.Graph). The
dcc.Interval component is used to refresh the data every 5 seconds (5000
milliseconds).
The callback function below updates the combined graph by fetching the latest system
stats and adding them to the history deques:
11/15
@app.callback()
defupdate_combined_graph(n):
# Fetch system stats (RAM, CPU, and Disk)
data = get_system_stats()
ifnot data:
logging.info("No data fetched")
return {}
# Append the current time, RAM, CPU, and Disk usage to history
current_time = datetime.now().strftime('%H:%M:%S') # Get the current time as
a string
history['ram'].append(data['RAM Usage (%)'])
history['cpu'].append(data['CPU Usage (%)'])
history['disk'].append(data['Disk Usage (%)'])
history['time'].append(current_time)
combined_figure
12/15
This callback fetches the data every 5 seconds, appends it to the history deque, and
then creates a combined line chart to display the three metrics over time.
else:
app.layout = html.Div([
html.H1('System Monitoring Dashboard (Separate Graphs)'),
dcc.Interval( =, interval=5*1000,
n_intervals=0 ) ])
13/15
@app.callback()
defupdate_separate_graphs(n):
# Fetch system stats (RAM, CPU, and Disk)
data = get_system_stats()
ifnot data:
logging.info("No data fetched")
return {}, {}, {}
# Append the current time, RAM, CPU, and Disk usage to history
current_time = datetime.now().strftime('%H:%M:%S')
history['ram'].append(data['RAM Usage (%)'])
history['cpu'].append(data['CPU Usage (%)'])
history['disk'].append(data['Disk Usage (%)'])
history['time'].append(current_time)
cpu_figure = {
'data': [go.Scatter(
x=list(history['time']),
y=list(history['cpu']),
mode='lines+markers',
name='CPU Usage (%)'
)],
'layout': go.Layout(title='CPU Usage Over Time', xaxis=dict(title='Time'),
yaxis=dict(title='Percentage'))
}
disk_figure = {
'data': [go.Scatter(
x=list(history['time']),
y=list(history['disk']),
mode='lines+markers',
name='Disk Usage (%)'
)],
14/15
'layout': go.Layout(title='Disk Usage Over Time', xaxis=dict(title='Time'),
yaxis=dict(title='Percentage'))
}
Each graph displays its own data set, pulled from the history deque and updated every
5 seconds.
__name__ == : app.run_server(=True)
Running the app with python app.py one will display a combined graph, while python
app.py multiple will display separate graphs for each metric.
Visit this link for a similar project that uses Chart.js rather than dash/plotly.
Thank you for reading this article. I hope you found it helpful and informative. If you have
any questions, or if you would like to suggest new Python code examples or topics for
future tutorials, please feel free to reach out. Your feedback and suggestions are always
welcome!
Happy coding!
C. C. Python Programming
15/15