#!/usr/bin/env python3 # Standard library imports import logging import logging.config import logging.handlers import os import sys from traceback import print_exception import yaml # PyQt imports # Third party imports import stackprinter # type: ignore # App imports from config import Config class FunctionFilter(logging.Filter): """Filter to allow category-based logging to stderr.""" def __init__(self, module_functions: dict[str, list[str]]): super().__init__() self.modules: list[str] = [] self.functions: defaultdict[str, list[str]] = defaultdict(list) for module in module_functions.keys(): if module_functions[module]: for function in module_functions[module]: self.functions[module].append(function) else: self.modules.append(module) def filter(self, record: logging.LogRecord) -> bool: if not getattr(record, "levelname", None) == "DEBUG": # Only prcess DEBUG messages return False module = getattr(record, "module", None) if not module: # No module in record return False # Process if this is a module we're tracking if module in self.modules: return True # Process if this is a function we're tracking if getattr(record, "funcName", None) in self.functions[module]: return True return False class LevelTagFilter(logging.Filter): """Add leveltag""" def filter(self, record: logging.LogRecord) -> bool: # Extract the first character of the level name record.leveltag = record.levelname[0] # We never actually filter messages out, just add an extra field # to the LogRecord return True # Load YAML logging configuration with open("app/logging.yaml", "r") as f: config = yaml.safe_load(f) logging.config.dictConfig(config) # Get logger log = logging.getLogger(Config.LOG_NAME) def log_uncaught_exceptions(type_, value, traceback): from helpers import send_mail print("\033[1;31;47m") print_exception(type_, value, traceback) print("\033[1;37;40m") print( stackprinter.format( value, suppressed_paths=["/pypoetry/virtualenvs/"], style="darkbg" ) ) if os.environ["MM_ENV"] == "PRODUCTION": msg = stackprinter.format(value) send_mail( Config.ERRORS_TO, Config.ERRORS_FROM, "Exception (log_uncaught_exceptions) from musicmuster", msg, ) log.debug(msg) sys.excepthook = log_uncaught_exceptions