mirror of
https://github.com/BioArchLinux/bioarchlinux-tools.git
synced 2025-03-09 22:53:31 +00:00
95 lines
3.2 KiB
Python
95 lines
3.2 KiB
Python
'''
|
|
A Tornado-inspired logging formatter, with displayed time with millisecond accuracy
|
|
|
|
FYI: pyftpdlib also has a Tornado-style logger.
|
|
'''
|
|
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
import time
|
|
import logging
|
|
|
|
class TornadoLogFormatter(logging.Formatter):
|
|
def __init__(self, color, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self._color = color
|
|
if color:
|
|
import curses
|
|
curses.setupterm()
|
|
if sys.hexversion < 0x30203f0:
|
|
fg_color = str(curses.tigetstr("setaf") or
|
|
curses.tigetstr("setf") or "", "ascii")
|
|
else:
|
|
fg_color = curses.tigetstr("setaf") or curses.tigetstr("setf") or b""
|
|
self._colors = {
|
|
logging.DEBUG: str(curses.tparm(fg_color, 4), # Blue
|
|
"ascii"),
|
|
logging.INFO: str(curses.tparm(fg_color, 2), # Green
|
|
"ascii"),
|
|
logging.WARNING: str(curses.tparm(fg_color, 3), # Yellow
|
|
"ascii"),
|
|
logging.ERROR: str(curses.tparm(fg_color, 1), # Red
|
|
"ascii"),
|
|
logging.CRITICAL: str(curses.tparm(fg_color, 9), # Bright Red
|
|
"ascii"),
|
|
}
|
|
self._normal = str(curses.tigetstr("sgr0"), "ascii")
|
|
|
|
def format(self, record):
|
|
try:
|
|
record.message = record.getMessage()
|
|
except Exception as e:
|
|
record.message = "Bad message (%r): %r" % (e, record.__dict__)
|
|
record.asctime = time.strftime(
|
|
"%m-%d %H:%M:%S", self.converter(record.created))
|
|
prefix = '[%(levelname)1.1s %(asctime)s.%(msecs)03d %(module)s:%(lineno)d]' % \
|
|
record.__dict__
|
|
if self._color:
|
|
prefix = (self._colors.get(record.levelno, self._normal) +
|
|
prefix + self._normal)
|
|
formatted = prefix + " " + record.message
|
|
|
|
formatted += ''.join(
|
|
' %s=%s' % (k, v) for k, v in record.__dict__.items()
|
|
if k not in {
|
|
'levelname', 'asctime', 'module', 'lineno', 'args', 'message',
|
|
'filename', 'exc_info', 'exc_text', 'created', 'funcName',
|
|
'processName', 'process', 'msecs', 'relativeCreated', 'thread',
|
|
'threadName', 'name', 'levelno', 'msg', 'pathname', 'stack_info',
|
|
})
|
|
|
|
if record.exc_info:
|
|
if not record.exc_text:
|
|
record.exc_text = self.formatException(record.exc_info)
|
|
if record.exc_text:
|
|
formatted = formatted.rstrip() + "\n" + record.exc_text
|
|
return formatted.replace("\n", "\n ")
|
|
|
|
def enable_pretty_logging(level=logging.DEBUG, handler=None, color=None):
|
|
'''
|
|
handler: specify a handler instead of default StreamHandler
|
|
color: boolean, force color to be on / off. Default to be on only when
|
|
``handler`` isn't specified and the term supports color
|
|
'''
|
|
logger = logging.getLogger()
|
|
if handler is None:
|
|
h = logging.StreamHandler()
|
|
else:
|
|
h = handler
|
|
if color is None:
|
|
color = False
|
|
if handler is None and sys.stderr.isatty():
|
|
try:
|
|
import curses
|
|
curses.setupterm()
|
|
if curses.tigetnum("colors") > 0:
|
|
color = True
|
|
except:
|
|
import traceback
|
|
traceback.print_exc()
|
|
formatter = TornadoLogFormatter(color=color)
|
|
h.setLevel(level)
|
|
h.setFormatter(formatter)
|
|
logger.setLevel(level)
|
|
logger.addHandler(h)
|