Skip to content

Commit 02f8edd

Browse files
chore: logger added and naming variable improved
1 parent cf00b00 commit 02f8edd

File tree

10 files changed

+253
-108
lines changed

10 files changed

+253
-108
lines changed

app.py

+55-24
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
from src import routes
77
from src.utils import get_system_info_for_db
88
from src.models import SystemInformation, ApplicationGeneralSettings
9-
from src.scripts.email_me import send_smpt_email
10-
from flask import current_app
9+
from sqlalchemy.exc import SQLAlchemyError
10+
from src.logger import logger
1111

1212
def register_routes():
1313
app.register_blueprint(routes.dashboard_bp)
@@ -20,34 +20,65 @@ def register_routes():
2020
app.register_blueprint(routes.speedtest_bp)
2121
app.register_blueprint(routes.process_bp)
2222

23+
2324
def log_system_info():
24-
with app.app_context(): # Ensure Flask app context is available
25-
general_settings = ApplicationGeneralSettings.query.first()
26-
is_logging_system_info = general_settings.is_logging_system_info
27-
print("Is logging system info: ", is_logging_system_info)
28-
if not is_logging_system_info:
29-
return
30-
while True:
31-
system_info = get_system_info_for_db()
32-
info = SystemInformation(
33-
cpu_percent=system_info["cpu_percent"],
34-
memory_percent=system_info["memory_percent"],
35-
battery_percent=system_info["battery_percent"],
36-
network_sent=system_info["network_sent"],
37-
network_received=system_info["network_received"],
38-
timestamp=datetime.datetime.now(),
39-
)
40-
print("Logging system information")
41-
db.session.add(info)
42-
db.session.commit() # Commit to save the data in the database
43-
time.sleep(60)
25+
"""
26+
Function to log system information at regular intervals if logging is enabled in the general settings.
27+
"""
28+
with app.app_context(): # Push app context for this thread
29+
try:
30+
# Fetch general settings once at the beginning
31+
general_settings = ApplicationGeneralSettings.query.first()
32+
is_logging_system_info = general_settings.is_logging_system_info if general_settings else False
33+
34+
logger.info("Is logging system info: %s", is_logging_system_info)
35+
if not is_logging_system_info:
36+
logger.warning("Logging is disabled in the settings.")
37+
return
38+
39+
while is_logging_system_info:
40+
logger.debug("Fetching and logging system information.")
41+
log_data()
42+
43+
# Sleep for 60 seconds before logging the next set of data
44+
time.sleep(2)
45+
46+
except KeyboardInterrupt:
47+
logger.info("Logging system info interrupted by user.")
48+
except Exception as e:
49+
logger.error(f"Error while logging system info: {e}", exc_info=True)
50+
51+
52+
def log_data():
53+
"""
54+
Function to log system information to the database.
55+
"""
56+
try:
57+
system_info = get_system_info_for_db()
58+
info = SystemInformation(
59+
cpu_percent=system_info["cpu_percent"],
60+
memory_percent=system_info["memory_percent"],
61+
battery_percent=system_info["battery_percent"],
62+
network_sent=system_info["network_sent"],
63+
network_received=system_info["network_received"],
64+
timestamp=datetime.datetime.now(),
65+
)
66+
db.session.add(info)
67+
db.session.commit()
68+
logger.info("System information logged successfully.")
69+
except SQLAlchemyError as db_err:
70+
logger.error(f"Database error: {db_err}")
71+
db.session.rollback() # Ensure DB rollback on failure
72+
except Exception as e:
73+
logger.error(f"Failed to log system info: {e}", exc_info=True)
74+
4475

4576
if __name__ == "__main__":
4677
register_routes()
4778

48-
# Start the memory-consuming program in a separate thread
79+
# Start the system logging thread
4980
memory_thread = threading.Thread(target=log_system_info, daemon=True)
5081
memory_thread.start()
5182

5283
# Run the Flask application
53-
app.run(host="0.0.0.0", port=5000)
84+
app.run(host="0.0.0.0", port=5000, debug=True)

