Python TimedRotatingFileHandler日志跨文件写入问题求助
Flask + Gunicorn多进程下TimedRotatingFileHandler日志分散问题
我用Python Flask开发了一个API,使用TimedRotatingFileHandler按天生成新的日志文件,但日志并未按预期仅写入当日文件,而是分散到多个历史日期文件中——并非同一日志重复写入,而是不同日志分别出现在当日文件和历史日期文件里。
举几个例子:
- rest_api_log.20231115文件中存在日志行:
INFO - 2023-11-30 16:21:36,160 - Se ha ejecutado el método get_foo() - rest_api_log.20231129文件中存在日志行:
INFO - 2023-11-30 16:20:56,153 - Se ha ejecutado el método get_foo() - rest_api_log.20231130(11月30日的当日文件)中却存在:
INFO - 2023-12-01 09:44:31,322 - Se ha ejecutado el método add_foo(serial=908708ACE)
另外,1月18日的日志文件里包含1月19日的日志,同时1月19日的rest_api.log文件中也有当日日志,同一日期的日志被分散到了多个文件中。不确定是Gunicorn多进程(配置了3个worker)导致的问题,还是需要在每个HTTP请求中重新初始化日志实例,看起来日志handler始终保持打开状态,还在往历史日期的文件写入内容。
相关代码
api_logger.py
import logging from logging.handlers import TimedRotatingFileHandler def init_logger(level=logging.INFO): logpath = "logs/rest_api.log" logger = logging.getLogger(__name__) formatter = logging.Formatter('%(levelname)s - %(asctime)s - %(message)s') handler = TimedRotatingFileHandler(logpath, when="midnight", interval=1) handler.setFormatter(formatter) handler.setLevel(level) handler.suffix = "%Y%m%d" logger.addHandler(handler) logger.setLevel(level) return logger
主程序请求处理示例
from flask import request, jsonify, render_template import flask import logging app = flask.Flask(__name__) apilog = init_logger(logging.INFO) @app.route('/foobar', methods=['GET']) def get_foobar(): try: foo = some_work() resp = flask.make_response(foo) resp = RestHeaders.add_headers_to_response(resp) apilog.info(api.LOG_INFO_GET_FOO) return resp, api.HTTP_SUCCESS except Exception as e: apilog.exception(api.LOG_ERR_GET_FOO) return ExceptionManager.get_foo_exceptional_response(e)
排查思路与补充
之前考虑过将日志初始化逻辑移至每个请求方法中,也怀疑过服务器worker配置或日志本身的配置有误。
后来确认,该问题与Gunicorn多进程直接相关——当前的日志处理方式无法让多进程安全地写入同一个日志文件。目前有两个服务器节点且请求量较小,先将worker数限制为1来验证问题,后续再针对多进程场景寻求合适的解决方案。
内容的提问来源于stack exchange,提问作者RobertGG
相关产品推荐
相关产品推荐

