Add log level doesn't work with reporting file path
When I add a new log level with add_logging_level
and then add a custom formatter to this to report the file path with %(pathname)s
, it reports the file name as being inside the haggis module, not within the file of interest:
MWE:
#!/usr/bin/env python3
"""
Some wrapping around the default logging module.
"""
import logging
import sys
from haggis.logs import add_logging_level
from termcolor import colored
add_logging_level('TRACE', logging.DEBUG - 5)
add_logging_level('PRINT', logging.WARNING - 5)
class MyFormatter(logging.Formatter):
"""A nice formatter for logging messages."""
line_formatting = f" {colored('(%(pathname)s:%(lineno)d)', 'light_grey')}"
timestamp_formatting = f"{colored('[%(asctime)s]: ', 'green')}"
trace_format = f"{colored('TRACE', 'cyan')}:{line_formatting} %(msg)s"
debug_format = f"{colored('DEBUG', 'magenta')}:{line_formatting} %(msg)s"
info_format = f"{colored('INFO', 'blue')}:{line_formatting} %(msg)s"
print_format = f"%(msg)s"
warning_format = f"{timestamp_formatting}{colored('WARNING', 'yellow')}:{line_formatting} %(msg)s"
error_format = f"{timestamp_formatting}{colored('ERROR', 'red')}:{line_formatting} %(msg)s"
critical_format = f"{timestamp_formatting}{colored('CRITICAL', 'red', attrs=['reverse', 'blink', 'bold'])}: {line_formatting} %(msg)s"
def __init__(self):
super().__init__(fmt=f"UNKNOWN: %(msg)s", datefmt=None, style='%')
def format(self, record):
# Save the original format configured by the user
# when the logger formatter was instantiated
format_orig = self._style._fmt
# Replace the original format with one customized by logging level
if record.levelno == logging.TRACE:
self._style._fmt = MyFormatter.trace_format
elif record.levelno == logging.DEBUG:
self._style._fmt = MyFormatter.debug_format
elif record.levelno == logging.INFO:
self._style._fmt = MyFormatter.info_format
elif record.levelno == logging.PRINT:
self._style._fmt = MyFormatter.print_format
elif record.levelno == logging.WARNING:
self._style._fmt = MyFormatter.warning_format
elif record.levelno == logging.ERROR:
self._style._fmt = MyFormatter.error_format
elif record.levelno == logging.CRITICAL:
self._style._fmt = MyFormatter.critical_format
else:
raise NotImplementedError(f"We don't know how to format logging levels: {record.levelno}")
# Call the original formatter class to do the grunt work
result = logging.Formatter.format(self, record)
# Restore the original format configured by the user
self._style._fmt = format_orig
return result
class StdOutFilter(logging.Filter):
def filter(self, rec):
return rec.levelno <= logging.PRINT
class StdErrFilter(logging.Filter):
def filter(self, rec):
stdout_filter = StdOutFilter()
return not stdout_filter.filter(rec)
def setup_console_output():
fmt = MyFormatter()
stdout_handler = logging.StreamHandler(sys.stdout)
stdout_handler.setFormatter(fmt)
stdout_handler.addFilter(StdOutFilter())
logging.root.addHandler(stdout_handler)
stderr_handler = logging.StreamHandler(sys.stderr)
stderr_handler.setFormatter(fmt)
stderr_handler.addFilter(StdErrFilter())
logging.root.addHandler(stderr_handler)
if __name__ == "__main__":
setup_console_output()
print("writing some logs...")
logging.root.setLevel(logging.TRACE)
logging.debug("something debug message")
logging.trace("something trace message")
logging.warning("something warning message")
this outputs:
/Users/oliver/ClionProjects/testing/venv/bin/python3 /Users/oliver/ClionProjects/testing/misc/misc.py
writing some logs...
DEBUG: (/Users/oliver/ClionProjects/testing/misc/misc.py:90) something debug message
TRACE: (/Users/oliver/ClionProjects/testing/venv/lib/python3.11/site-packages/haggis/logs.py:211) something trace message
[2023-08-18 18:39:14,906]: WARNING: (/Users/oliver/ClionProjects/testing/misc/misc.py:92) something warning message
Process finished with exit code 0
Notice that the path name is correct for the debug message, but incorrect for the trace message.