| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- import sys
- import tempfile
- import hotshot
- import hotshot.stats
- from cStringIO import StringIO
-
- import cProfile
- import pstats
-
-
- def profile_this(fn):
- def profiled_fn(*args, **kwargs):
- filepath = "/tmp/%s.profile" % fn.__name__
- prof = cProfile.Profile()
- ret = prof.runcall(fn, *args, **kwargs)
- print "Writing to %s" % filepath
- prof.dump_stats(filepath)
-
- print "Printing stats"
- stats = pstats.Stats(filepath)
- stats.sort_stats('cumulative')
- stats.print_stats()
-
- return ret
- return profiled_fn
-
-
- class BaseMiddleware(object):
- query_param = None
-
- def show_profile(self, request):
- return self.query_param in request.GET
-
- def process_request(self, request):
- if self.show_profile(request):
- if 'prof_file' in request.GET:
- # It's sometimes useful to generate a file of output that can
- # converted for use with kcachegrind. To convert this file,
- # use:
- #
- # pyprof2calltree -o /tmp/callgrind.stats -i /tmp/out.stats
- #
- # then open the file in kcachegrind.
- self.tmpfile = open('/tmp/out.stats', 'w')
- else:
- self.tmpfile = tempfile.NamedTemporaryFile()
- self.profile = self.profiler()
-
- def profiler(self):
- return None
-
- def process_view(self, request, callback, callback_args, callback_kwargs):
- # We profile the view call - note that this misses the rest of Django's
- # request processing (eg middleware etc)
- if self.show_profile(request):
- return self.profile.runcall(
- callback, request, *callback_args, **callback_kwargs)
-
- def process_response(self, request, response):
- if self.show_profile(request):
- stats = self.stats()
-
- if 'prof_strip' in request.GET:
- stats.strip_dirs()
- if 'prof_sort' in request.GET:
- # See # http://docs.python.org/2/library/profile.html#pstats.Stats.sort_stats
- # for the fields you can sort on.
- stats.sort_stats(*request.GET['prof_sort'].split(','))
- else:
- stats.sort_stats('time', 'calls')
-
- # Capture STDOUT temporarily
- old_stdout = sys.stdout
- out = StringIO()
- sys.stdout = out
- stats.print_stats()
-
- stats_str = out.getvalue()
- sys.stdout.close()
- sys.stdout = old_stdout
-
- # Print status within PRE block
- if response and response.content and stats_str:
- response.content = "<pre>" + stats_str + "</pre>"
-
- return response
-
-
- class ProfileMiddleware(BaseMiddleware):
- query_param = 'cprofile'
-
- def profiler(self):
- return cProfile.Profile()
-
- def stats(self):
- self.profile.dump_stats(self.tmpfile.name)
- return pstats.Stats(self.tmpfile.name)
-
-
- class HotshotMiddleware(BaseMiddleware):
- """
- Displays hotshot profiling for any view.
- http://yoursite.com/yourview/?prof
-
- Based on http://djangosnippets.org/snippets/186/
- """
- query_param = 'hotshot'
-
- def profiler(self):
- return hotshot.Profile(self.tmpfile.name)
-
- def stats(self):
- self.profile.close()
- return hotshot.stats.load(self.tmpfile.name)
|