VWED_server/utils/logger.py

215 lines
6.8 KiB
Python
Raw Normal View History

2025-04-30 16:57:46 +08:00
# utils/logger.py
import logging
import os
import traceback
from logging.handlers import RotatingFileHandler
from config.settings import LogConfig
def setup_logger():
"""设置日志"""
# 获取日志配置
LOG_CONFIG = LogConfig.as_dict()
# 创建日志目录
log_dir = os.path.dirname(LOG_CONFIG["file"])
if not os.path.exists(log_dir):
os.makedirs(log_dir)
# 设置日志级别
log_level = getattr(logging, LOG_CONFIG["level"].upper(), logging.INFO)
# 设置日志格式 - 增加行号、函数名等信息
log_format = logging.Formatter(LOG_CONFIG.get("format", "%(asctime)s - %(name)s - %(levelname)s - %(message)s"))
# 为警告和错误级别创建特殊格式
detailed_format = logging.Formatter(
"%(asctime)s - %(name)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(funcName)s() - %(message)s"
)
# 创建根日志记录器
root_logger = logging.getLogger()
root_logger.setLevel(log_level)
# 清除现有处理器
for handler in root_logger.handlers[:]:
root_logger.removeHandler(handler)
# 添加控制台处理器
console_handler = logging.StreamHandler()
console_handler.setFormatter(log_format)
# 为警告及以上级别设置详细格式
console_handler.setLevel(logging.INFO)
root_logger.addHandler(console_handler)
# 添加专门的错误控制台处理器,显示更多详细信息
error_console_handler = logging.StreamHandler()
error_console_handler.setFormatter(detailed_format)
error_console_handler.setLevel(logging.WARNING) # 只处理警告及以上级别
root_logger.addHandler(error_console_handler)
# 添加文件处理器
file_handler = RotatingFileHandler(
LOG_CONFIG["file"],
maxBytes=10 * 1024 * 1024, # 10MB
backupCount=5
)
file_handler.setFormatter(log_format)
root_logger.addHandler(file_handler)
# 添加专门的错误文件处理器,显示更多详细信息
error_file_handler = RotatingFileHandler(
LOG_CONFIG.get("error_file", os.path.join(log_dir, "error.log")),
maxBytes=10 * 1024 * 1024, # 10MB
backupCount=5
)
error_file_handler.setFormatter(detailed_format)
error_file_handler.setLevel(logging.WARNING) # 只处理警告及以上级别
root_logger.addHandler(error_file_handler)
# 设置第三方库的日志级别
logging.getLogger("werkzeug").setLevel(logging.WARNING)
logging.getLogger("urllib3").setLevel(logging.WARNING)
return root_logger
class Logger:
"""
日志记录器类
封装不同级别的日志记录功能
"""
def __init__(self, name):
"""
初始化日志记录器
Args:
name (str): 日志记录器名称通常为模块名称
"""
# 获取指定名称的日志记录器
self.logger = logging.getLogger(name)
self.name = name
def debug(self, message, *args, **kwargs):
"""
记录调试日志
Args:
message: 日志消息
*args: 位置参数
**kwargs: 关键字参数
"""
self.logger.debug(message, *args, **kwargs)
def info(self, message, *args, **kwargs):
"""
记录一般信息日志
Args:
message: 日志消息
*args: 位置参数
**kwargs: 关键字参数
"""
self.logger.info(message, *args, **kwargs)
def warning(self, message, *args, exc_info=False, stack_info=False, **kwargs):
"""
记录警告日志
Args:
message: 日志消息
*args: 位置参数
exc_info: 是否包含异常信息默认False
stack_info: 是否包含堆栈信息默认False
**kwargs: 关键字参数
"""
# 默认启用堆栈信息以便显示行号
# 如果不想显示整个堆栈跟踪可以保持stack_info为False系统会自动记录行号
self.logger.warning(message, *args, exc_info=exc_info, stack_info=stack_info, **kwargs)
def error(self, message, *args, exc_info=True, stack_info=True, **kwargs):
"""
记录错误日志
Args:
message: 日志消息
*args: 位置参数
exc_info: 是否包含异常信息默认True
stack_info: 是否包含堆栈信息默认True
**kwargs: 关键字参数
"""
# 由于我们已经在日志格式中添加了行号和文件名,这里不需要特殊处理
self.logger.error(message, *args, exc_info=exc_info, stack_info=stack_info, **kwargs)
def critical(self, message, *args, exc_info=True, stack_info=True, **kwargs):
"""
记录严重错误日志
Args:
message: 日志消息
*args: 位置参数
exc_info: 是否包含异常信息默认True
stack_info: 是否包含堆栈信息默认True
**kwargs: 关键字参数
"""
self.logger.critical(message, *args, exc_info=exc_info, stack_info=stack_info, **kwargs)
def exception(self, message, *args, **kwargs):
"""
记录异常日志自动包含异常堆栈信息
Args:
message: 日志消息
*args: 位置参数
**kwargs: 关键字参数
"""
self.logger.exception(message, *args, **kwargs)
def log_error_with_trace(self, message, e=None):
"""
记录带有详细追踪信息的错误日志
Args:
message: 日志消息
e: 异常对象可选
"""
error_msg = f"{message}"
if e:
error_msg += f": {str(e)}"
# 使用traceback模块获取完整的堆栈跟踪
trace = traceback.format_exc()
self.logger.error(f"{error_msg}\n{trace}")
def log_startup(self, module_name, version=None):
"""
记录模块启动日志
Args:
module_name: 模块名称
version: 版本号可选
"""
version_str = f" v{version}" if version else ""
self.logger.info(f"=== {module_name}{version_str} 启动完成 ===")
def log_shutdown(self, module_name):
"""
记录模块关闭日志
Args:
module_name: 模块名称
"""
self.logger.info(f"=== {module_name} 已关闭 ===")
def get_logger(name):
"""
获取指定名称的日志记录器
Args:
name (str): 日志记录器名称通常为模块名称
Returns:
Logger: 日志记录器实例
"""
# 确保全局日志配置已初始化
setup_logger()
# 创建并返回Logger实例
return Logger(name)