Skip to content

Instantly share code, notes, and snippets.

@zerodeux
Created February 4, 2014 13:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zerodeux/8803753 to your computer and use it in GitHub Desktop.
Save zerodeux/8803753 to your computer and use it in GitHub Desktop.
WSGI basic profiling middleware based on POSIX getrusage (simple mods from Gawel's)
__doc__ = """
Profiling middleware. Log wallclock, utime, stime and idle time.
Copy the file in your source tree and wrap your application with the RUsage
middleware::
from wsgi_profile import RUsage
application = WSGIAppilcation()
application = RUsage(application)
You can also use a paste config file::
[pipeline:main]
pipeline = profile yourapp
[filter:profile]
paste.filter_factory = wsgi_profile:rusage
[app:yourapp]
# [app:main]
"""
import resource
import logging
import time
import os
import ldap_profile
log = logging.getLogger(__name__)
class Stats(object):
stats_keys = ['ru_utime', 'ru_stime']
fmt = (
'%(path)-40s - time: %(time)6.3f - '
'stime: %(ru_stime)6.3f - utime: %(ru_utime)6.3f - idle: %(idle)6.3f '
)
def __init__(self, environ):
self.iterator = None
self.path = (
'%(REQUEST_METHOD)s %(PATH_INFO)s?%(QUERY_STRING)s') % environ
self.time = time.time()
self.bstats = resource.getrusage(resource.RUSAGE_SELF)
def log_stats(self):
estats = resource.getrusage(resource.RUSAGE_SELF)
stats = {'path': self.path}
for k in self.stats_keys:
stats[k] = getattr(estats, k) - getattr(self.bstats, k)
stats['time'] = time.time() - self.time
stats['idle'] = stats['time'] - (stats['ru_utime'] + stats['ru_stime'])
log.info(self.fmt, stats)
def __iter__(self):
return self
def next(self):
try:
return self.iterator.next()
except StopIteration:
self.log_stats()
raise StopIteration()
__next__ = next
class RUsage(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
_, ext = os.path.splitext(environ['PATH_INFO'])
if ext in ('.js', '.css', '.png', '.jpg', '.gif'):
return self.app(environ, start_response)
stats = Stats(environ)
iterator = self.app(environ, start_response)
if isinstance(iterator, list):
stats.log_stats()
return iterator
else:
stats.iterator = iterator
return iter(stats)
def rusage(*args, **kwargs):
"""Middleware factory"""
return RUsage
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment