Skip to main content
 首页 » 编程设计

python之获取 Flask 中错误记录的请求上下文

2025年05月04日17lidabo

Flask 教程有一个发生错误时给自己发电子邮件的例子。我想从 request 添加一些信息,但一直收到错误:

RuntimeError: working outside of request context 

这是我的:

if  __name__ == '__main__': 
    if not app.debug:   
 
        # create mail handler 
        import logging 
        from logging.handlers import SMTPHandler 
        mail_handler = SMTPHandler('127.0.0.1', 
                               'server-error@example.com', 
                               ['admin@example.com'], 'YourApplication Failed') 
 
        # Log format 
        from logging import Formatter 
        mail_handler.setFormatter(Formatter(''' 
        Message type:       %(levelname)s 
        Location:           %(pathname)s:%(lineno)d 
        Module:             %(module)s 
        Function:           %(funcName)s 
        Time:               %(asctime)s 
 
        Message: 
 
        %(message)s 
        ''' % request.headers ))   # Added request here 
 
        # Attach log handler to app 
        mail_handler.setLevel(logging.ERROR) 
        app.logger.addHandler(mail_handler) 

如何获取日志记录的请求上下文?

请您参考如下方法:

您实际上需要添加一个过滤器以将您想要的内容添加到记录器:

import logging 
 
class ContextualFilter(logging.Filter): 
    def filter(self, log_record): 
        log_record.url = request.path 
        log_record.method = request.method 
        log_record.ip = request.environ.get("REMOTE_ADDR") 
        log_record.headers = request.headers 
 
        return True 

然后您可以使用应用程序的记录器注册过滤器:

context_provider = ContextualFilter() 
app.logger.addFilter(context_provider) 

并使用您添加到格式化程序上下文中的额外键:

mail_handler.setFormatter(Formatter(''' 
    Message type:       %(levelname)s 
    Location:           %(pathname)s:%(lineno)d 
    Module:             %(module)s 
    Function:           %(funcName)s 
    Time:               %(asctime)s 
    URL:                %(url)s 
    Method:             %(method)s 
    Headers:            %(headers)s 
 
    Message: 
 
    %(message)s 
    ''')) 

为什么我不能将 request.headers 添加到我的格式化程序中

两个原因:

  1. 设置记录器时没有请求上下文,因为没有入站请求
  2. 即使有,该代码实际上也不会执行您希望它执行的操作。当您设置记录器时,它将在范围内的请求中添加请求 header (因此所有请求都将是第一个请求)。

另请参阅:https://realpython.com/blog/python/python-web-applications-with-flask-part-iii/