分别记录烧瓶请求:如何通过ID删除Python记录处理程序

时间:2020-04-08 11:31:49

标签: python flask logging

所以我有以下问题:

我正在使用Flask,我想生成两种不同类型的日志文件:一个常规日志文件,它将所有内容记录到一个文件中,一个Logger / Handler,它仅记录传入的请求和相应的传出响应,并分别记录每个请求的文件。在实践中,我使用具有自定义级别和易于调用功能的自定义日志类。但我试图将其分解为基本内容:

app = Flask(__name__)
general_logger = logging.getLogger(__name__)
# add_handlers_to_general_logger()

@app.before_request
def log_incoming_request():
    request_id = get_current_request_id()
    unique_logger = logging.getLogger("{0}.{1}".format(__name__, request_id))
    # add_handler_to_unique_logger()
    unique_logger.info("INCOMING REQUEST")


@app.route('/')
def index():
    general_logger.info("Index called!")
    file_A.do_something_A()  # this function takes X seconds to process, general_logger is also used in there
    return "Hello World"


@app.after_request
def log_outgoing_response(response):
    request_id = get_current_request_id()  # same id as in before_request
    unique_logger = logging.getLogger("{0}.{1}".format(__name__, request_id))
    unique_logger.info("OUTGOING RESPONSE")
    return response

现在的问题是,尽管它可以工作,但我认为创建这么多不同的记录器并不是一个好主意。在index()中调用的函数需要花费未知的秒数来处理,具体取决于发送的请求数据,并且应该能够一次处理多个请求。我的想法是只删除@ app.after_request中的相应处理程序。

因此,问题是: 在@ app.before_request中添加特定处理程序后,如何在@ app.after_request中按名称正确删除正确的处理程序,如:

@app.before_request
def log_incoming_request():
    request_id = get_current_request_id()
    unique_logger = logging.getLogger("unique")

    add_handler_to_unique_logger(request_id)

    unique_logger.info("INCOMING REQUEST")

@app.after_request
def log_outgoing_response(response):
    request_id = get_current_request_id()  # same id as in before_request
    unique_logger = logging.getLogger("{0}.{1}".format(__name__, request_id))
    unique_logger.info("OUTGOING RESPONSE")

    unique_logger.removeHandler(request_id)

    return response

或者还有其他方法可以正确记录单独的请求日志文件(文件名中带有request_id)?

谢谢!

1 个答案:

答案 0 :(得分:0)

在出现问题之前,我不会担心内存管理。无论如何,您都可以删除日志记录模块保存的引用:

del logging.root.manager.loggerDict[unique_logger_id]

当然,只有在代码中对记录器对象的所有其他引用也都消失的情况下,记录器对象本身才会停止存在。如果您还使用唯一的处理程序,我还建议在它们上调用close(),以便清除使用的文件资源。