Files
MIND/backend/logging.py
2024-03-03 23:19:04 +01:00

139 lines
2.9 KiB
Python

#-*- coding: utf-8 -*-
import logging
import logging.config
from os.path import exists
from typing import Any
from backend.helpers import folder_path
class InfoOnlyFilter(logging.Filter):
def filter(self, record: logging.LogRecord) -> bool:
return record.levelno == logging.INFO
class DebuggingOnlyFilter(logging.Filter):
def filter(self, record: logging.LogRecord) -> bool:
return LOGGER.level == logging.DEBUG
class ErrorColorFormatter(logging.Formatter):
def format(self, record: logging.LogRecord) -> Any:
result = super().format(record)
return f'\033[1;31:40m{result}\033[0m'
LOGGER_NAME = "MIND"
LOGGER_DEBUG_FILENAME = "MIND_debug.log"
LOGGER = logging.getLogger(LOGGER_NAME)
LOGGING_CONFIG = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"simple": {
"format": "[%(asctime)s][%(levelname)s] %(message)s",
"datefmt": "%H:%M:%S"
},
"simple_red": {
"()": ErrorColorFormatter,
"format": "[%(asctime)s][%(levelname)s] %(message)s",
"datefmt": "%H:%M:%S"
},
"detailed": {
"format": "%(asctime)s | %(threadName)s | %(filename)sL%(lineno)s | %(levelname)s | %(message)s",
"datefmt": "%Y-%m-%dT%H:%M:%S%z",
}
},
"filters": {
"only_info": {
"()": InfoOnlyFilter
},
"only_if_debugging": {
"()": DebuggingOnlyFilter
}
},
"handlers": {
"console_error": {
"class": "logging.StreamHandler",
"level": "WARNING",
"formatter": "simple_red",
"stream": "ext://sys.stderr"
},
"console": {
"class": "logging.StreamHandler",
"level": "INFO",
"formatter": "simple",
"filters": ["only_info"],
"stream": "ext://sys.stdout"
},
"debug_file": {
"class": "logging.StreamHandler",
"level": "DEBUG",
"formatter": "detailed",
"filters": ["only_if_debugging"],
"stream": ""
}
},
"loggers": {
LOGGER_NAME: {
"level": "INFO"
}
},
"root": {
"level": "DEBUG",
"handlers": [
"console",
"console_error",
"debug_file"
]
}
}
def setup_logging() -> None:
"Setup the basic config of the logging module"
logging.config.dictConfig(LOGGING_CONFIG)
return
def get_debug_log_filepath() -> str:
"""
Get the filepath to the debug logging file.
Not in a global variable to avoid unnecessary computation.
"""
return folder_path(LOGGER_DEBUG_FILENAME)
def set_log_level(
level: int,
clear_file: bool = True
) -> None:
"""Change the logging level
Args:
level (int): The level to set the logging to.
Should be a logging level, like `logging.INFO` or `logging.DEBUG`.
clear_file (bool, optional): Empty the debug logging file.
Defaults to True.
"""
LOGGER.debug(f'Setting logging level: {level}')
LOGGER.setLevel(level)
if level == logging.DEBUG:
stream_handler = logging.getLogger().handlers[
LOGGING_CONFIG["root"]["handlers"].index('debug_file')
]
file = get_debug_log_filepath()
if clear_file:
if exists(file):
open(file, "w").close()
else:
open(file, "x").close()
stream_handler.setStream(
open(file, "a")
)
return