mirror of
				https://github.com/avatao-content/baseimage-tutorial-framework
				synced 2025-11-04 05:12:54 +00:00 
			
		
		
		
	Refactor TFW logging
This commit is contained in:
		@@ -1,10 +1,9 @@
 | 
			
		||||
# pylint: disable=bad-whitespace
 | 
			
		||||
from sys import stderr
 | 
			
		||||
from datetime import datetime
 | 
			
		||||
from typing import TextIO, Union
 | 
			
		||||
from dataclasses import dataclass
 | 
			
		||||
from logging import DEBUG, getLogger, Handler, Formatter, Filter
 | 
			
		||||
 | 
			
		||||
from .envvars import TFWENV
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Color:
 | 
			
		||||
    GREY        = '\033[30;1m'
 | 
			
		||||
@@ -17,40 +16,55 @@ class Color:
 | 
			
		||||
    RESET       = '\033[0m'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TFWLog:
 | 
			
		||||
    def __init__(self, path=TFWENV.LOGFILE, level=DEBUG):
 | 
			
		||||
        self.log = getLogger()
 | 
			
		||||
        self.old_level = self.log.level
 | 
			
		||||
@dataclass
 | 
			
		||||
class Log:
 | 
			
		||||
    stream: Union[str, TextIO]
 | 
			
		||||
    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.handler = TFWLogHandler(path)
 | 
			
		||||
        self.handler.setFormatter(TFWLogFormatter(20))
 | 
			
		||||
        self.handlers = []
 | 
			
		||||
        for log in logs:
 | 
			
		||||
            handler = LogHandler(log.stream)
 | 
			
		||||
            handler.setFormatter(log.formatter)
 | 
			
		||||
            self.handlers.append(handler)
 | 
			
		||||
 | 
			
		||||
    def start(self):
 | 
			
		||||
        self.log.setLevel(self.new_level)
 | 
			
		||||
        self.log.addHandler(self.handler)
 | 
			
		||||
        self.root_logger.setLevel(self.new_level)
 | 
			
		||||
        for handler in self.handlers:
 | 
			
		||||
            self.root_logger.addHandler(handler)
 | 
			
		||||
 | 
			
		||||
    def stop(self):
 | 
			
		||||
        self.log.setLevel(self.old_level)
 | 
			
		||||
        self.handler.close()
 | 
			
		||||
        self.log.removeHandler(self.handler)
 | 
			
		||||
        self.root_logger.setLevel(self.old_level)
 | 
			
		||||
        for handler in self.handlers:
 | 
			
		||||
            handler.close()
 | 
			
		||||
            self.root_logger.removeHandler(handler)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TFWLogHandler(Handler):
 | 
			
		||||
    def __init__(self, path):
 | 
			
		||||
        self.logfile = open(path, 'a+')
 | 
			
		||||
class LogHandler(Handler):
 | 
			
		||||
    def __init__(self, stream):
 | 
			
		||||
        if isinstance(stream, str):
 | 
			
		||||
            self.stream = open(stream, 'a+')
 | 
			
		||||
            self.close_stream = True
 | 
			
		||||
        else:
 | 
			
		||||
            self.stream = stream
 | 
			
		||||
            self.close_stream = False
 | 
			
		||||
        super().__init__()
 | 
			
		||||
 | 
			
		||||
    def emit(self, record):
 | 
			
		||||
        short_entry, long_entry = self.format(record)
 | 
			
		||||
        stderr.write(short_entry+'\n')
 | 
			
		||||
        self.logfile.write(long_entry+'\n')
 | 
			
		||||
        stderr.flush()
 | 
			
		||||
        self.logfile.flush()
 | 
			
		||||
        entry = self.format(record)
 | 
			
		||||
        self.stream.write(entry+'\n')
 | 
			
		||||
        self.stream.flush()
 | 
			
		||||
 | 
			
		||||
    def close(self):
 | 
			
		||||
        self.logfile.close()
 | 
			
		||||
        if self.close_stream:
 | 
			
		||||
            self.stream.close()
 | 
			
		||||
 | 
			
		||||
class TFWLogFormatter(Formatter):
 | 
			
		||||
class LogFormatter(Formatter):
 | 
			
		||||
    severity_to_color = {
 | 
			
		||||
        'CRITICAL' : Color.BOLDRED,
 | 
			
		||||
        'ERROR'    : Color.RED,
 | 
			
		||||
@@ -69,18 +83,13 @@ class TFWLogFormatter(Formatter):
 | 
			
		||||
        if 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))
 | 
			
		||||
            short_message = record.msg % clean_args
 | 
			
		||||
            long_message = record.msg % record.args
 | 
			
		||||
            message = record.msg % clean_args
 | 
			
		||||
        else:
 | 
			
		||||
            short_message = record.msg
 | 
			
		||||
            long_message = record.msg
 | 
			
		||||
            message = record.msg
 | 
			
		||||
 | 
			
		||||
        short_entry = (f'[{Color.GREY}{date}{Color.RESET}|>'
 | 
			
		||||
                       f'{self.severity_to_color[record.levelname]}{record.module}:'
 | 
			
		||||
                       f'{record.levelname.lower()}{Color.RESET}] {short_message}')
 | 
			
		||||
        long_entry = (f'[{date}|>{record.module}:{record.levelname.lower()}] '
 | 
			
		||||
                      f'{long_message}')
 | 
			
		||||
        return short_entry, long_entry
 | 
			
		||||
        return (f'[{Color.GREY}{date}{Color.RESET}|>'
 | 
			
		||||
                f'{self.severity_to_color[record.levelname]}{record.module}:'
 | 
			
		||||
                f'{record.levelname.lower()}{Color.RESET}] {message}')
 | 
			
		||||
 | 
			
		||||
    def trim(self, value):
 | 
			
		||||
        if isinstance(value, dict):
 | 
			
		||||
@@ -91,6 +100,18 @@ class TFWLogFormatter(Formatter):
 | 
			
		||||
        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):
 | 
			
		||||
    def __init__(self, names):
 | 
			
		||||
        self.names = names
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user