Peter Hoffmann Code Blog

Random postings about python, code and social apps. If you want more, check out my friendfeed profile.
Sep 23
Permalink

middleware to monitor python wsgi applications

I’m working on some RESTful python wsgi application. For debugging and monitoring I needed a way to see the request and response HTTP header without modifying the actual code.

So I posted the question to stackoverflow where Florian Boenisch came up with a nice solution.

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 sorted(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 sorted(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()

This middelware is is a example of accessing the response from the wrapped middleware.

The output will be something like this:

REQUEST
PUT http://localhost:5000/testdb/1
    Accept-Encoding: identity
    Host: localhost:5000
    User-Agent: Python-httplib2/$Rev: 196 $
RESPONSE
201 CREATED
    content-type: application/json
    ['{"rev": "1222169702", "ok": true, "id": "1"}']

REQUEST
GET http://localhost:5000/_all_dbs
    Accept-Encoding: compress, gzip
    Host: localhost:5000
    User-Agent: Python-httplib2/$Rev: 196 $
RESPONSE
200 OK
    Content-Type: text/plain; charset=utf-8
   ['["testdb"]']

REQUEST
DELETE http://localhost:5000/testdb
    Accept-Encoding: identity
    Host: localhost:5000
    User-Agent: Python-httplib2/$Rev: 196 $
RESPONSE
200 OK
    Content-Type: text/plain; charset=utf-8
    ['{"ok":true}']
Comments (View)
blog comments powered by Disqus