Skip to content

Commit 5faa56c

Browse files
chore: SystemInfo added in db, screenshot added
1 parent be8fb7e commit 5faa56c

14 files changed

Lines changed: 116 additions & 45 deletions

File tree

README.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# SystemDashboard
22

3-
System Dashboard is a Flask app designed to monitor server stats such as CPU, Memory, Disk, and Network. It also provides real-time monitoring capabilities.
3+
System Dashboard is a Flask app designed to monitor server stats such as CPU, Memory, Disk, and Network. It also provides real-time monitoring capabilities which can be useful for system administrators, developers, and DevOps engineers to keep track of their server's performance and troubleshoot issues. The app uses the `psutil` library to retrieve system stats and the `speedtest-cli` library to perform a network speed test.
44

55
## Installation
66

@@ -34,6 +34,28 @@ http://localhost:5000
3434
- Check the network speed of the server using a speed test.
3535
- Rate limit the speed test to prevent abuse.
3636

37+
## Product Screenshots
38+
39+
### HomePage
40+
41+
![HomePage](/static/images/dashboard.png)
42+
43+
### CPU Stats
44+
45+
![CPU Stats](/static/images/cpu.png)
46+
47+
### Memory Stats
48+
49+
![Memory Stats](/static/images/memory.png)
50+
51+
### Disk Stats
52+
53+
![Disk Stats](/static/images/disk.png)
54+
55+
### Speed Test
56+
57+
![Speed Test](/static/images/speedtest.png)
58+
3759
## Why not use a Docker image?
3860

3961
A Docker image has not been created for this project because it requires access to the host machine in order to retrieve server stats. Therefore, it is not possible to obtain server stats from within a Docker container.

app.py

Lines changed: 76 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,27 @@ class DashoardSettings(db.Model):
3535
def __repr__(self):
3636
return f'<DashboardSettings {self.speedtest_cooldown}, {self.timezone}, {self.number_of_speedtests}>'
3737

38+
class SystemInfo(db.Model):
39+
id = db.Column(db.Integer, primary_key=True)
40+
username = db.Column(db.String(50))
41+
cpu_percent = db.Column(db.Float)
42+
memory_percent = db.Column(db.Float)
43+
disk_usage = db.Column(db.Float)
44+
battery_percent = db.Column(db.Float)
45+
cpu_core = db.Column(db.Integer)
46+
boot_time = db.Column(db.String(50))
47+
network_sent = db.Column(db.Float)
48+
network_received = db.Column(db.Float)
49+
process_count = db.Column(db.Integer)
50+
swap_memory = db.Column(db.Float)
51+
uptime = db.Column(db.String(50))
52+
ipv4_connections = db.Column(db.String(50))
53+
dashboard_memory_usage = db.Column(db.String(50))
54+
timestamp = db.Column(db.DateTime, default=datetime.datetime.now())
55+
56+
def __repr__(self):
57+
return f'<SystemInfo {self.username}, {self.cpu_percent}, {self.memory_percent}, {self.disk_usage}, {self.battery_percent}, {self.cpu_core}, {self.boot_time}, {self.network_sent}, {self.network_received}, {self.process_count}, {self.swap_memory}, {self.uptime}, {self.ipv4_connections}, {self.ipv6_connections}, {self.dashboard_memory_usage}>'
58+
3859
# initialize the database
3960
with app.app_context():
4061
db.create_all()
@@ -80,37 +101,16 @@ def run_speedtest():
80101
def datetimeformat(value, format='%Y-%m-%d %H:%M:%S'):
81102
return value.strftime(format)
82103

83-
@app.route('/speedtest')
84-
def speedtest():
85-
settings = DashoardSettings.query.first()
86-
SPEEDTEST_COOLDOWN_IN_HOURS = settings.speedtest_cooldown
87-
NUMBER_OF_SPEEDTESTS = settings.number_of_speedtests
88-
n_hour_ago = datetime.datetime.now() - datetime.timedelta(hours=SPEEDTEST_COOLDOWN_IN_HOURS)
89-
recent_results = SpeedTestResult.query.filter(SpeedTestResult.timestamp > n_hour_ago).all()
90-
91-
if len(recent_results) < NUMBER_OF_SPEEDTESTS:
92-
speedtest_result = run_speedtest()
93-
if speedtest_result['status'] == "Error":
94-
return render_template('error/speedtest_error.html', error=speedtest_result['message'])
95104

