import logging import os from datetime import datetime from logging.handlers import TimedRotatingFileHandler class CustomHourlyHandler(TimedRotatingFileHandler): def __init__(self, base_filename, level=logging.INFO, is_error=False): # 初始化路径 self.is_error = is_error self.base_filename = base_filename self.log_dir = self._get_log_dir() filename = self._build_log_path() # 初始化 handler super().__init__( filename, when='H', interval=1, backupCount=336, # 14天 * 24小时 = 336 小时日志 encoding='utf-8', utc=False ) self.setLevel(level) formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s') self.setFormatter(formatter) def _get_log_dir(self): today = datetime.now().strftime("%Y-%m-%d") log_dir = os.path.join("logs", today) os.makedirs(log_dir, exist_ok=True) return log_dir def _build_log_path(self): hour = datetime.now().strftime("%H") suffix = "err.log" if self.is_error else "app.log" return os.path.join(self.log_dir, f"{hour}_{suffix}") def shouldRollover(self, record): # 每小时轮换并重设路径 result = super().shouldRollover(record) if result: self.baseFilename = os.path.abspath(self._build_log_path()) return result logger = logging.getLogger("DailyMotion") logger.setLevel(logging.DEBUG) if not logger.handlers: logger.addHandler(CustomHourlyHandler("app", level=logging.DEBUG, is_error=False)) logger.addHandler(CustomHourlyHandler("err", level=logging.ERROR, is_error=True)) ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) ch.setFormatter(logging.Formatter('%(asctime)s %(levelname)s %(message)s')) logger.addHandler(ch)