Files
张翔 08ea5fbe98 feat(admin): 添加用户管理相关文件
添加用户管理视图、API和状态管理文件
2026-03-28 14:37:29 +08:00

156 lines
5.1 KiB
Python

"""
日志工具模块
"""
import logging
import sys
from pathlib import Path
from typing import Optional
from datetime import datetime
class TestLogger:
"""测试日志记录器"""
def __init__(self, name: str = "test", log_file: str = None, level: str = "INFO", console: bool = True):
"""
初始化日志记录器
Args:
name: 日志记录器名称
log_file: 日志文件路径
level: 日志级别
console: 是否输出到控制台
"""
self.logger = logging.getLogger(name)
self.logger.setLevel(getattr(logging, level.upper()))
# 清除现有的处理器
self.logger.handlers.clear()
# 创建格式化器
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
# 添加文件处理器
if log_file:
log_path = Path(log_file)
log_path.parent.mkdir(parents=True, exist_ok=True)
file_handler = logging.FileHandler(log_file, encoding='utf-8')
file_handler.setFormatter(formatter)
self.logger.addHandler(file_handler)
# 添加控制台处理器
if console:
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setFormatter(formatter)
self.logger.addHandler(console_handler)
def debug(self, message: str) -> None:
"""记录调试信息"""
self.logger.debug(message)
def info(self, message: str) -> None:
"""记录信息"""
self.logger.info(message)
def warning(self, message: str) -> None:
"""记录警告"""
self.logger.warning(message)
def error(self, message: str) -> None:
"""记录错误"""
self.logger.error(message)
def critical(self, message: str) -> None:
"""记录严重错误"""
self.logger.critical(message)
def exception(self, message: str) -> None:
"""记录异常信息"""
self.logger.exception(message)
def log_test_start(self, test_name: str) -> None:
"""记录测试开始"""
self.info(f"{'='*60}")
self.info(f"开始测试: {test_name}")
self.info(f"{'='*60}")
def log_test_end(self, test_name: str, passed: bool, duration: float = None) -> None:
"""记录测试结束"""
status = "✅ 通过" if passed else "❌ 失败"
duration_str = f" (耗时: {duration:.2f}ms)" if duration else ""
self.info(f"测试结束: {test_name} - {status}{duration_str}")
def log_request(self, method: str, url: str, data: dict = None, headers: dict = None) -> None:
"""记录请求信息"""
self.info(f"发送请求: {method} {url}")
if data:
self.info(f"请求数据: {data}")
if headers:
self.info(f"请求头: {headers}")
def log_response(self, status_code: int, response_time: float, data: dict = None) -> None:
"""记录响应信息"""
self.info(f"响应状态码: {status_code}")
self.info(f"响应时间: {response_time:.2f}ms")
if data:
self.info(f"响应数据: {data}")
def log_validation(self, rule_type: str, passed: bool, message: str = "") -> None:
"""记录验证结果"""
status = "" if passed else ""
self.info(f"{status} 验证规则 [{rule_type}]: {message or '通过'}")
def log_error(self, error: Exception) -> None:
"""记录错误详情"""
self.error(f"错误类型: {type(error).__name__}")
self.error(f"错误信息: {str(error)}")
self.exception("错误堆栈:")
def log_summary(self, total: int, passed: int, failed: int, skipped: int = 0, duration: float = None) -> None:
"""记录测试摘要"""
self.info(f"{'='*60}")
self.info(f"测试摘要:")
self.info(f" 总数: {total}")
self.info(f" 通过: {passed}")
self.info(f" 失败: {failed}")
self.info(f" 跳过: {skipped}")
if duration:
self.info(f" 总耗时: {duration:.2f}ms")
self.info(f" 通过率: {(passed/total*100):.2f}%")
self.info(f"{'='*60}")
class LoggerFactory:
"""日志记录器工厂"""
_loggers = {}
@classmethod
def get_logger(cls, name: str = "test", log_file: str = None, level: str = "INFO", console: bool = True) -> TestLogger:
"""
获取日志记录器实例
Args:
name: 日志记录器名称
log_file: 日志文件路径
level: 日志级别
console: 是否输出到控制台
Returns:
日志记录器实例
"""
key = f"{name}_{log_file}_{level}_{console}"
if key not in cls._loggers:
cls._loggers[key] = TestLogger(name, log_file, level, console)
return cls._loggers[key]
@classmethod
def clear_all(cls) -> None:
"""清除所有日志记录器"""
cls._loggers.clear()