src/logger.py

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import logging
2+
from logging.handlers import RotatingFileHandler
3+
import os
4+
5+
# Create a logs directory if it doesn't exist
6+
if not os.path.exists('logs'):
7+
os.makedirs('logs')
8+
9+
# Log Formatter with datetime, log level, and message
10+
formatter = logging.Formatter(
11+
'%(asctime)s - %(levelname)s - %(message)s',
12+
datefmt='%Y-%m-%d %H:%M:%S'
13+
)
14+
15+
# File handler for logging to a file
16+
file_handler = RotatingFileHandler(
17+
'logs/app_debug.log',
18+
maxBytes=10 * 1024 * 1024, # 10 MB per log file
19+
backupCount=5 # Keep up to 5 old log files
20+
)
21+
file_handler.setLevel(logging.DEBUG)
22+
file_handler.setFormatter(formatter)
23+
24+
# Set up the logger
25+
logger = logging.getLogger(__name__)
26+
logger.setLevel(logging.DEBUG) # Log everything (DEBUG, INFO, WARNING, etc.)
27+
logger.addHandler(file_handler)
28+
29+
# Optionally, add console output for real-time debugging (optional)
30+
console_handler = logging.StreamHandler()
31+
console_handler.setLevel(logging.INFO)
32+
console_handler.setFormatter(formatter)
33+
logger.addHandler(console_handler)

src/models/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from src.models.network_speed_test_result import NetworkSpeedTestResult
99
from src.models.system_information import SystemInformation
1010
from src.models.user_profile import UserProfile
11-
from src.models.ping import Website
11+
from src.models.monitored_website import MonitoredWebsite
1212
from flask_login import current_user
1313
from werkzeug.security import generate_password_hash
1414
import json

src/models/monitored_website.py

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from src.config import db
2+
3+
4+
class MonitoredWebsite(db.Model):
5+
id = db.Column(db.Integer, primary_key=True)
6+
name = db.Column(db.String(255), nullable=False)
7+
ping_interval = db.Column(db.Integer, nullable=False) # in seconds
8+
is_ping_active = db.Column(db.Boolean, default=True) # True: ping the site, False: do not ping
9+
ping_status = db.Column(db.String(50), nullable=True) # Stores 'UP' or 'DOWN'
10+
ping_status_code = db.Column(db.Integer, nullable=True)
11+
last_ping_time = db.Column(db.DateTime, nullable=True)
12+
email_alerts_enabled = db.Column(db.Boolean, default=False)
13+
14+
def __repr__(self):
15+
return f'<Website {self.name} - Ping Every {self.ping_interval}s>'

src/models/ping.py

-13
This file was deleted.

src/routes/ping.py

+43-28
Original file line numberDiff line numberDiff line change
@@ -2,75 +2,90 @@
22
from threading import Timer
33
from flask import render_template, request, redirect, url_for, blueprints, flash
44
from src.config import app, db
5-
from src.models.ping import Website
5+
from src.models.monitored_website import MonitoredWebsite
6+
from flask_login import login_required
67
import requests
78

89
ping_bp = blueprints.Blueprint('ping', __name__)
910

1011
# Route to view and add websites
11-
@app.route('/ping')
12-
def ping_website():
13-
websites = Website.query.all()
12+
@app.route('/monitor_websites')
13+
@login_required
14+
def monitor_websites():
15+
websites = MonitoredWebsite.query.all()
1416
return render_template('ping/ping.html', websites=websites)
1517

1618
# Route to add a website
17-
@app.route('/add_website', methods=['POST'])
19+
@app.route('/add_monitored_website', methods=['POST'])
20+
@login_required
1821
def add_website():
1922
name = request.form['name']
20-
ping_period = int(request.form['ping_period'])
21-
website = Website(name=name, ping_period=ping_period, is_ping=True)
23+
ping_interval = int(request.form['ping_interval'])
24+
email_alerts_enabled = request.form.get('email_alerts_enabled') == 'on'
25+
website = MonitoredWebsite(name=name, ping_interval=ping_interval, is_ping_active=True, email_alerts_enabled=email_alerts_enabled)
2226
db.session.add(website)
2327
db.session.commit()
24-
return redirect(url_for('ping_website'))
28+
return redirect(url_for('monitor_websites'))
2529

