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

rub*_*lex 1 python error-handling error-logging flask

Flask教程有一个在发生错误时通过电子邮件发送自己的示例.我想添加一些信息request,但一直收到错误:

RuntimeError: working outside of request context
Run Code Online (Sandbox Code Playgroud)

这是我有的:

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)
Run Code Online (Sandbox Code Playgroud)

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

Sea*_*ira 6

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

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
Run Code Online (Sandbox Code Playgroud)

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

context_provider = ContextualFilter()
app.logger.addFilter(context_provider)
Run Code Online (Sandbox Code Playgroud)

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

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
    '''))
Run Code Online (Sandbox Code Playgroud)

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

两个原因:

  1. 因为没有请求是入站的,所以在设置记录器时没有请求上下文
  2. 即使有,该代码实际上也不会按照您的意愿执行.当您设置记录器时,它将在范围内添加请求标头(因此所有请求都是第一个请求).

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