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

Python日志RotatingFileHandler无法写入错误日志至文件问题求助

Python日志记录问题:RotatingFileHandler未写入错误日志

我在Python应用中遇到日志记录问题,已配置RotatingFileHandler捕获错误并写入文件,但错误日志未按预期写入文件。

我的日志配置

# In logger_config.py
import logging
from logging.handlers import RotatingFileHandler

def setup_logging(name: str):

    logger = logging.getLogger(name)

    logger.setLevel(logging.DEBUG)

    log_msg = """
===========
%(asctime)s - %(name)s - %(levelname)s - %(filename)s:
%(message)s
===========
"""
    formatter = logging.Formatter(log_msg)

    file_handler = RotatingFileHandler(
        'logs/app.log', maxBytes=1000000, backupCount=5)
    file_handler.setLevel(logging.ERROR)
    file_handler.setFormatter(formatter)

    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.DEBUG)
    console_handler.setFormatter(formatter)

    logger.addHandler(file_handler)
    logger.addHandler(console_handler)

    return logger

日志实例使用场景

# In my_script.py
from .logger_config import setup_logging

logger = setup_logging(__name__)

async def CallStep1(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """
    STEP 1: Choosing the Location
    """
    try:
        # Code...
    except Exception as e:
        logger.error(f"An error occurred in CallStep1: {e}", exc_info=True) # this gets logged in the console but its not getting saved in the file

已做配置说明

  • 定义了日志配置函数,设置了RotatingFileHandler和StreamHandler(输出至控制台)
  • 使用logging.getLogger(name)实例化日志对象
  • 已将日志级别设为DEBUG,文件处理器级别设为ERROR
  • 尽管如此,错误日志仍未写入文件

已排查内容

  • 日志目录权限设置正确,进程具备写入权限
  • 日志记录过程未抛出异常
  • 日志调用正确使用了日志实例及对应级别

问题排查与修复方案

1. 修正日志文件路径

'logs/app.log'是相对路径,进程工作目录可能与脚本所在目录不一致,导致日志文件被创建在非预期位置。改为绝对路径即可解决:

# 在logger_config.py中添加os模块引用
import os

def setup_logging(name: str):
    logger = logging.getLogger(name)
    logger.setLevel(logging.DEBUG)

    # 生成日志目录的绝对路径
    log_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'logs')
    # 确保日志目录存在,不存在则自动创建
    os.makedirs(log_dir, exist_ok=True)

    log_msg = """
===========
%(asctime)s - %(name)s - %(levelname)s - %(filename)s:
%(message)s
===========
"""
    formatter = logging.Formatter(log_msg)

    # 使用绝对路径创建文件处理器
    file_handler = RotatingFileHandler(
        os.path.join(log_dir, 'app.log'), maxBytes=1000000, backupCount=5)
    file_handler.setLevel(logging.ERROR)
    file_handler.setFormatter(formatter)

    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.DEBUG)
    console_handler.setFormatter(formatter)

    logger.addHandler(file_handler)
    logger.addHandler(console_handler)

    return logger

2. 确认处理器是否正确添加

在setup_logging函数末尾添加打印语句,验证文件处理器是否成功加入日志实例:

print(f"当前日志实例的处理器列表: {[h.__class__.__name__ for h in logger.handlers]}")

如果输出中没有RotatingFileHandler,说明处理器添加逻辑存在问题,需检查是否有其他代码修改了日志实例的处理器集合。

3. 验证日志级别配置

在调用logger.error()的位置添加级别打印,确认配置的级别是否生效:

except Exception as e:
    print(f"日志实例级别: {logging.getLevelName(logger.level)}")
    print(f"文件处理器级别: {logging.getLevelName(logger.handlers[0].level)}")
    logger.error(f"An error occurred in CallStep1: {e}", exc_info=True)

需确保日志实例级别≤文件处理器级别(此处DEBUG≤ERROR符合要求),否则日志会被过滤。

4. 排查异步环境影响

由于日志调用在异步函数中,可先在同步代码中测试日志写入:

# 在my_script.py中添加同步测试代码
def test_log():
    logger.error("测试错误日志写入", exc_info=True)

test_log()

如果同步测试能正常写入文件,说明异步环境中可能存在日志线程阻塞,可确认异步框架是否有特殊的日志处理要求,或使用logging的线程安全机制优化。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 14:46:31