26-
@app.route('/remove_website/<int:website_id>', methods=['POST'])
30+
@app.route('/delete_monitored_website/<int:website_id>', methods=['POST'])
31+
@login_required
2732
def remove_website(website_id):
28-
website = Website.query.get_or_404(website_id)
33+
website = MonitoredWebsite.query.get_or_404(website_id)
2934
db.session.delete(website)
3035
db.session.commit()
3136
flash('Website removed successfully!', 'danger')
32-
return redirect(url_for('ping_website'))
37+
return redirect(url_for('monitor_websites'))
3338

34-
@app.route('/edit_website/<int:website_id>', methods=['GET', 'POST'])
39+
@app.route('/edit_monitored_website/<int:website_id>', methods=['GET', 'POST'])
3540
def edit_website(website_id):
36-
website = Website.query.get_or_404(website_id)
41+
website = MonitoredWebsite.query.get_or_404(website_id)
3742
if request.method == 'POST':
3843
website.name = request.form['name']
39-
website.ping_period = int(request.form['ping_period'])
44+
website.ping_interval = int(request.form['ping_interval'])
4045
db.session.commit()
4146
flash('Website updated successfully!', 'success')
42-
return redirect(url_for('ping_website'))
47+
return redirect(url_for('monitor_websites'))
4348
return render_template('ping/edit_website.html', website=website)
4449

4550
# Route to toggle pinging status
46-
@app.route('/toggle_ping/<int:website_id>')
51+
@app.route('/toggle_ping_status/<int:website_id>')
52+
@login_required
4753
def toggle_ping(website_id):
48-
website = Website.query.get_or_404(website_id)
49-
website.is_ping = not website.is_ping
54+
website = MonitoredWebsite.query.get_or_404(website_id)
55+
website.is_ping_active = not website.is_ping_active
5056
db.session.commit()
51-
return redirect(url_for('ping_website'))
57+
return redirect(url_for('monitor_websites'))
58+
59+
@app.route('/toggle_email_alerts/<int:website_id>')
60+
@login_required
61+
def toggle_emaail_alerts(website_id):
62+
website = MonitoredWebsite.query.get_or_404(website_id)
63+
website.email_alerts_enabled = not website.email_alerts_enabled
64+
db.session.commit()
65+
return redirect(url_for('monitor_websites'))
5266

5367
# Function to ping websites periodically
54-
def ping_websites():
68+
def start_website_monitoring():
5569
with app.app_context():
56-
websites = Website.query.filter_by(is_ping=True).all()
70+
websites = MonitoredWebsite.query.filter_by(is_ping_active=True).all()
5771
for website in websites:
5872
print(f'Pinging {website.name}...')
5973
try:
6074
response = requests.get(website.name, timeout=10)
61-
website.last_ping_timestamp = datetime.datetime.now()
75+
website.last_ping_time = datetime.datetime.now()
76+
website.ping_status_code = response.status_code
6277
if response.status_code == 200:
63-
website.last_status = 'UP'
78+
website.ping_status = 'UP'
6479
else:
65-
website.last_status = 'DOWN'
80+
website.ping_status = 'DOWN'
6681
except requests.RequestException:
67-
website.last_status = 'Something went wrong'
82+
website.ping_status = 'Something went wrong'
6883

6984
db.session.commit()
7085

7186
# Schedule next ping after the minimum interval period
72-
min_interval = min([w.ping_period for w in websites]) if websites else 60
73-
Timer(min_interval, ping_websites).start()
87+
min_interval = min([w.ping_interval for w in websites]) if websites else 60
88+
Timer(min_interval, monitor_websites).start()
7489

7590
# Start pinging periodically after server starts
76-
ping_websites()
91+
start_website_monitoring()

0 commit comments

Comments
 (0)