Source code for popsynth.utils.logging

import logging
import logging.handlers as handlers
import sys
from contextlib import contextmanager
from typing import Dict, Optional

import colorama
from colorama import Back, Fore, Style

from popsynth.utils.configuration import popsynth_config
from popsynth.utils.package_data import get_path_of_log_dir, get_path_of_log_file

colorama.deinit()
colorama.init(strip=False)
# set up the console logging


[docs]class ColoredFormatter(logging.Formatter): """ Colored log formatter. """
[docs] def __init__(self, *args, colors: Optional[Dict[str, str]] = None, **kwargs) -> None: """Initialize the formatter with specified format strings.""" super().__init__(*args, **kwargs) self.colors = colors if colors else {}
[docs] def format(self, record) -> str: """Format the specified record as text.""" record.color = self.colors.get(record.levelname, "") record.reset = Style.RESET_ALL return super().format(record)
[docs]class MyFilter(object):
[docs] def __init__(self, level): self.__level = level
[docs] def filter(self, logRecord): return logRecord.levelno != self.__level
# now create the developer handler that rotates every day and keeps # 10 days worth of backup popsynth_dev_log_handler = handlers.TimedRotatingFileHandler( get_path_of_log_file("dev.log"), when="D", interval=1, backupCount=10) # lots of info written out _dev_formatter = logging.Formatter( "%(asctime)s | %(name)s | %(levelname)s| %(funcName)s | %(lineno)d | %(message)s", datefmt="%Y-%m-%d %H:%M:%S", ) popsynth_dev_log_handler.setFormatter(_dev_formatter) popsynth_dev_log_handler.setLevel(logging.DEBUG) # now set up the usr log which will save the info popsynth_usr_log_handler = handlers.TimedRotatingFileHandler( get_path_of_log_file("usr.log"), when="D", interval=1, backupCount=10) popsynth_usr_log_handler.setLevel(popsynth_config["logging"]["file"]["level"]) # lots of info written out _usr_formatter = logging.Formatter("%(asctime)s | %(levelname)s | %(message)s", datefmt="%Y-%m-%d %H:%M:%S") popsynth_usr_log_handler.setFormatter(_usr_formatter) # now set up the console logger _console_formatter = ColoredFormatter( "{color} {levelname:8} {reset}| {color} {message} {reset}", style="{", datefmt="%Y-%m-%d %H:%M:%S", colors={ "DEBUG": Fore.CYAN, "INFO": Fore.GREEN + Style.BRIGHT, "WARNING": Fore.YELLOW + Style.DIM, "ERROR": Fore.RED + Style.BRIGHT, "CRITICAL": Fore.RED + Back.WHITE + Style.BRIGHT, }, ) popsynth_console_log_handler = logging.StreamHandler(sys.stdout) popsynth_console_log_handler.setFormatter(_console_formatter) popsynth_console_log_handler.setLevel( popsynth_config["logging"]["console"]["level"]) warning_filter = MyFilter(logging.WARNING)
[docs]class LoggingState(object):
[docs] def __init__( self, popsynth_usr_log_handler, popsynth_console_log_handler, ): """ A container to store the state of the logs. """ # attach the log handlers self.popsynth_usr_log_handler = popsynth_usr_log_handler self.popsynth_console_log_handler = popsynth_console_log_handler # store their current states self.popsynth_usr_log_handler_state = popsynth_usr_log_handler.level self.popsynth_console_log_handler_state = popsynth_console_log_handler.level
def _store_state(self): self.popsynth_usr_log_handler_state = popsynth_usr_log_handler.level self.popsynth_console_log_handler_state = popsynth_console_log_handler.level
[docs] def restore_last_state(self): self.popsynth_usr_log_handler.setLevel( self.popsynth_usr_log_handler_state) self.popsynth_console_log_handler.setLevel( self.popsynth_console_log_handler_state)
[docs] def silence_logs(self): # store the state self._store_state() # silence the logs self.popsynth_usr_log_handler.setLevel(logging.CRITICAL) self.popsynth_console_log_handler.setLevel(logging.CRITICAL)
[docs] def loud_logs(self): # store the state self._store_state() # silence the logs self.popsynth_usr_log_handler.setLevel(logging.INFO) self.popsynth_console_log_handler.setLevel(logging.INFO)
[docs] def debug_logs(self): # store the state self._store_state() # silence the logs self.popsynth_console_log_handler.setLevel(logging.DEBUG)
_log_state = LoggingState( popsynth_usr_log_handler, popsynth_console_log_handler, )
[docs]def silence_warnings(): """ Supress warning messages in console and file usr logs. """ popsynth_usr_log_handler.addFilter(warning_filter) popsynth_console_log_handler.addFilter(warning_filter)
[docs]def activate_warnings(): """ Supress warning messages in console and file usr logs. """ popsynth_usr_log_handler.removeFilter(warning_filter) popsynth_console_log_handler.removeFilter(warning_filter)
[docs]def update_logging_level(level): popsynth_console_log_handler.setLevel(level)
[docs]def silence_logs(): """ Turn off all logging. """ # handle dev logs independently popsynth_dev_log_handler.setLevel(logging.CRITICAL) _log_state.silence_logs()
[docs]def show_progress_bars(): popsynth_config.show_progress = True
[docs]def silence_progress_bars(): popsynth_config.show_progress = False
[docs]def quiet_mode(): """ Turn off all logging and progress bars. """ silence_progress_bars() # save state and silence silence_logs()
[docs]def loud_mode(): """ Turn on all progress bars and logging. """ show_progress_bars() # save state and make loud _log_state.loud_logs()
[docs]def activate_logs(): """ Re-activate silenced logs. """ # handle dev logs independently popsynth_dev_log_handler.setLevel(logging.DEBUG) _log_state.restore_last_state()
[docs]def debug_mode(): """ Activate debug in the console. """ # store state and switch console to debug _log_state.debug_logs()
[docs]@contextmanager def silence_console_log(): current_console_logging_level = popsynth_console_log_handler.level current_usr_logging_level = popsynth_usr_log_handler.level popsynth_console_log_handler.setLevel(logging.ERROR) popsynth_usr_log_handler.setLevel(logging.ERROR) try: yield finally: popsynth_console_log_handler.setLevel(current_console_logging_level) popsynth_usr_log_handler.setLevel(current_usr_logging_level)
[docs]def setup_logger(name): """ Set up a new logger. :param name: Name of the logger """ # A logger with name name will be created # and then add it to the print stream log = logging.getLogger(name) # this must be set to allow debug messages through log.setLevel(logging.DEBUG) # add the handlers if popsynth_config["logging"]["debug"]: log.addHandler(popsynth_dev_log_handler) if popsynth_config["logging"]["console"]["on"]: log.addHandler(popsynth_console_log_handler) if popsynth_config["logging"]["file"]["on"]: log.addHandler(popsynth_usr_log_handler) # we do not want to duplicate teh messages in the parents log.propagate = False return log