You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python3使用logging模块实现按日期动态生成日志文件问题咨询

解决方案

你现有代码的问题在于,仅在初始化logger的阶段调用了一次get_file_handler,生成的文件路径是程序启动时的日期,后续运行过程中不会主动检测日期变更更新文件路径,因此日期切换后仍会写入旧文件。
要实现你要求的直接按当前日期生成对应文件名写入、不经过固定文件名重命名的逻辑,可以通过自定义logging的旋转Handler实现,修改后的可运行代码如下:

import logging
import coloredlogs
import platform
import sys
import os
from datetime import datetime
from logging.handlers import BaseRotatingHandler

FORMATTER = logging.Formatter("%(asctime)s : %(hostname)s : %(name)s : %(levelname)s : %(message)s")
LOG_FILE = os.environ['RMQ_DISPACHER_LOGFILE']
NICKNAME = os.environ['LOGNICKNAME']

class HostnameFilter(logging.Filter):
    hostname = platform.node()
    def filter(self, record):
        record.hostname = HostnameFilter.hostname
        return True

# 自定义按天动态生成文件名的Handler
class DailyDynamicFileHandler(BaseRotatingHandler):
    def __init__(self, log_dir, nickname, encoding=None, delay=False):
        self.log_dir = log_dir
        self.nickname = nickname
        self.current_date = datetime.now().strftime('%Y%m%d')
        # 生成初始日志文件名
        filename = self._get_current_filename()
        super().__init__(filename, mode='a', encoding=encoding, delay=delay)

    def _get_current_filename(self):
        return f"{self.log_dir}/{self.nickname}_{self.current_date}.log"

    def shouldRollover(self, record):
        # 检查当前日期是否和上次写入的日期一致
        now_date = datetime.now().strftime('%Y%m%d')
        if now_date != self.current_date:
            self.current_date = now_date
            return True
        return False

    def doRollover(self):
        # 关闭旧的文件流
        if self.stream:
            self.stream.close()
            self.stream = None
        # 更新为新日期的文件名
        self.baseFilename = self._get_current_filename()
        # 打开新的文件流
        if not self.delay:
            self.stream = self._open()

def get_console_handler():
    console_handler = logging.StreamHandler(sys.stdout)
    console_handler.addFilter(HostnameFilter())
    console_handler.setFormatter(FORMATTER)
    return console_handler

def get_file_handler():
    # 替换为自定义的Handler
    file_handler = DailyDynamicFileHandler(LOG_FILE, NICKNAME)
    file_handler.addFilter(HostnameFilter())
    file_handler.setFormatter(FORMATTER)
    return file_handler

def get_logger(logger_name):
    logger = logging.getLogger(logger_name)
    logger.setLevel(logging.DEBUG)
    logger.addHandler(get_console_handler())
    logger.addHandler(get_file_handler())
    logger.propagate = False
    coloredlogs.install(logger=logger)
    return logger

实现说明

  • 自定义的DailyDynamicFileHandler继承了logging官方提供的BaseRotatingHandler基础旋转类,每次写入日志前都会调用shouldRollover方法校验当前日期是否发生变化
  • 检测到日期变更后自动触发doRollover逻辑,关闭旧日志文件流,按你指定的命名规则生成新日期的日志文件并打开新流,完全符合你的使用要求
  • 兼容你原有代码中的HostnameFilter、日志格式配置和coloredlogs的能力,不需要修改上层调用logger的业务代码

如果需要自动清理过期日志,可以在doRollover方法中补充扫描日志目录、删除超过指定保留天数的旧文件的逻辑,避免磁盘占用过高。


内容的提问来源于stack exchange,提问作者Éric

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 07:15:05