Spaces:
Sleeping
Sleeping
| import logging | |
| from enum import IntEnum | |
| from typing import Any, Optional | |
| from rich.console import Console, Group | |
| from rich.panel import Panel | |
| from rich.rule import Rule | |
| from rich.syntax import Syntax | |
| from rich.table import Table | |
| from rich.tree import Tree | |
| from rich.logging import RichHandler | |
| from src.utils import Singleton | |
| YELLOW_HEX = "#d4b702" | |
| class LogLevel(IntEnum): | |
| CRITICAL = logging.CRITICAL | |
| FATAL = logging.FATAL | |
| ERROR = logging.ERROR | |
| WARNING = logging.WARNING | |
| WARN = logging.WARN | |
| INFO = logging.INFO | |
| DEBUG = logging.DEBUG | |
| class Logger(logging.Logger, metaclass=Singleton): | |
| def __init__(self, name="logger", level=logging.INFO): | |
| # Initialize the parent class | |
| super().__init__(name, level) | |
| # Define a formatter for log messages | |
| self.formatter = logging.Formatter( | |
| fmt="%(asctime)s - %(name)s:%(levelname)s - %(filename)s:%(lineno)s - %(message)s", | |
| datefmt="%Y-%m-%d %H:%M:%S", | |
| ) | |
| def init_logger(self, config, level: int = LogLevel.INFO): | |
| """ | |
| Initialize the logger with a file path and optional main process check. | |
| Args: | |
| log_path (str): The log file path. | |
| level (int, optional): The logging level. Defaults to logging.INFO. | |
| accelerator (Accelerator, optional): Accelerator instance to determine the main process. | |
| """ | |
| log_path = config.log_path | |
| self.handlers.clear() | |
| self.console = Console( | |
| width=None, | |
| markup=True, | |
| color_system="truecolor", | |
| force_terminal=True | |
| ) | |
| rich_handler = RichHandler( | |
| console=self.console, | |
| rich_tracebacks=True, | |
| show_time=False, | |
| show_level=False, | |
| show_path=False, | |
| markup=True, | |
| omit_repeated_times=False | |
| ) | |
| rich_handler.setLevel(level) | |
| rich_handler.setFormatter(self.formatter) | |
| self.addHandler(rich_handler) | |
| self.file_console = Console( | |
| width=None, | |
| markup=True, | |
| color_system="truecolor", | |
| force_terminal=True, | |
| file=open(log_path, "a", encoding="utf-8") | |
| ) | |
| rich_file_handler = RichHandler( | |
| console=self.file_console, | |
| rich_tracebacks=True, | |
| show_time=False, | |
| show_level=False, | |
| show_path=False, | |
| markup=True, | |
| omit_repeated_times=False, | |
| ) | |
| rich_file_handler.setLevel(level) | |
| rich_file_handler.setFormatter(self.formatter) | |
| self.addHandler(rich_file_handler) | |
| self.propagate = False | |
| def info(self, msg, *args, **kwargs): | |
| """ | |
| Only for string messages, not for rich objects. | |
| """ | |
| kwargs.setdefault("stacklevel", 2) | |
| if "style" in kwargs: | |
| kwargs.pop("style") | |
| if "level" in kwargs: | |
| kwargs.pop("level") | |
| super().info(msg, *args, **kwargs) | |
| def warning(self, msg, *args, **kwargs): | |
| """ | |
| Only for string messages, not for rich objects. | |
| """ | |
| kwargs.setdefault("stacklevel", 2) | |
| super().warning(msg, *args, **kwargs) | |
| def error(self, msg, *args, **kwargs): | |
| kwargs.setdefault("stacklevel", 2) | |
| super().error(msg, *args, **kwargs) | |
| def critical(self, msg, *args, **kwargs): | |
| kwargs.setdefault("stacklevel", 2) | |
| super().critical(msg, *args, **kwargs) | |
| def debug(self, msg, *args, **kwargs): | |
| kwargs.setdefault("stacklevel", 2) | |
| super().debug(msg, *args, **kwargs) | |
| def log(self, | |
| msg: Optional[Any] = None, | |
| level: LogLevel = LogLevel.INFO, | |
| **kwargs): | |
| """ | |
| Log a rich object or a string message to both console and file. | |
| """ | |
| if isinstance(msg, str): | |
| self.info(msg, **kwargs) | |
| elif isinstance(msg, (Group, Panel, Rule, Syntax, Table, Tree)): | |
| self.console.print(msg, **kwargs) | |
| self.file_console.print(msg, **kwargs) | |
| logger = Logger() |