Python WSGI 应用程序的调试/监控中间件

1 投票
5 回答
2411 浏览
提问于 2025-04-11 09:28

我在找一种可以包裹在wsgi应用程序周围的中间件,这样我就能监控进来的和出去的http请求以及头部信息。

就像火狐浏览器的实时头部功能,但这是针对服务器端的。

5 个回答

2

如果你想要类似Apache的日志,可以试试 paste.translogger

不过,如果你想要更完整的功能,虽然这个文件的位置可能不太方便或者不太稳定(你可以考虑把它复制到你的源代码里),可以看看 wsgifilter.proxyapp.DebugHeaders

另外,你也可以使用 WebOb 来自己写一个:

import webob, sys
class LogHeaders(object):
    def __init__(self, app, stream=sys.stderr):
        self.app = app
        self.stream = stream
    def __call__(self, environ, start_response):
        req = webob.Request(environ)
        resp = req.get_response(self.app)
        print >> self.stream, 'Request:\n%s\n\nResponse:\n%s\n\n\n' % (req, resp)
        return resp(environ, start_response)
2

这应该不难,只要你只需要获取头部信息就可以自己写。试试这个:

import sys

def log_headers(app, stream=None):
    if stream is None:
        stream = sys.stdout
    def proxy(environ, start_response):
        for key, value in environ.iteritems():
            if key.startswith('HTTP_'):
                stream.write('%s: %s\n' % (key[5:].title().replace('_', '-'), value))
        return app(environ, start_response)
    return proxy
2

中间件

from wsgiref.util import request_uri
import sys

def logging_middleware(application, stream=sys.stdout):
    def _logger(environ, start_response):
        stream.write('REQUEST\n')
        stream.write('%s %s\n' %(
            environ['REQUEST_METHOD'],
            request_uri(environ),
        ))

        for name, value in environ.items():
            if name.startswith('HTTP_'):
                stream.write('    %s: %s\n' %(
                    name[5:].title().replace('_', '-'),
                    value,
                ))
        stream.flush()
        def _start_response(code, headers):
            stream.write('RESPONSE\n')
            stream.write('%s\n' % code)
            for data in headers:
                stream.write('    %s: %s\n' % data)
            stream.flush()
            start_response(code, headers)
        return application(environ, _start_response)
    return _logger

测试

def application(environ, start_response):
    start_response('200 OK', [
        ('Content-Type', 'text/html')
    ])
    return ['Hello World']

if __name__ == '__main__':
    logger = logging_middleware(application)
    from wsgiref.simple_server import make_server
    httpd = make_server('', 1234, logger)
    httpd.serve_forever()

另外,看看 Armin 写的 werkzeug 调试工具,它对于交互式调试非常有用。

撰写回答