Source code for patcher.utils.logger

import logging
import os
import traceback
from logging import handlers
from typing import AnyStr, Optional

from click import echo, style

formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
logger_name = "patcher"
default_log_level = logging.INFO
log_roll_size = 1048576 * 100
log_backupCount = 10


[docs] def setup_logger( log_name: Optional[AnyStr] = logger_name, log_filename: Optional[AnyStr] = f"{logger_name}.log", log_level: Optional[int] = default_log_level, ) -> logging.Logger: """ Set up the main logger with rotating file handler. :param log_name: The name of the logger, defaults to 'patcher'. :type log_name: Optional[AnyStr] :param log_filename: The log file name, defaults to ``{log_name}.log``. :type log_filename: Optional[AnyStr] :param log_level: The logging level, defaults to logging.INFO. :type log_level: Optional[int] :return: The configured logger. :rtype: logging.Logger """ log_path = os.path.abspath( os.path.join(os.path.expanduser("~/Library/Application Support/Patcher"), "logs") ) if not os.path.isdir(log_path): os.makedirs(log_path) log_file = os.path.join(log_path, log_filename) handler = handlers.RotatingFileHandler( log_file, maxBytes=log_roll_size, backupCount=log_backupCount ) handler.setFormatter(formatter) logger = logging.getLogger(log_name) if logger.hasHandlers(): logger.handlers.clear() logger.addHandler(handler) logger.setLevel(log_level) return logger
[docs] def setup_child_logger( name_of_child: AnyStr, name_of_logger: Optional[AnyStr] = logger_name, debug: Optional[bool] = False, ) -> logging.Logger: """ Setup a child logger for a specified context. :param name_of_child: The name of the child logger. :type name_of_child: AnyStr :param name_of_logger: The name of the parent logger, defaults to 'patcher' :type name_of_logger: AnyStr :param debug: Whether to set the child logger level to DEBUG, defaults to False. :type debug: Optional[bool] :return: The configured child logger. :rtype: logging.Logger """ child_logger = logging.getLogger(name_of_logger).getChild(name_of_child) if debug: child_logger.setLevel(logging.DEBUG) else: child_logger.setLevel(logging.INFO) return child_logger
logthis = setup_logger(logger_name, f"{logger_name}.log")
[docs] def handle_traceback(exception: Exception): """ Write tracebacks to logs instead of to console for readability purposes. :param exception: The exception instance to log. :type exception: Exception """ full_traceback = traceback.format_exc() logthis.error(f"Exception occurred: {str(exception)}\nTraceback:\n{full_traceback}")
[docs] class LogMe: """ A wrapper class for logging with additional output to console using click. :param class_name: The name of the class for which the logger is being set up. :type class_name: AnyStr :param debug: Whether to set the child logger level to DEBUG, defaults to False. :type debug: Optional[bool] """ def __init__(self, class_name: AnyStr, debug: Optional[bool] = False): self.logger = setup_child_logger(class_name, logger_name, debug)
[docs] def is_debug_enabled(self) -> bool: """ Check if debug logging is enabled. :return: True if debug logging is enabled, False otherwise. :rtype: bool """ return self.logger.isEnabledFor(logging.DEBUG)
[docs] def debug(self, msg: AnyStr): """ Log a debug message and output to console if debug is enabled. :param msg: The debug message to log. :type msg: AnyStr """ self.logger.debug(msg) if self.is_debug_enabled(): debug_out = style(text=f"DEBUG: {msg.strip()}", fg="magenta", bold=False) echo(message=debug_out, err=False)
[docs] def info(self, msg: AnyStr): """ Log an info message and output to console. :param msg: The info message to log. :type msg: AnyStr """ self.logger.info(msg) if self.is_debug_enabled(): std_output = style(text=f"\rINFO: {msg.strip()}", fg="blue", bold=False) echo(message=std_output, err=False)
[docs] def warning(self, msg: AnyStr): """ Log a warning message and output to console. :param msg: The warning message to log. :type msg: AnyStr """ self.logger.warning(msg) if self.is_debug_enabled(): warn_out = style(text=f"\rWARNING: {msg.strip()}", fg="yellow", bold=True) echo(message=warn_out, err=False)
[docs] def error(self, msg: AnyStr): """ Log an error message and output to console. :param msg: The error message to log. :type msg: AnyStr """ self.logger.error(msg) err_out = style(text=f"\rERROR: {msg.strip()}", fg="red", bold=True) echo(message=err_out, err=True)