Update logging and error handling
* Move from basic logging to more detailed logging with a log file. * Improve error handling in several functions. * Modify the way log messages are displayed.
This commit is contained in:
parent
ef00f112f3
commit
89994c1f0a
|
@ -1,4 +1,5 @@
|
|||
config_local.toml
|
||||
status
|
||||
alert_history
|
||||
log
|
||||
__pycache__
|
||||
|
|
|
@ -12,25 +12,23 @@ from pathlib import Path
|
|||
import argparse, textwrap, logging
|
||||
from alert_processor import AlertProcessor
|
||||
|
||||
def setup_logger(loglevel):
|
||||
"""Setup basic logging."""
|
||||
loglevel = getattr(logging, loglevel.upper(), None)
|
||||
|
||||
if not isinstance(loglevel, int):
|
||||
raise ValueError('Invalid log level: %s' % loglevel)
|
||||
|
||||
logging.basicConfig(filename='app.log', filemode='w', format='%(name)s - %(levelname)s - %(message)s')
|
||||
#Setup basic logging.
|
||||
log_format='[%(levelname)s] %(asctime)s %(message)s'
|
||||
logging.basicConfig(format=log_format, level=logging.INFO)
|
||||
logger = logging.getLogger()
|
||||
logger.setLevel(loglevel)
|
||||
file_handler = logging.FileHandler('log', mode='a')
|
||||
formatter = logging.Formatter(log_format)
|
||||
file_handler.setFormatter(formatter)
|
||||
logger.addHandler(file_handler)
|
||||
|
||||
def parse_args():
|
||||
"""Parse command line arguments."""
|
||||
parser = argparse.ArgumentParser(description="A simple calendar alerting daemon written in Python")
|
||||
parser.add_argument('--config', type=str, help='Path to config file. Must be .toml')
|
||||
parser.add_argument('--loglevel', choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'], default='INFO', help='Set the logging level')
|
||||
parser.add_argument('--loglevel', choices=['info', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'], default='INFO', help='Set the logging level')
|
||||
args = parser.parse_args()
|
||||
if args.config is None:
|
||||
logging.error("No config file provided. Please use --config path_to_config.toml")
|
||||
logger.error("No config file provided. Please use --config path_to_config.toml")
|
||||
sys.exit(1)
|
||||
return args
|
||||
|
||||
|
@ -38,14 +36,14 @@ def read_file(filename):
|
|||
try:
|
||||
return Path(filename).read_text()
|
||||
except FileNotFoundError as e:
|
||||
logging.error("Error: The specified file does not exist.")
|
||||
logger.error("Error: The specified file does not exist.")
|
||||
sys.exit(1)
|
||||
|
||||
def parse_toml(content):
|
||||
try:
|
||||
return toml.loads(content)
|
||||
except Exception as e:
|
||||
logging.error("Error: Failed to parse TOML file.")
|
||||
logger.error("Error: Failed to parse TOML file.")
|
||||
sys.exit(1)
|
||||
|
||||
def calculate_event_hash(event):
|
||||
|
@ -68,44 +66,44 @@ class FileChangeHandler(FileSystemEventHandler):
|
|||
self.event_list = event_list
|
||||
|
||||
def on_modified(self, event):
|
||||
logging.debug(f"File modified: {event.src_path}")
|
||||
logger.info(f"File modified: {event.src_path}")
|
||||
if not event.is_directory:
|
||||
try:
|
||||
with open(event.src_path, 'r') as f:
|
||||
cal_str = f.read()
|
||||
except Exception as e:
|
||||
logging.error(f"Not a valid file: {event.src_path}. Error: {e}")
|
||||
logger.error(f"Not a valid file: {event.src_path}. Error: {e}")
|
||||
return
|
||||
|
||||
try:
|
||||
event_dict = self.calendar_parser.parse_calendar(cal_str) # Use the instance to call parse_calendar method
|
||||
except Exception as e:
|
||||
logging.error(f"Failed to parse calendar event at: {event.src_path}. Error: {e}")
|
||||
logger.error(f"Failed to parse calendar event at: {event.src_path}. Error: {e}")
|
||||
return
|
||||
|
||||
self.handle_modified(old_event=None, event_dict=event_dict)
|
||||
|
||||
def on_deleted(self, event):
|
||||
logging.debug(f"File deleted: {event.src_path}")
|
||||
logger.info(f"File deleted: {event.src_path}")
|
||||
if not event.is_directory:
|
||||
uid = os.path.splitext(os.path.basename(event.src_path))[0] # Get the UID from the file path without extension
|
||||
|
||||
self.handle_modified(old_event=None, event_dict={"uid": uid}, remove=True)
|
||||
|
||||
def on_created(self, event):
|
||||
logging.debug(f"File created: {event.src_path}")
|
||||
logger.info(f"File created: {event.src_path}")
|
||||
if not event.is_directory:
|
||||
try:
|
||||
with open(event.src_path, 'r') as f:
|
||||
cal_str = f.read()
|
||||
except Exception as e:
|
||||
logging.error(f"Not a valid file: {event.src_path}. Error: {e}")
|
||||
logger.error(f"Not a valid file: {event.src_path}. Error: {e}")
|
||||
return
|
||||
|
||||
try:
|
||||
event_dict = self.calendar_parser.parse_calendar(cal_str) # Use the instance to call parse_calendar method
|
||||
except Exception as e:
|
||||
logging.error(f"Failed to parse calendar event at: {event.src_path}. Error: {e}")
|
||||
logger.error(f"Failed to parse calendar event at: {event.src_path}. Error: {e}")
|
||||
return
|
||||
|
||||
self.handle_modified(old_event=None, event_dict=event_dict)
|
||||
|
@ -118,7 +116,7 @@ class FileChangeHandler(FileSystemEventHandler):
|
|||
|
||||
new_hash = calculate_event_hash(event_dict)
|
||||
if new_hash != old_hash:
|
||||
logging.debug(f"Event with UID {old_event['uid']} has been modified or deleted")
|
||||
logger.info(f"Event with UID {old_event['uid']} has been modified or deleted")
|
||||
self.event_list[i] = event_dict
|
||||
break
|
||||
else:
|
||||
|
@ -126,7 +124,7 @@ class FileChangeHandler(FileSystemEventHandler):
|
|||
else: # If remove is True, remove the event from the list
|
||||
for i, old_event in enumerate(self.event_list):
|
||||
if old_event["uid"] == event_dict["uid"]:
|
||||
logging.debug(f"Event with UID {old_event['uid']} has been deleted")
|
||||
logger.info(f"Event with UID {old_event['uid']} has been deleted")
|
||||
|
||||
del self.event_list[i]
|
||||
break
|
||||
|
@ -336,12 +334,12 @@ def process_alert(current_time, next_alert, next_event, event, config):
|
|||
"""
|
||||
if current_time >= next_alert and current_time < next_alert + dt.timedelta(seconds=15):
|
||||
if len(event["alert_history"]) == 0:
|
||||
logging.debug(f"First alert for '{event['summary']}' detected")
|
||||
logger.info(f"First alert for '{event['summary']}' detected")
|
||||
event["alert_history"] = [{"timestamp_alert_triggered": current_time, "alert_defintition_time": next_alert}]
|
||||
elif next_alert in [i["alert_defintition_time"] for i in event["alert_history"]]:
|
||||
return
|
||||
else:
|
||||
logging.debug(f"Posting alert for {event['summary']}!")
|
||||
logger.info(f"Posting alert for {event['summary']}!")
|
||||
event["alert_history"].append({"timestamp_alert_triggered": current_time, "alert_defintition_time": next_alert})
|
||||
try:
|
||||
processor = AlertProcessor(config)
|
||||
|
@ -376,7 +374,7 @@ def main():
|
|||
try:
|
||||
event_dict = calendar_parser.parse_calendar(cal_str)
|
||||
except Exception:
|
||||
logging.error(f"Error parsing event, skipping. {file}")
|
||||
logger.error(f"Error parsing event, skipping. {file}")
|
||||
continue
|
||||
event_list.append(event_dict)
|
||||
|
||||
|
|
|
@ -8,7 +8,8 @@ Type=simple
|
|||
Restart=always
|
||||
RestartSec=1
|
||||
User=root
|
||||
ExecStart=/opt/remindme_caldav/.venv/bin/python3 /opt/remindme_caldav/remindme_caldav.py --config /etc/remindme_caldav/config.toml
|
||||
ExecStart=/opt/remindme_caldav/.venv/bin/python3 -u /opt/remindme_caldav/remindme_caldav.py --config /etc/remindme_caldav/config.toml
|
||||
Environment="PYTHONUNBUFFERED=1"
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
|
Loading…
Reference in New Issue