diff --git a/app/logger.py b/app/logger.py new file mode 100644 index 0000000..81d7cd0 --- /dev/null +++ b/app/logger.py @@ -0,0 +1,88 @@ +"""This module contains the logging module.""" +from typing import Union +from pathlib import Path +from datetime import datetime +import sys + + +class Logger: + """A logger class that logs, ya get the point.""" + + LOG_LEVELS = [ + "debug", + "info", + "warning", + "error", + "critical", + ] + """The log levels' names. + + When used as arguments, the counting starts at 1 + instead of 0. + """ + + def __init__( + self, + log_file: Union[Path, str] = None, + append: bool = True, + stdout: bool = True, + log_level: int = 3, + ): + """Initialize a new Logger object. + + Args: + log_file: path to a log file. If any of the folders within the log + file's path don't exist, they will get created. If no value is + specified, no log file is created. + append: wether or not to append to the existing file or overwrite + it. If False, the original file gets deleted during init. + stdout: wether or not to log to stdout as well + log_level: the minimum level to log + """ + self.log_file = Path(log_file) if log_file else None + self.stdout = stdout + self.log_level = log_level + + # Remove the original log file + if not append: + self.log_file.unlink(missing_ok=True) + + def log(self, level: int, message: str): + """Log a message with a specific level. + + Args: + level: log level (index in the LOG_LEVELS variable) + message: the message to log + """ + if level < self.log_level: + return + + level_name = self.LOG_LEVELS[level - 1].upper() + timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + log_message = f"[{timestamp}][{level_name}]{message}\n" + + if self.log_file: + self.log_file.write_text(log_message) + + if self.stdout: + sys.stdout.write(log_message) + + def debug(self, message: str): + """Log a debug message.""" + self.log(1, message) + + def info(self, message: str): + """Log an info message.""" + self.log(2, message) + + def warning(self, message: str): + """Log a warning message.""" + self.log(3, message) + + def error(self, message: str): + """Log an error message.""" + self.log(4, message) + + def critical(self, message: str): + """Log a critical message.""" + self.log(5, message)