#!/usr/bin/python3 import logging import logging.handlers import stackprinter 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): # Exceptions are logged at ERROR level if record.levelno in [logging.DEBUG, logging.ERROR]: 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) class VerboseExceptionFormatter(logging.Formatter): def formatException(self, exc_info): msg = stackprinter.format(exc_info) lines = msg.split('\n') lines_indented = [" ┆ " + line + "\n" for line in lines] msg_indented = "".join(lines_indented) return msg_indented stderr_fmt = '[%(asctime)s] %(leveltag)s: %(message)s' stderr_formatter = VerboseExceptionFormatter(stderr_fmt, datefmt='%H:%M:%S') stderr.setFormatter(stderr_formatter) syslog_fmt = '[%(name)s] %(module)s.%(funcName)s - %(leveltag)s: %(message)s' syslog_formatter = VerboseExceptionFormatter(syslog_fmt) syslog.setFormatter(syslog_formatter) # add the handlers to the log log.addHandler(stderr) log.addHandler(syslog)