import os import logging class ColoredFormatter(logging.Formatter): MAPPING = { 'DEBUG': 37, # white 'INFO': 36, # cyan 'WARNING': 33, # yellow 'ERROR': 31, # red 'CRITICAL': 41, # white on red bg } PREFIX = '\033[' SUFFIX = '\033[0m' def __init__(self, patern): logging.Formatter.__init__(self, patern) def format(self, record): seq = self.MAPPING.get(record.levelname, 37) # default white record.levelname = ('{0}{1}m{2}{3}') \ .format(self.PREFIX, seq, record.levelname, self.SUFFIX) return logging.Formatter.format(self, record) class BookLogger: def __init__(self, name, book_id, main_logger=None, filemode='w+', logging_level=logging.INFO): """ Method for Logger configuration. Logger will write to file. :param name: name of the Logger. :param attr_name: name of attribute that will be added to self. :param filename: name of the log file. :param filemode: mode of opening log file. :param logging_level: logging level: 10 - debug, 20 - info, 30 - warning, 40 - error, 50 - critical. :param logging_format: format of record in log file. """ self.main_logger = main_logger self.logger = logging.getLogger(name) folder_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) folder_path = os.path.dirname(folder_path) filename = f'logs/{book_id}_log.log' file_path = os.path.join(folder_path, filename) file_handler = logging.FileHandler(file_path, mode=filemode) file_format = ColoredFormatter('%(asctime)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)') file_handler.setFormatter(file_format) self.logger.addHandler(file_handler) self.logger.setLevel(logging_level) def log(self, message, logging_level=20): """ Method for logging. :param message: body of the message :param logging_level: level of logging """ self.logger.log(msg=message, level=logging_level) def log_error_to_main_log(self, message=''): """ Method for logging error to main log file. """ if self.main_logger: if not message: message = f'Error in book conversion. Check log file.' self.main_logger.error(message) class BookStatusWrapper: def __init__(self, access, logger_object, book_id=0): self.access = access self.logger_object = logger_object self.book_id = book_id def set_processing(self): try: if self.access: self.access.update_status(self.book_id, self.access.PROCESS) self.logger_object.log(f'Status has been updated to [PROCESS].') except Exception as exc: self.logger_object.log("Can't update status of the book [PROCESS].", logging.ERROR) self.logger_object.log_error_to_main_log() raise exc def set_generating(self): try: if self.access: self.access.update_status(self.book_id, self.access.GENERATE) self.logger_object.log(f'Status has been updated to [GENERATE].') except Exception as exc: self.logger_object.log("Can't update status of the book [GENERATE].", logging.ERROR) self.logger_object.log_error_to_main_log() raise exc def set_error(self): try: if self.access: self.access.update_status(self.book_id, self.access.ERROR) self.logger_object.log(f'Status has been updated to [ERROR].') except Exception as exc: self.logger_object.log("Can't update status of the book [ERROR].", logging.ERROR) self.logger_object.log_error_to_main_log() raise exc