0% found this document useful (0 votes)
1 views15 pages

Building A Real-Time System Monitoring Dashboard With Python

The document outlines the creation of a real-time system monitoring dashboard using Python, Dash, and Plotly to display RAM, CPU load, and disk space usage. It provides a step-by-step guide for setting up the project, including creating a virtual environment, installing necessary libraries, and writing the code to gather and visualize system statistics. The dashboard is designed to work on Windows and Linux, with potential adjustments for macOS users.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
1 views15 pages

Building A Real-Time System Monitoring Dashboard With Python

The document outlines the creation of a real-time system monitoring dashboard using Python, Dash, and Plotly to display RAM, CPU load, and disk space usage. It provides a step-by-step guide for setting up the project, including creating a virtual environment, installing necessary libraries, and writing the code to gather and visualize system statistics. The dashboard is designed to work on Windows and Linux, with potential adjustments for macOS users.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 15

Building a Real-Time System Monitoring Dashboard

with Python
towardsdev.com/building-a-real-time-system-monitoring-dashboard-with-python-6e09ff15e0ff

Py-Core Python Programming 13 de janeiro de 2025

System Dashboard with Plotly in Python

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

Step 1: Create a Project Folder


Begin by creating a folder for the project. Open a terminal (or command prompt) and
create a new directory.

system_monitor_dashboard system_monitor_dashboard

Step 2: Set Up a Virtual Environment


Isolating your project dependencies is important. We’ll create a virtual environment to
keep our environment clean and predictable.

For Windows:

python -m venv venvvenv\\activate

2/15
For Linux/Mac:

python3 -m venv venv venv/bin/activate

Step 3: Install Required Libraries


We need to install the following Python packages:

dash: Web framework for building dashboards.


plotly: Used to create graphs and charts.
pandas: For handling data in a tabular format.
psutil: For monitoring system resources.

Install them by running:

pip install dash plotly pandas psutil

This will install all the libraries required to build our dashboard.

Building the Dashboard

Step 4: Writing the Code


Now we’ll create a Python script that gathers system statistics and displays them using a
dynamic, real-time dashboard.

1. The psutil library provides cross-platform access to system monitoring information.


It works on Windows, Linux, and macOS.

Create a new Python file called app.py:

app.py

Open app.py and paste the following code:

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

# Set up basic logging to debug


logging.basicConfig(level=logging.INFO)

# Initialize the Dash app


app = dash.Dash(__name__)

# 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
}

# Function to get system statistics (RAM, CPU, and Disk)


defget_system_stats():
try:
# Get memory stats
memory = psutil.virtual_memory()
ram = memory.percent

# Get CPU usage


cpu = psutil.cpu_percent(interval=1)

# Get Disk usage


disk = psutil.disk_usage('/').percent

# Return RAM, CPU, and Disk data


return {
'RAM Usage (%)': ram,
'CPU Usage (%)': cpu,
'Disk Usage (%)': disk
}

4/15
except Exception as e:
logging.error(f"Error fetching system stats: ")
return {}

# Determine whether to run in 'one' or 'multiple' mode based on command-line


argument
mode = sys.argv[1] iflen(sys.argv) > 1else'multiple'

if mode == 'one':
app.layout = html.Div([
html.H1('System Monitoring Dashboard (Combined Graph)'),

# Combined Line Chart for RAM, CPU, and Disk


dcc.Graph(id='combined-graph'),

# Interval for updating the dashboard every 5 seconds


dcc.Interval(
id='interval-component',
interval=5*1000, # 5000 milliseconds (5 seconds)
n_intervals=0
)
])

# 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 {}

# Log fetched data in the terminal


logging.info(f"Fetched data: ")

# 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)

# Create Combined Line Chart


combined_figure = {
'data': [
go.Scatter(
x=list(history['time']),
y=list(history['ram']),
mode='lines+markers',
name='RAM Usage (%)'
),
go.Scatter(
x=list(history['time']),
y=list(history['cpu']),
mode='lines+markers',
name='CPU Usage (%)'
),
go.Scatter(
x=list(history['time']),
y=list(history['disk']),
mode='lines+markers',
name='Disk Usage (%)'
)
],
'layout': go.Layout(
title='RAM, CPU, and Disk Usage Over Time',
xaxis=dict(title='Time', tickformat='%H:%M:%S'), # Format the
time
yaxis=dict(title='Percentage'),
)
}

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)'),

# RAM Usage Line Chart


dcc.Graph(id='ram-usage-graph'),

# CPU Usage Line Chart


dcc.Graph(id='cpu-usage-graph'),

6/15
# Disk Usage Line Chart
dcc.Graph(id='disk-usage-graph'),

# Interval for updating the dashboard every 5 seconds


dcc.Interval(
id='interval-component',
interval=5*1000, # 5000 milliseconds (5 seconds)
n_intervals=0
)
])

# 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 {}, {}, {}

# Log fetched data in the terminal


logging.info(f"Fetched data: ")

# 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)

# Create RAM Usage Line Chart


