Team Ai
Apppublic

PCNUSMSE/transcript_service

sourceHugging Faceapache-2.0updated 1mo agoView on Hugging Face
0likes
logger.py260 linesDownload Raw Back to utils
1"""日志管理模块2 3提供结构化日志记录功能,支持任务跟踪和状态记录。4"""5 6import logging7import logging.config8import logging.handlers9import uuid10from pathlib import Path11from typing import Any, Dict, Optional12import yaml13 14try:15    from rich.console import Console16    from rich.logging import RichHandler17    RICH_AVAILABLE = True18except ImportError:19    RICH_AVAILABLE = False20 21from ..core.config import get_config22 23 24class TaskContextFilter(logging.Filter):25    """任务上下文过滤器26    27    为日志记录添加任务ID上下文信息。28    """29    30    def __init__(self):31        super().__init__()32        self.task_id = 'system'33    34    def filter(self, record):35        """添加任务ID到日志记录"""36        # 确保所有记录都有task_id字段37        if not hasattr(record, 'task_id'):38            record.task_id = getattr(self, 'task_id', 'system')39        elif getattr(record, 'task_id', None) is None:40            record.task_id = getattr(self, 'task_id', 'system')41        return True42 43 44class Logger:45    """日志管理器"""46    47    def __init__(self, name: str = "transcript_service"):48        """初始化日志管理器49        50        Args:51            name: 日志器名称52        """53        self.name = name54        self.config = get_config()55        self._setup_logging()56        self.logger = logging.getLogger(name)57        self.task_filter = TaskContextFilter()58        59        # 为所有处理器添加任务过滤器60        for handler in self.logger.handlers:61            handler.addFilter(self.task_filter)62            63        # 同时为根日志器的处理器添加过滤器64        root_logger = logging.getLogger()65        for handler in root_logger.handlers:66            if not any(isinstance(f, TaskContextFilter) for f in handler.filters):67                handler.addFilter(self.task_filter)68    69    def _setup_logging(self):70        """设置日志配置"""71        # 确保日志目录存在72        logs_dir = self.config.get_logs_dir()73        74        # 加载日志配置文件75        config_file = self.config.get_project_root() / "config" / "logging.yaml"76        77        if config_file.exists():78            with open(config_file, 'r', encoding='utf-8') as file:79                logging_config = yaml.safe_load(file)80            81            # 更新文件路径为绝对路径82            for handler_name, handler_config in logging_config.get('handlers', {}).items():83                if 'filename' in handler_config:84                    handler_config['filename'] = str(logs_dir / Path(handler_config['filename']).name)85            86            logging.config.dictConfig(logging_config)87        else:88            # 使用默认配置89            self._setup_default_logging()90    91    def _setup_default_logging(self):92        """设置默认日志配置"""93        # 控制台处理器94        if RICH_AVAILABLE:95            console = Console()96            console_handler = RichHandler(97                console=console,98                show_time=True,99                show_path=True,100                markup=True101            )102        else:103            console_handler = logging.StreamHandler()104            console_formatter = logging.Formatter(105                '[%(asctime)s] [%(levelname)s] [%(name)s] %(message)s',106                datefmt='%Y-%m-%d %H:%M:%S'107            )108            console_handler.setFormatter(console_formatter)109        110        console_handler.setLevel(logging.DEBUG if self.config.app.debug else logging.INFO)111        112        # 文件处理器113        log_file = self.config.get_logs_dir() / "app.log"114        file_handler = logging.handlers.RotatingFileHandler(115            log_file,116            maxBytes=10*1024*1024,  # 10MB117            backupCount=5,118            encoding='utf-8'119        )120        file_handler.setLevel(logging.INFO)121        122        # 格式化器(简化版本)123        formatter = logging.Formatter(124            '[%(asctime)s] [%(levelname)s] [%(name)s] %(message)s',125            datefmt='%Y-%m-%d %H:%M:%S'126        )127        file_handler.setFormatter(formatter)128        129        # 配置根日志器130        root_logger = logging.getLogger()131        root_logger.setLevel(logging.DEBUG if self.config.app.debug else logging.INFO)132        root_logger.addHandler(console_handler)133        root_logger.addHandler(file_handler)134    135    def set_task_id(self, task_id: str):136        """设置当前任务ID137        138        Args:139            task_id: 任务ID140        """141        self.task_filter.task_id = task_id142    143    def clear_task_id(self):144        """清除当前任务ID"""145        self.task_filter.task_id = 'system'146    147    def debug(self, message: str, **kwargs):148        """记录调试信息"""149        self.logger.debug(message, extra=kwargs)150    151    def info(self, message: str, **kwargs):152        """记录一般信息"""153        self.logger.info(message, extra=kwargs)154    155    def warning(self, message: str, **kwargs):156        """记录警告信息"""157        self.logger.warning(message, extra=kwargs)158    159    def error(self, message: str, **kwargs):160        """记录错误信息"""161        self.logger.error(message, extra=kwargs)162    163    def critical(self, message: str, **kwargs):164        """记录严重错误"""165        self.logger.critical(message, extra=kwargs)166    167    def exception(self, message: str, **kwargs):168        """记录异常信息(包含堆栈跟踪)"""169        self.logger.exception(message, extra=kwargs)170 171 172class TaskLogger:173    """任务日志记录器174    175    为特定任务提供上下文日志记录。176    """177    178    def __init__(self, task_id: Optional[str] = None, logger_name: str = "transcript_service"):179        """初始化任务日志记录器180        181        Args:182            task_id: 任务ID,如果为None则自动生成183            logger_name: 基础日志器名称184        """185        self.task_id = task_id or str(uuid.uuid4())[:8]186        self.logger = Logger(logger_name)187        self.logger.set_task_id(self.task_id)188    189    def __enter__(self):190        """进入上下文管理器"""191        return self192    193    def __exit__(self, exc_type, exc_val, exc_tb):194        """退出上下文管理器"""195        self.logger.clear_task_id()196    197    def debug(self, message: str, **kwargs):198        """记录调试信息"""199        self.logger.debug(message, **kwargs)200    201    def info(self, message: str, **kwargs):202        """记录一般信息"""203        self.logger.info(message, **kwargs)204    205    def warning(self, message: str, **kwargs):206        """记录警告信息"""207        self.logger.warning(message, **kwargs)208    209    def error(self, message: str, **kwargs):210        """记录错误信息"""211        self.logger.error(message, **kwargs)212    213    def critical(self, message: str, **kwargs):214        """记录严重错误"""215        self.logger.critical(message, **kwargs)216    217    def exception(self, message: str, **kwargs):218        """记录异常信息"""219        self.logger.exception(message, **kwargs)220    221    def set_task_id(self, task_id: str):222        """设置当前任务ID223        224        Args:225            task_id: 任务ID226        """227        self.logger.set_task_id(task_id)228    229    def clear_task_id(self):230        """清除当前任务ID"""231        self.logger.clear_task_id()232 233 234# 全局日志实例235logger = Logger()236 237 238def get_logger(name: str = "transcript_service") -> Logger:239    """获取日志实例240    241    Args:242        name: 日志器名称243        244    Returns:245        日志实例246    """247    return Logger(name)248 249 250def get_task_logger(task_id: Optional[str] = None, logger_name: str = "transcript_service") -> TaskLogger:251    """获取任务日志实例252    253    Args:254        task_id: 任务ID255        logger_name: 日志器名称256        257    Returns:258        任务日志实例259    """260    return TaskLogger(task_id, logger_name)