96-
if speedtest_result:
97-
new_result = SpeedTestResult(
98-
download_speed=speedtest_result['download_speed'],
99-
upload_speed=speedtest_result['upload_speed'],
100-
ping=speedtest_result['ping']
101-
)
102-
db.session.add(new_result)
103-
db.session.commit()
104-
return render_template('speedtest_result.html', speedtest_result=speedtest_result, source="Actual Test")
105-
else:
106-
latest_result = recent_results[-1]
107-
next_test_time = latest_result.timestamp + datetime.timedelta(hours=SPEEDTEST_COOLDOWN_IN_HOURS)
108-
remaining_time_for_next_test = round((next_test_time - datetime.datetime.now()).total_seconds() / 60)
109-
return render_template('speedtest_result.html',
110-
speedtest_result=latest_result,
111-
source="Database",
112-
next_test_time=next_test_time,
113-
remaining_time_for_next_test=remaining_time_for_next_test)
105+
def get_flask_memory_usage():
106+
"""
107+
Returns the memory usage of the current Flask application in MB.
108+
"""
109+
pid = os.getpid()
110+
process = psutil.Process(pid)
111+
memory_info = process.memory_info()
112+
memory_in_mb = memory_info.rss / (1024 ** 2)
113+
return f"{round(memory_in_mb)} MB"
114114

115115
def get_system_info():
116116
print("Getting system information...")
@@ -129,8 +129,12 @@ def get_system_info():
129129
'swap_memory': psutil.swap_memory().percent,
130130
'uptime': change_up_time_format(datetime.datetime.now() - datetime.datetime.fromtimestamp(psutil.boot_time())),
131131
'ipv4_connections': ipv4_dict,
132-
'ipv6_connections': ipv6_dict
132+
'dashboard_memory_usage': get_flask_memory_usage(),
133+
'timestamp': datetime.datetime.now()
133134
}
135+
with app.app_context():
136+
db.session.add(SystemInfo(**info))
137+
db.session.commit()
134138
return info
135139

136140
def get_established_connections():
@@ -150,13 +154,16 @@ def get_established_connections():
150154

151155
@app.route('/')
152156
def dashboard():
157+
results = {}
153158
settings = DashoardSettings.query.first()
154159
SPEEDTEST_COOLDOWN_IN_HOURS = settings.speedtest_cooldown
155160
system_info = get_system_info()
161+
156162
# Fetch the last speedtest result
157163
n_hour_ago = datetime.datetime.now() - datetime.timedelta(hours=SPEEDTEST_COOLDOWN_IN_HOURS)
158164
recent_results = SpeedTestResult.query.filter(SpeedTestResult.timestamp > n_hour_ago).all()
159165
last_timestamp = datetimeformat(recent_results[-1].timestamp) if recent_results else None
166+
160167
if recent_results:
161168
# Display the most recent result from the database
162169
latest_result = recent_results[-1]
@@ -175,20 +182,14 @@ def dashboard():
175182
source = None
176183
show_prompt = True
177184
remaining_time_for_next_test = None
178-
185+
179186
return render_template('dashboard.html', system_info=system_info,
180187
speedtest_result=speedtest_result,
181188
source=source,
182189
last_timestamp=last_timestamp,
183190
next_test_time=remaining_time_for_next_test,
184191
show_prompt=show_prompt)
185192

186-
@app.route('/cpu_usage')
187-
def cpu_usage():
188-
cpu_usage = psutil.cpu_percent(interval=1, percpu=True)
189-
return render_template('cpu_usage.html', cpu_usage=cpu_usage)
190-
191-
192193
@app.route('/settings', methods=['GET', 'POST'])
193194
def settings():
194195
# Fetch the settings from the database and update them
@@ -202,6 +203,43 @@ def settings():
202203
flash('Settings updated successfully!', 'success')
203204
return render_template('settings.html', settings=settings)
204205

