Refactor TFW logging

This commit is contained in:
R. Richard 2019-06-28 17:34:37 +02:00 committed by Kristóf Tóth
parent f94c5b0c37
commit 68a6469d23
2 changed files with 63 additions and 36 deletions

View File

@ -1,10 +1,9 @@
# pylint: disable=bad-whitespace # pylint: disable=bad-whitespace
from sys import stderr
from datetime import datetime from datetime import datetime
from typing import TextIO, Union
from dataclasses import dataclass
from logging import DEBUG, getLogger, Handler, Formatter, Filter from logging import DEBUG, getLogger, Handler, Formatter, Filter
from .envvars import TFWENV
class Color: class Color:
GREY = '\033[30;1m' GREY = '\033[30;1m'
@ -17,40 +16,55 @@ class Color:
RESET = '\033[0m' RESET = '\033[0m'
class TFWLog: @dataclass
def __init__(self, path=TFWENV.LOGFILE, level=DEBUG): class Log:
self.log = getLogger() stream: Union[str, TextIO]
self.old_level = self.log.level formatter: Formatter
class Logger:
def __init__(self, logs, level=DEBUG):
self.root_logger = getLogger()
self.old_level = self.root_logger.level
self.new_level = level self.new_level = level
self.handler = TFWLogHandler(path) self.handlers = []
self.handler.setFormatter(TFWLogFormatter(20)) for log in logs:
handler = LogHandler(log.stream)
handler.setFormatter(log.formatter)
self.handlers.append(handler)
def start(self): def start(self):
self.log.setLevel(self.new_level) self.root_logger.setLevel(self.new_level)
self.log.addHandler(self.handler) for handler in self.handlers:
self.root_logger.addHandler(handler)
def stop(self): def stop(self):
self.log.setLevel(self.old_level) self.root_logger.setLevel(self.old_level)
self.handler.close() for handler in self.handlers:
self.log.removeHandler(self.handler) handler.close()
self.root_logger.removeHandler(handler)
class TFWLogHandler(Handler): class LogHandler(Handler):
def __init__(self, path): def __init__(self, stream):
self.logfile = open(path, 'a+') if isinstance(stream, str):
self.stream = open(stream, 'a+')
self.close_stream = True
else:
self.stream = stream
self.close_stream = False
super().__init__() super().__init__()
def emit(self, record): def emit(self, record):
short_entry, long_entry = self.format(record) entry = self.format(record)
stderr.write(short_entry+'\n') self.stream.write(entry+'\n')
self.logfile.write(long_entry+'\n') self.stream.flush()
stderr.flush()
self.logfile.flush()
def close(self): def close(self):
self.logfile.close() if self.close_stream:
self.stream.close()
class TFWLogFormatter(Formatter): class LogFormatter(Formatter):
severity_to_color = { severity_to_color = {
'CRITICAL' : Color.BOLDRED, 'CRITICAL' : Color.BOLDRED,
'ERROR' : Color.RED, 'ERROR' : Color.RED,
@ -69,18 +83,13 @@ class TFWLogFormatter(Formatter):
if record.args: if record.args:
tuple_args = (record.args,) if isinstance(record.args, dict) else record.args tuple_args = (record.args,) if isinstance(record.args, dict) else record.args
clean_args = tuple((self.trim(arg) for arg in tuple_args)) clean_args = tuple((self.trim(arg) for arg in tuple_args))
short_message = record.msg % clean_args message = record.msg % clean_args
long_message = record.msg % record.args
else: else:
short_message = record.msg message = record.msg
long_message = record.msg
short_entry = (f'[{Color.GREY}{date}{Color.RESET}|>' return (f'[{Color.GREY}{date}{Color.RESET}|>'
f'{self.severity_to_color[record.levelname]}{record.module}:' f'{self.severity_to_color[record.levelname]}{record.module}:'
f'{record.levelname.lower()}{Color.RESET}] {short_message}') f'{record.levelname.lower()}{Color.RESET}] {message}')
long_entry = (f'[{date}|>{record.module}:{record.levelname.lower()}] '
f'{long_message}')
return short_entry, long_entry
def trim(self, value): def trim(self, value):
if isinstance(value, dict): if isinstance(value, dict):
@ -91,6 +100,18 @@ class TFWLogFormatter(Formatter):
return value return value
class VerboseLogFormatter(Formatter):
def format(self, record):
date = datetime.utcfromtimestamp(record.created).strftime('%H:%M:%S')
if record.args:
message = record.msg % record.args
else:
message = record.msg
return (f'[{date}|>{record.module}:{record.levelname.lower()}] '
f'{message}')
class WhitelistFilter(Filter): class WhitelistFilter(Filter):
def __init__(self, names): def __init__(self, names):
self.names = names self.names = names

View File

@ -1,10 +1,16 @@
from sys import stderr
from tornado.ioloop import IOLoop from tornado.ioloop import IOLoop
from tfw.config.log import TFWLog
from tfw.server import TFWServer from tfw.server import TFWServer
from tfw.config import TFWENV
from tfw.logging import Log, Logger, LogFormatter, VerboseLogFormatter
if __name__ == '__main__': if __name__ == '__main__':
TFWLog().start() Logger([
Log(stderr, LogFormatter(20)),
Log(TFWENV.LOGFILE, VerboseLogFormatter())
]).start()
TFWServer().listen() TFWServer().listen()
IOLoop.instance().start() IOLoop.instance().start()