NotificationChannel / core /logger /core_logger.py
Ekimart078's picture
Update type hints in CoreLogger constructor for better clarity
2ca99e2
Raw
History Blame Contribute Delete
3.09 kB
import os
import sys
from enum import Enum
from logging import Formatter, LogRecord, getLogger, StreamHandler, FileHandler
from pathlib import Path
from typing import Optional
from colorama import Fore, Style
class LoggerTarget(Enum):
CONSOLE = "console"
FILE = "file"
BOTH = "both"
class ColorFormatter(Formatter):
COLORS_LEVEL = {
"DEBUG": Fore.CYAN,
"INFO": Fore.GREEN,
"WARNING": Fore.YELLOW,
"ERROR": Fore.RED,
"CRITICAL": Fore.MAGENTA + Style.BRIGHT,
}
def format(self, record: LogRecord):
original_levelname = record.levelname
color = self.COLORS_LEVEL.get(original_levelname, "")
record.levelname = f"{color}{original_levelname}{Style.RESET_ALL}"
formatted = super().format(record)
return formatted
class CoreLogger:
def __init__(
self,
name: str = "app",
level: str = "INFO",
fmt: Optional[str] = None,
datefmt: Optional[str] = None,
log_to_console: bool = True,
log_to_file: bool = False,
):
self.logger = getLogger(name)
self.logger.setLevel(level)
self.log_to_console = log_to_console
self.log_to_file = log_to_file
self.logger.propagate = False
self.fmt = fmt or "%(asctime)s | %(levelname)-8s | %(message)s"
self.datefmt = datefmt or "%Y-%m-%d %H:%M:%S"
self.logger_file_path = Path(__file__).resolve().parents[2]
self.logger_file_path = self.logger_file_path / "logs" / "app.log"
formatter = Formatter(self.fmt, self.datefmt)
color_formatter = ColorFormatter(self.fmt, self.datefmt)
if self.log_to_console:
console_handler = StreamHandler(sys.stdout)
console_handler.setFormatter(color_formatter)
self.logger.addHandler(console_handler)
if self.log_to_file:
log_file_path = Path(self.logger_file_path).resolve()
log_file_path.parent.mkdir(parents=True, exist_ok=True)
fh = FileHandler(log_file_path, encoding="utf-8")
fh.setFormatter(formatter)
self.logger.addHandler(fh)
def debug(self, message: str):
self.logger.debug(message)
def info(self, message: str):
self.logger.info(message)
def warning(self, message: str):
self.logger.warning(message)
def error(self, message: str):
self.logger.error(message)
def clear_log(self, target: LoggerTarget = LoggerTarget.BOTH):
if target in (LoggerTarget.CONSOLE, LoggerTarget.BOTH) and self.log_to_console:
os.system("cls" if sys.platform.startswith("win") else "clear")
if target in (LoggerTarget.FILE, LoggerTarget.BOTH) and self.log_to_file:
log_file_path = Path(self.logger_file_path).resolve()
if log_file_path.exists():
with log_file_path.open("w", encoding="utf-8") as f:
f.truncate(0)
if __name__ == "__main__":
logger = CoreLogger(log_to_console=True, log_to_file=True)
logger.info("test")