Coverage for src/symphra_modules/utils/logger.py: 78.38%
33 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-26 18:16 +0800
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-26 18:16 +0800
1"""抽象日志接口."""
3import logging
4from typing import Any, Protocol
7class Logger(Protocol):
8 """日志记录器协议.
10 定义了日志接口,用户可以提供自己的日志实现。
11 """
13 def debug(self, message: str, **kwargs: Any) -> None:
14 """记录 DEBUG 级别日志."""
15 ...
17 def info(self, message: str, **kwargs: Any) -> None:
18 """记录 INFO 级别日志."""
19 ...
21 def warning(self, message: str, **kwargs: Any) -> None:
22 """记录 WARNING 级别日志."""
23 ...
25 def error(self, message: str, **kwargs: Any) -> None:
26 """记录 ERROR 级别日志."""
27 ...
29 def exception(self, message: str, **kwargs: Any) -> None:
30 """记录异常信息."""
31 ...
34class StandardLogger:
35 """基于 Python 标准库 logging 的默认日志实现."""
37 def __init__(self, name: str = "symphra_modules") -> None:
38 """初始化日志记录器.
40 Args:
41 name: 日志记录器名称
42 """
43 self._logger = logging.getLogger(name)
44 if not self._logger.handlers: 44 ↛ exitline 44 didn't return from function '__init__' because the condition on line 44 was always true
45 handler = logging.StreamHandler()
46 formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
47 handler.setFormatter(formatter)
48 self._logger.addHandler(handler)
49 self._logger.setLevel(logging.INFO)
51 def debug(self, message: str, **kwargs: Any) -> None:
52 """记录 DEBUG 级别日志."""
53 self._logger.debug(self._format_message(message, kwargs))
55 def info(self, message: str, **kwargs: Any) -> None:
56 """记录 INFO 级别日志."""
57 self._logger.info(self._format_message(message, kwargs))
59 def warning(self, message: str, **kwargs: Any) -> None:
60 """记录 WARNING 级别日志."""
61 self._logger.warning(self._format_message(message, kwargs))
63 def error(self, message: str, **kwargs: Any) -> None:
64 """记录 ERROR 级别日志."""
65 self._logger.error(self._format_message(message, kwargs))
67 def exception(self, message: str, **kwargs: Any) -> None:
68 """记录异常信息."""
69 self._logger.exception(self._format_message(message, kwargs))
71 def _format_message(self, message: str, kwargs: dict[str, Any]) -> str:
72 """格式化日志消息.
74 Args:
75 message: 消息模板
76 kwargs: 格式化参数
78 Returns:
79 格式化后的消息
80 """
81 if kwargs: 81 ↛ 82line 81 didn't jump to line 82 because the condition on line 81 was never true
82 try:
83 return message.format(**kwargs)
84 except (KeyError, ValueError):
85 # 如果格式化失败,附加 kwargs 信息
86 return f"{message} | {kwargs}"
87 return message
90# 全局日志实例
91_global_logger: Logger = StandardLogger()
94def get_logger() -> Logger:
95 """获取全局日志实例.
97 Returns:
98 当前配置的日志记录器
99 """
100 return _global_logger
103def set_logger(logger: Logger) -> None:
104 """设置全局日志实例.
106 Args:
107 logger: 新的日志记录器实例
108 """
109 global _global_logger
110 _global_logger = logger