Skip to main content
Glama
logging_config.py6.26 kB
"""日志配置模块 提供统一的日志配置和管理功能,支持控制台、文件和性能日志。 使用 loguru 作为底层日志库,提供结构化日志和性能监控功能。 主要功能: - 多种日志输出格式(控制台、文件、性能) - 日志轮转和压缩 - 结构化日志记录 - 性能监控日志 - 日志统计信息 """ import sys from pathlib import Path from typing import Dict, Any from loguru import logger class LoggingConfig: """日志配置类 提供统一的日志配置管理,支持多种输出方式和格式。 使用 loguru 作为底层日志库,提供高性能和灵活的日志功能。 """ # 文件日志格式 FILE_FORMAT = ( "{time:YYYY-MM-DD HH:mm:ss.SSS} | {level: <8} | " "{name}:{function}:{line} | {message}" ) # 控制台日志格式(带颜色) CONSOLE_FORMAT = ( "<green>{time:HH:mm:ss.SSS}</green> | " "<level>{level: <8}</level> | " "<cyan>{name}</cyan>:<cyan>{function}</cyan>:" "<cyan>{line}</cyan> | {message}" ) # 性能日志格式 PERFORMANCE_FORMAT = ( "{time:YYYY-MM-DD HH:mm:ss.SSS} | PERF | " "{extra[operation]} | {extra[duration]:.3f}s | {message}" ) def __init__(self, log_level: str = "INFO", logs_dir: str = "logs") -> None: """初始化日志配置 Args: log_level: 日志级别,默认为 INFO logs_dir: 日志文件目录,默认为 logs """ self.log_level = log_level.upper() self.logs_dir = Path(logs_dir) self.logs_dir.mkdir(exist_ok=True) # 日志文件路径 self.app_log_file = self.logs_dir / "app.log" self.error_log_file = self.logs_dir / "error.log" self.performance_log_file = self.logs_dir / "performance.log" # 清除默认处理器 logger.remove() def setup_logging(self, enable_console: bool = True, enable_file: bool = True, enable_performance: bool = False) -> None: """设置日志配置 Args: enable_console: 是否启用控制台日志 enable_file: 是否启用文件日志 enable_performance: 是否启用性能日志 """ try: if enable_console: self._setup_console_logging() if enable_file: self._setup_file_logging() if enable_performance: self._setup_performance_logging() logger.info(f"日志系统初始化完成,级别: {self.log_level}") except Exception as e: # 如果配置失败,至少保证基本的控制台输出 logger.add(sys.stderr, level="ERROR") logger.error(f"日志配置失败: {e}") raise def _setup_file_logging(self) -> None: """设置文件日志""" # 应用日志(所有级别) logger.add( self.app_log_file, format=self.FILE_FORMAT, level=self.log_level, rotation="10 MB", retention="30 days", compression="zip", encoding="utf-8", enqueue=True # 异步写入 ) # 错误日志(仅错误和严重错误) logger.add( self.error_log_file, format=self.FILE_FORMAT, level="ERROR", rotation="5 MB", retention="60 days", compression="zip", encoding="utf-8", enqueue=True ) def _setup_console_logging(self) -> None: """设置控制台日志""" logger.add( sys.stderr, format=self.CONSOLE_FORMAT, level=self.log_level, colorize=True ) def _setup_performance_logging(self) -> None: """设置性能日志""" logger.add( self.performance_log_file, format=self.PERFORMANCE_FORMAT, level="INFO", filter=lambda record: "performance" in record["extra"], rotation="5 MB", retention="7 days", encoding="utf-8" ) @staticmethod def log_performance(operation: str, duration: float, details: str = "") -> None: """记录性能日志 Args: operation: 操作名称 duration: 执行时间(秒) details: 详细信息 """ logger.bind(performance=True, operation=operation, duration=duration).info( f"操作完成: {details}" if details else "操作完成" ) @staticmethod def log_structured(level: str, event: str, **kwargs: Any) -> None: """记录结构化日志 Args: level: 日志级别 event: 事件描述 **kwargs: 结构化数据 """ log_func = getattr(logger, level.lower(), logger.info) log_func(event) def get_log_stats(self) -> Dict[str, Any]: """获取日志统计信息 Returns: 包含日志文件信息的字典 """ stats: Dict[str, Any] = { "log_directory": str(self.logs_dir), "log_level": self.log_level, "log_files": [] } log_files_list = stats["log_files"] for log_file in [self.app_log_file, self.error_log_file, self.performance_log_file]: if log_file.exists(): log_files_list.append({ "name": log_file.name, "path": str(log_file), "size": log_file.stat().st_size, "modified": log_file.stat().st_mtime }) return stats def setup_default_logging( log_level: str = "INFO", logs_dir: str = "logs") -> LoggingConfig: """设置默认日志配置 Args: log_level: 日志级别 logs_dir: 日志目录 Returns: 配置好的 LoggingConfig 实例 """ logging_config = LoggingConfig(log_level, logs_dir) logging_config.setup_logging() return logging_config

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/icatw/uml-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server