206+
@app.route('/speedtest')
207+
def speedtest():
208+
settings = DashoardSettings.query.first()
209+
SPEEDTEST_COOLDOWN_IN_HOURS = settings.speedtest_cooldown
210+
NUMBER_OF_SPEEDTESTS = settings.number_of_speedtests
211+
n_hour_ago = datetime.datetime.now() - datetime.timedelta(hours=SPEEDTEST_COOLDOWN_IN_HOURS)
212+
recent_results = SpeedTestResult.query.filter(SpeedTestResult.timestamp > n_hour_ago).all()
213+
214+
if len(recent_results) < NUMBER_OF_SPEEDTESTS:
215+
speedtest_result = run_speedtest()
216+
if speedtest_result['status'] == "Error":
217+
return render_template('error/speedtest_error.html', error=speedtest_result['message'])
218+
219+
if speedtest_result:
220+
new_result = SpeedTestResult(
221+
download_speed=speedtest_result['download_speed'],
222+
upload_speed=speedtest_result['upload_speed'],
223+
ping=speedtest_result['ping']
224+
)
225+
db.session.add(new_result)
226+
db.session.commit()
227+
return render_template('speedtest_result.html', speedtest_result=speedtest_result, source="Actual Test")
228+
else:
229+
latest_result = recent_results[-1]
230+
next_test_time = latest_result.timestamp + datetime.timedelta(hours=SPEEDTEST_COOLDOWN_IN_HOURS)
231+
remaining_time_for_next_test = round((next_test_time - datetime.datetime.now()).total_seconds() / 60)
232+
return render_template('speedtest_result.html',
233+
speedtest_result=latest_result,
234+
source="Database",
235+
next_test_time=next_test_time,
236+
remaining_time_for_next_test=remaining_time_for_next_test)
237+
238+
@app.route('/cpu_usage')
239+
def cpu_usage():
240+
cpu_usage = psutil.cpu_percent(interval=1, percpu=True)
241+
return render_template('cpu_usage.html', cpu_usage=cpu_usage)
242+
205243
@app.route('/memory_usage')
206244
def memory_usage():
207245
memory_info = {

static/css/style.css

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919
--color-cpu-usage: #ffc107; /* Yellow for CPU usage */
2020
--color-memory: #6f42c1; /* Purple for memory */
2121
--color-disk: #6711e9; /* Gray for disk */
22-
--color-uptime: #17a2b8; /* Cyan for uptime */
23-
--color-network: #11eeee; /* Bright blue for network */
24-
--color-speedtest: #c9ef4b; /* Bright blue for speedtest */
22+
--color-uptime: #042b31; /* Cyan for uptime */
23+
--color-network: #20053d; /* Bright blue for network */
24+
--color-speedtest: #253003; /* Bright blue for speedtest */
2525
--color-battery: #007bff; /* Bright blue for battery */
2626

2727
/* shadow colors */
@@ -37,7 +37,7 @@
3737

3838
/* General Styles */
3939
body {
40-
font-family: 'Arial', sans-serif;
40+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; /* Default font stack */
4141
color: #333;
4242
background-size: cover; /* Ensure the image covers the entire background */
4343
background-repeat: no-repeat; /* Prevent the image from repeating */

static/images/background.jpg

-442 KB
Binary file not shown.

static/images/cpu.png

36.7 KB
Loading

static/images/dashboard.png

135 KB
Loading

static/images/disk.png

46.4 KB
Loading

static/images/memory.png

44.1 KB
Loading

static/images/speedtest.png

37 KB
Loading

templates/dasbhboard_comp/boot_time.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<div class="col-md-6 mb-4">
1+
<div class="col-md-6 col-lg-4 mb-4">
22
<div class="card bg-boot">
33
<div class="card-body">
44
<h5 class="card-title">Boot Time <i class="fas fa-clock"></i></h5>

0 commit comments

Comments
 (0)