live-forum/server/crawler/commerce/utils/logger.py
2026-03-24 11:27:37 +08:00

128 lines
3.6 KiB
Python
Raw 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.

"""
日志工具模块
使用Python标准库logging兼容Python 3.8.6
"""
import logging
import sys
from pathlib import Path
from datetime import datetime
from config.settings import LOG_LEVEL, LOG_FORMAT, LOG_DIR
def get_log_filename(base_name: str = 'crawler') -> Path:
"""
根据当前月份生成日志文件名
Args:
base_name: 日志文件基础名称
Returns:
日志文件路径,格式为: base_name-yyyy-mm.log
"""
current_date = datetime.now()
filename = f"{base_name}-{current_date.strftime('%Y-%m')}.log"
return LOG_DIR / filename
class MonthlyRotatingFileHandler(logging.FileHandler):
"""
按月轮转的日志处理器
文件名格式为: base_name-yyyy-mm.log
当月份变化时,自动切换到新的日志文件
"""
def __init__(self, base_name: str = 'crawler', encoding: str = 'utf-8', delay: bool = False):
"""
初始化按月轮转的日志处理器
Args:
base_name: 日志文件基础名称
encoding: 文件编码
delay: 是否延迟打开文件
"""
self.base_name = base_name
self.current_month = None
self.log_dir = LOG_DIR
self.log_dir.mkdir(parents=True, exist_ok=True)
# 获取当前月份的日志文件
log_file = get_log_filename(base_name)
self.current_month = datetime.now().strftime('%Y-%m')
super().__init__(str(log_file), mode='a', encoding=encoding, delay=delay)
def emit(self, record):
"""
发送日志记录
在发送前检查月份是否变化,如果变化则切换到新的日志文件
"""
current_month = datetime.now().strftime('%Y-%m')
# 如果月份变化,切换到新的日志文件
if current_month != self.current_month:
self.do_rollover()
self.current_month = current_month
super().emit(record)
def do_rollover(self):
"""
执行日志轮转
关闭当前文件,打开新月份的日志文件
"""
if self.stream:
self.stream.close()
self.stream = None
# 生成新月份的日志文件名
new_log_file = get_log_filename(self.base_name)
self.baseFilename = str(new_log_file)
# 打开新的日志文件
if not self.delay:
self.stream = self._open()
def setup_logger(name: str = 'crawler', level: str = LOG_LEVEL) -> logging.Logger:
"""
配置并返回logger实例
Args:
name: logger名称
level: 日志级别
Returns:
logging.Logger实例
"""
logger = logging.getLogger(name)
logger.setLevel(getattr(logging, level.upper(), logging.INFO))
# 避免重复添加handler
if logger.handlers:
return logger
# 控制台输出
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setLevel(getattr(logging, level.upper(), logging.INFO))
console_formatter = logging.Formatter(LOG_FORMAT)
console_handler.setFormatter(console_formatter)
logger.addHandler(console_handler)
# 文件输出 - 按月轮转,文件名格式为: crawler-yyyy-mm.log
file_handler = MonthlyRotatingFileHandler(
base_name=name,
encoding='utf-8',
delay=False
)
file_handler.setLevel(logging.INFO)
file_formatter = logging.Formatter(LOG_FORMAT)
file_handler.setFormatter(file_formatter)
logger.addHandler(file_handler)
return logger
# 创建默认logger
logger = setup_logger()