If the default log level for stderr is greater than DEBUG, DEBUG message won't be shown. The DEBUG(msg) function now takes an optional Boolean second parameter. If that is True, the DEBUG message is always sent to stderr.
109 lines
2.2 KiB
Python
109 lines
2.2 KiB
Python
#!/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):
|
|
# 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
|
|
|
|
|
|
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
|
|
filter = LevelTagFilter()
|
|
syslog.addFilter(filter)
|
|
stderr.addFilter(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] %(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
|
|
|
|
|
|
def DEBUG(msg, force_stderr=False):
|
|
"""
|
|
Outupt a log message at level DEBUG. If force_stderr is True,
|
|
output this message to stderr regardless of default stderr level
|
|
setting.
|
|
"""
|
|
|
|
if force_stderr:
|
|
old_level = stderr.level
|
|
stderr.setLevel(logging.DEBUG)
|
|
log.debug(msg)
|
|
stderr.setLevel(old_level)
|
|
else:
|
|
log.debug(msg)
|
|
|
|
|
|
def EXCEPTION(msg):
|
|
log.exception(msg, exc_info=True, stack_info=True)
|
|
|
|
|
|
def ERROR(msg):
|
|
log.error(msg)
|
|
|
|
|
|
def INFO(msg):
|
|
log.info(msg)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
DEBUG("hi debug")
|
|
ERROR("hi error")
|
|
INFO("hi info")
|
|
EXCEPTION("hi exception")
|
|
|
|
def f():
|
|
return g()
|
|
|
|
def g():
|
|
return h()
|
|
|
|
def h():
|
|
return i()
|
|
|
|
def i():
|
|
1 / 0
|
|
|
|
f()
|