#!/usr/bin/python3 import logging import logging.handlers import sys import traceback from config import Config class LevelTagFilter(logging.Filter): """Add leveltag""" def filter(self, record: logging.LogRecord): # Extract the first character of the level name record.leveltag = record.levelname[0] # We never actually filter messages out, just abuse filtering to add an # extra field to the LogRecord return True class DebugStdoutFilter(logging.Filter): """Filter debug messages sent to stdout""" def filter(self, record: logging.LogRecord): if record.levelno != logging.DEBUG: return True if record.module in Config.DEBUG_MODULES: return True if record.funcName in Config.DEBUG_FUNCTIONS: return True return False log = logging.getLogger(Config.LOG_NAME) log.setLevel(logging.DEBUG) # stderr stderr = logging.StreamHandler() stderr.setLevel(Config.LOG_LEVEL_STDERR) # syslog syslog = logging.handlers.SysLogHandler(address='/dev/log') syslog.setLevel(Config.LOG_LEVEL_SYSLOG) # Filter local_filter = LevelTagFilter() debug_filter = DebugStdoutFilter() syslog.addFilter(local_filter) stderr.addFilter(local_filter) stderr.addFilter(debug_filter) # create formatter and add it to the handlers stderr_fmt = logging.Formatter('[%(asctime)s] %(leveltag)s: %(message)s', datefmt='%H:%M:%S') syslog_fmt = logging.Formatter( '[%(name)s] %(module)s.%(funcName)s - %(leveltag)s: %(message)s' ) stderr.setFormatter(stderr_fmt) syslog.setFormatter(syslog_fmt) # add the handlers to the log log.addHandler(stderr) log.addHandler(syslog) def log_uncaught_exceptions(ex_cls, ex, tb): print("\033[1;31;47m") logging.critical(''.join(traceback.format_tb(tb))) print("\033[1;37;40m") logging.critical('{0}: {1}'.format(ex_cls, ex)) sys.excepthook = log_uncaught_exceptions