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

Python使用basicConfig和RotatingFileHandler做日志轮转报WindowsError32怎么办

问题根源

你代码中对同一个日志文件C:\temp\debug.log注册了两个持有文件锁的日志处理器:

  • 调用logging.basicConfig时,会自动给根日志器添加一个默认的FileHandler,一直占用着debug.log的文件句柄
  • 后续你又给自定义的Rotating Log日志器添加了RotatingFileHandler,也打开了同一个文件
    Windows系统下文件默认是独占访问模式,当RotatingFileHandler触发日志轮转需要重命名当前日志文件时,另一个FileHandler还在持有文件锁,就会抛出Error 32报错。
解决方案

两种修改方式选其一即可:

方式1:不要同时使用basicConfig的filename参数和自定义RotatingFileHandler

把日志格式、日志级别直接配置到你自定义的RotatingFileHandler上,删掉make_log_setup里logging.basicConfig的filename配置,改为单独创建格式器给轮转处理器用:

def make_log_setup():
    global log_formatter
    date_strftime_format = "%d-%b-%y %H:%M:%S"
    message_format='%(asctime)s %(levelname)s %(module)s - %(funcName)s: %(message)s'
    # 提前创建格式器,后续给RotatingFileHandler使用
    log_formatter = logging.Formatter(message_format, datefmt=date_strftime_format)
    # 只配置全局日志级别,不要指定filename,避免自动生成FileHandler占用文件
    logging.basicConfig(level=logging.DEBUG)

def create_rotating_log(path):
    logger = logging.getLogger("Rotating Log")
    # 关闭日志向上传递到根日志器,避免重复输出日志
    logger.propagate = False
    logger.setLevel(logging.DEBUG)
    
    handler = RotatingFileHandler(path, maxBytes=20, backupCount=5)
    # 给轮转处理器绑定自定义日志格式
    handler.setFormatter(log_formatter)
    logger.addHandler(handler)
    
    for i in range(6):
        logger.info("This is test log line %s" % i)
        time.sleep(1.5)

方式2:移除根日志器默认生成的FileHandler

如果要保留basicConfig的原有配置,就在添加RotatingFileHandler前先把根日志器上绑定的FileHandler关闭并移除:

def create_rotating_log(path):
    # 先清理根日志器占用目标文件的处理器
    root_logger = logging.getLogger()
    for handler in root_logger.handlers[:]:
        if isinstance(handler, logging.FileHandler) and handler.baseFilename == path:
            handler.close()
            root_logger.removeHandler(handler)
    
    logger = logging.getLogger("Rotating Log")
    logger.setLevel(logging.DEBUG)
    # 后续原有逻辑保持不变
    handler = RotatingFileHandler(path, maxBytes=20,backupCount=5)
    logger.addHandler(handler)
    
    for i in range(6):
        logger.info("This is test log line %s" % i)
        time.sleep(1.5)

小提示:你当前设置的maxBytes=20表示日志文件满20字节就触发轮转,仅适合测试用,实际使用时可以根据需求调整为更大的数值,比如10*1024*1024对应10MB。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 13:15:10