Download src/utils/logger.py from Shimokumo/shimokumo: direct link, hf CLI and curl.
- Browser
- Download file 5.38 kB
-
https://huggingface.co/Shimokumo/shimokumo/resolve/main/src/utils/logger.py
- Command line
-
hf download hf://Shimokumo/shimokumo/src/utils/logger.py
-
curl -L -o logger.py https://huggingface.co/Shimokumo/shimokumo/resolve/main/src/utils/logger.py
5.38 kB
| """ | |
| 霜云(Shimokumo) - 日志工具模块 | |
| 支持彩色终端日志输出和文件日志记录。 | |
| 提供DEBUG、INFO、WARNING、ERROR四个级别。 | |
| """ | |
| import logging | |
| import os | |
| import sys | |
| from datetime import datetime | |
| from typing import Optional | |
| class ColoredFormatter(logging.Formatter): | |
| """彩色日志格式化器""" | |
| # ANSI颜色代码 | |
| COLORS = { | |
| "DEBUG": "\033[36m", # 青色 | |
| "INFO": "\033[32m", # 绿色 | |
| "WARNING": "\033[33m", # 黄色 | |
| "ERROR": "\033[31m", # 红色 | |
| "CRITICAL": "\033[35m", # 紫色 | |
| } | |
| RESET = "\033[0m" | |
| def format(self, record: logging.LogRecord) -> str: | |
| """格式化日志记录,添加颜色""" | |
| color = self.COLORS.get(record.levelname, self.RESET) | |
| # 保存原始level名称 | |
| record.levelname_colored = f"{color}{record.levelname}{self.RESET}" | |
| return super().format(record) | |
| class ShimokumoLogger: | |
| """霜云专用日志管理器 | |
| 提供统一的日志接口,支持彩色终端输出和文件记录。 | |
| 用法: | |
| logger = ShimokumoLogger(log_level="DEBUG", log_file="app.log") | |
| logger.info("服务启动成功") | |
| logger.error("连接失败", exc_info=True) | |
| """ | |
| # 日志格式模板 | |
| CONSOLE_FORMAT = ( | |
| "\033[90m%(asctime)s\033[0m | " | |
| "%(levelname_colored)-8s | " | |
| "\033[90m%(name)s\033[0m | " | |
| "%(message)s" | |
| ) | |
| FILE_FORMAT = ( | |
| "%(asctime)s | %(levelname)-8s | %(name)s | %(message)s" | |
| ) | |
| DATE_FORMAT = "%Y-%m-%d %H:%M:%S" | |
| def __init__( | |
| self, | |
| name: str = "Shimokumo", | |
| log_level: str = "INFO", | |
| log_file: Optional[str] = None, | |
| console_output: bool = True, | |
| ): | |
| """ | |
| 初始化日志管理器。 | |
| Args: | |
| name: 日志器名称 | |
| log_level: 日志级别 (DEBUG/INFO/WARNING/ERROR) | |
| log_file: 日志文件路径,为None则不写入文件 | |
| console_output: 是否输出到终端 | |
| """ | |
| self.name = name | |
| self.log_level = getattr(logging, log_level.upper(), logging.INFO) | |
| self.log_file = log_file | |
| self._logger = self._setup_logger(console_output) | |
| def _setup_logger(self, console_output: bool) -> logging.Logger: | |
| """配置日志器""" | |
| logger = logging.getLogger(self.name) | |
| logger.setLevel(self.log_level) | |
| # 清除已有handler防止重复 | |
| logger.handlers.clear() | |
| # 终端输出handler | |
| if console_output: | |
| console_handler = logging.StreamHandler(sys.stdout) | |
| console_handler.setLevel(self.log_level) | |
| console_formatter = ColoredFormatter( | |
| self.CONSOLE_FORMAT, | |
| datefmt=self.DATE_FORMAT, | |
| ) | |
| console_handler.setFormatter(console_formatter) | |
| logger.addHandler(console_handler) | |
| # 文件输出handler | |
| if self.log_file: | |
| log_dir = os.path.dirname(self.log_file) | |
| if log_dir: | |
| os.makedirs(log_dir, exist_ok=True) | |
| file_handler = logging.FileHandler( | |
| self.log_file, | |
| encoding="utf-8", | |
| mode="a", | |
| ) | |
| file_handler.setLevel(self.log_level) | |
| file_formatter = logging.Formatter( | |
| self.FILE_FORMAT, | |
| datefmt=self.DATE_FORMAT, | |
| ) | |
| file_handler.setFormatter(file_formatter) | |
| logger.addHandler(file_handler) | |
| return logger | |
| def debug(self, msg: str, **kwargs) -> None: | |
| """输出DEBUG级别日志""" | |
| self._logger.debug(msg, **kwargs) | |
| def info(self, msg: str, **kwargs) -> None: | |
| """输出INFO级别日志""" | |
| self._logger.info(msg, **kwargs) | |
| def warning(self, msg: str, **kwargs) -> None: | |
| """输出WARNING级别日志""" | |
| self._logger.warning(msg, **kwargs) | |
| def error(self, msg: str, **kwargs) -> None: | |
| """输出ERROR级别日志""" | |
| self._logger.error(msg, **kwargs) | |
| def critical(self, msg: str, **kwargs) -> None: | |
| """输出CRITICAL级别日志""" | |
| self._logger.critical(msg, **kwargs) | |
| def exception(self, msg: str, **kwargs) -> None: | |
| """输出异常信息(ERROR级别,包含堆栈跟踪)""" | |
| self._logger.exception(msg, **kwargs) | |
| def get_logger( | |
| name: str = "Shimokumo", | |
| log_level: str = "INFO", | |
| log_file: Optional[str] = None, | |
| ) -> "ShimokumoLogger": | |
| """ | |
| 工厂方法:获取或创建日志实例。 | |
| Args: | |
| name: 日志器名称 | |
| log_level: 日志级别 | |
| log_file: 日志文件路径 | |
| Returns: | |
| ShimokumoLogger实例 | |
| """ | |
| return ShimokumoLogger( | |
| name=name, | |
| log_level=log_level, | |
| log_file=log_file, | |
| ) | |
| def get_logger( | |
| name: str = "Shimokumo", | |
| log_level: str = "INFO", | |
| log_file: Optional[str] = None, | |
| ) -> ShimokumoLogger: | |
| """ | |
| 快捷函数:获取霜云日志器。 | |
| Args: | |
| name: 日志器名称 | |
| log_level: 日志级别 | |
| log_file: 日志文件路径 | |
| Returns: | |
| ShimokumoLogger实例 | |
| """ | |
| return ShimokumoLogger.get_logger(name, log_level, log_file) | |