ram_figure = {
'data': [go.Scatter(
x=list(history['time']),
y=list(history['ram']),
mode='lines+markers',
name='RAM Usage (%)'
)],
'layout': go.Layout(
title='RAM Usage Over Time',
xaxis=dict(title='Time', tickformat='%H:%M:%S'), # Format the
time

7/15
yaxis=dict(title='Percentage'),
)
}

# Create CPU Usage Line Chart


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', tickformat='%H:%M:%S'), # Format the
time
yaxis=dict(title='Percentage'),
)
}

# Create Disk Usage Line Chart


disk_figure = {
'data': [go.Scatter(
x=list(history['time']),
y=list(history['disk']),
mode='lines+markers',
name='Disk Usage (%)'
)],
'layout': go.Layout(
title='Disk Usage Over Time',
xaxis=dict(title='Time', tickformat='%H:%M:%S'), # Format the
time
yaxis=dict(title='Percentage'),
)
}

return ram_figure, cpu_figure, disk_figure

__name__ == : app.run_server(debug=)

Step 5: Running the Dashboard


1. Ensure your virtual environment is activated.
2. Run the dashboard with the following command to show one chart with all three
metrics:

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:

You’ll see a dashboard that updates every 5 seconds, showing:

in percentage
in percentage
in percentage

Step 6: Additional Notes


works cross-platform, so the code will run on both Windows and Linux without
modification.
If you’re on a macOS system, all functions except disk usage should work. You
might need to adjust psutil.disk_usage('/') if you have a different filesystem
configuration.

Breakdown of Above Code:

1. Setting Up the Logging System


The logging configuration is initialized early in the script, allowing us to capture and print
important debugging information to the console.# Set up basic logging to debug

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.

2. Initializing the Dash Application


Dash is a powerful Python framework for building interactive web applications. The app is
initialized as follows:

= 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.

3. Setting Up History with Deques


Deques (double-ended queues) are used to store the last 20 data points for RAM, CPU,
Disk usage, and timestamps.

= { : deque(maxlen=20), : deque(maxlen=20), : deque(maxlen=20), :


deque(maxlen=20) }

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.

4. Fetching System Statistics


We use the psutil library to gather system data such as RAM, CPU, and disk usage.
The get_system_stats function is responsible for this:

defget_system_stats():
try:
# Get memory stats
memory = psutil.virtual_memory()
ram = memory.percent

# Get CPU usage


cpu = psutil.cpu_percent(interval=1)

# Get Disk usage


disk = psutil.disk_usage('/').percent

{ : ram, : cpu, : disk }


Exception e: logging.error() {}

RAM Usage: We call psutil.virtual_memory() to get memory information and extract


the percentage of RAM in use.

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.

5. Mode Selection: Single or Multiple Graphs


The dashboard can operate in two modes: either all data is combined in a single graph, or
each metric (RAM, CPU, and Disk) has its own graph. This is determined by checking the
command-line arguments:

= sys.argv[] if len(sys.argv) > else

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)'),

# Combined Line Chart for RAM, CPU, and Disk


dcc.Graph(id='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 {}

# Log fetched data in the terminal


logging.info(f"Fetched data: ")

# 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)

# Create Combined Line Chart


combined_figure = {
'data': [
go.Scatter(
x=list(history['time']),
y=list(history['ram']),
mode='lines+markers',
name='RAM Usage (%)'
),
go.Scatter(
x=list(history['time']),
y=list(history['cpu']),
mode='lines+markers',
name='CPU Usage (%)'
),
go.Scatter(
x=list(history['time']),
y=list(history['disk']),
mode='lines+markers',
name='Disk Usage (%)'
)
],
'layout': go.Layout(
title='RAM, CPU, and Disk Usage Over Time',
xaxis=dict(title='Time', tickformat='%H:%M:%S'), # Format the time
yaxis=dict(title='Percentage'),
)
}

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.

7. Creating the Layout and Callbacks for Multiple Graphs Mode


In multiple mode, the layout consists of three separate graphs (one for each metric):

else:
app.layout = html.Div([
html.H1('System Monitoring Dashboard (Separate Graphs)'),

# RAM Usage Line Chart


dcc.Graph(id='ram-usage-graph'),

# CPU Usage Line Chart


dcc.Graph(id='cpu-usage-graph'),

# Disk Usage Line Chart


dcc.Graph(id='disk-usage-graph'),

dcc.Interval( =, interval=5*1000,
n_intervals=0 ) ])

The callback in this mode updates each graph individually:

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)

# Create RAM, CPU, and Disk Usage Line Charts


ram_figure = {
'data': [go.Scatter(
x=list(history['time']),
y=list(history['ram']),
mode='lines+markers',
name='RAM Usage (%)'
)],
'layout': go.Layout(title='RAM Usage Over Time', xaxis=dict(title='Time'),
yaxis=dict(title='Percentage'))
}

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'))
}

ram_figure, cpu_figure, disk_figure

Each graph displays its own data set, pulled from the history deque and updated every
5 seconds.

8. Running the App


Finally, the Dash app is started using the app.run_server() function:

__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

You might also like