import os import re import thread class WSGILogger(object): """A WSGI middleware app which wraps 'nextapp' with pyconquer.""" def __init__(self, nextapp, path="pyconquer.log", time_calls=True, match=".*", c_calls=False): self.nextapp = nextapp self.path = path self.time_calls = time_calls self.match = match self.events = ['call', 'return', 'exception'] if c_calls: self.events.extend(['c_call', 'c_return', 'c_exception']) self.count = 0 def run(self, func, *args): """run(func, *args). Run func, dumping trace data into self.path.""" import pyconquer tr = pyconquer.Logger(events = self.events) path, ext = os.path.splitext(self.path) self.count += 1 path = "%s-%s-%s%s" % (path, self.count, thread.get_ident(), ext) tr.out = open(path, "wb") tr.time_calls = self.time_calls try: tr.start() return func(*args) finally: tr.stop() tr.out.close() def __call__(self, environ, start_response): # Wrap the request in a function so we get a "total time". # This breaks the spec (which says we must yield for each chunk # in the next app), but ... meh. def gather(): result = [] for line in self.nextapp(environ, start_response): result.append(line) return result if re.search(self.match, environ.get('PATH_INFO', '')): return self.run(gather) else: return gather()