在Flask或WSGI中打印原始HTTP请求

74 投票
7 回答
103710 浏览
提问于 2025-04-18 18:18

我正在调试一个我自己制作的微控制器,它正在逐行写入原始的HTTP请求。我使用Flask作为我的后端,我想看到请求的完整内容,格式如下:

GET / HTTP/1.1
Content-length: 123
User-agent: blah
...

我知道Flask是基于WSGI的。有没有办法让这个在Flask中工作?

7 个回答

14

你可能想要类似这样的东西

print(request.headers)
print(request.cookies)
print(request.data)
print(request.args)
print(request.form)
print(request.endpoint)
print(request.method)
print(request.remote_addr)
18

为什么不呢?

from flask import Flask, request

app = Flask(__name__)

@app.before_request
def log_request():
    app.logger.debug("Request Headers %s", request.headers)
    return None

# The remaining application code.

我用过请求头,但你也可以用同样的方法来打印任何请求的属性。相关文档在这里:http://flask.pocoo.org/docs/0.12/api/#flask.Request

另外,你需要把FLASK_DEBUG设置为1,这样Flask.logger.debug才能正常工作,这样的好处是你可以在生产环境中关闭它。

祝好,

34

假设你想要完整的细节,

还有另一种方法

@app.route('/')
def index():
    print request.__dict__
    #this prints all variables in `dict` format including `headers`
63

没错,Flask是一个WSGI应用,所以给你的应用加一层额外的日志记录其实很简单:

import pprint

class LoggingMiddleware(object):
    def __init__(self, app):
        self._app = app

    def __call__(self, env, resp):
        errorlog = env['wsgi.errors']
        pprint.pprint(('REQUEST', env), stream=errorlog)

        def log_response(status, headers, *args):
            pprint.pprint(('RESPONSE', status, headers), stream=errorlog)
            return resp(status, headers, *args)

        return self._app(env, log_response)

这段代码定义了一个中间件,用来包裹你的Flask应用。这样做的好处是,它完全独立于Flask,可以让你清楚地看到请求进来和响应出去的情况。

如何使用这个中间件,取决于你用的具体WSGI服务器;你可以查阅你WSGI服务器的文档。

如果你是用Flask自带的服务器(app.run())来运行Flask,可以这样做:

if __name__ == '__main__':
    app.wsgi_app = LoggingMiddleware(app.wsgi_app)
    app.run()

这段小小的app.wsgi_app包裹动作,把LoggingMiddleware放在Flask的WSGI应用周围。

输出信息会发送到wsgi.error流;这些信息最后去哪里也取决于你的WSGI服务器;比如mod_wsgi会把这些信息放到你网站的Apache错误日志里,而Flask自带的服务器则会把它打印到stderr

47

在Flask中,你可以使用一个叫做请求对象(request object)的东西,它里面包含了所有的HTTP请求的详细信息:

from flask import request

@app.route('/')
def index():
    print(request.headers)

撰写回答