VWED_server/utils/logger.py
2025-04-30 16:57:46 +08:00

215 lines
6.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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)