You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

profiling.py 2.3KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import sys
  2. import tempfile
  3. import hotshot
  4. import hotshot.stats
  5. from cStringIO import StringIO
  6. import cProfile
  7. import pstats
  8. class BaseMiddleware(object):
  9. query_param = None
  10. def show_profile(self, request):
  11. return self.query_param in request.GET
  12. def process_request(self, request):
  13. if self.show_profile(request):
  14. self.tmpfile = tempfile.NamedTemporaryFile()
  15. self.profile = self.profiler()
  16. def profiler(self):
  17. return None
  18. def process_view(self, request, callback, callback_args, callback_kwargs):
  19. # We profile the view call - note that this misses the rest of Django's
  20. # request processing (eg middleware etc)
  21. if self.show_profile(request):
  22. return self.profile.runcall(
  23. callback, request, *callback_args, **callback_kwargs)
  24. def process_response(self, request, response):
  25. if self.show_profile(request):
  26. stats = self.stats()
  27. # Capture STDOUT temporarily
  28. old_stdout = sys.stdout
  29. sys.stdout = StringIO()
  30. if 'prof_strip' in request.GET:
  31. stats.strip_dirs()
  32. if 'prof_sort' in request.GET:
  33. stats.sort_stats(*request.GET['prof_sort'].split(','))
  34. else:
  35. stats.sort_stats('time', 'calls')
  36. stats.print_stats()
  37. stats_str = sys.stdout.getvalue()
  38. sys.stdout.close()
  39. sys.stdout = old_stdout
  40. # Print status within PRE block
  41. if response and response.content and stats_str:
  42. response.content = "<pre>" + stats_str + "</pre>"
  43. return response
  44. class ProfileMiddleware(BaseMiddleware):
  45. query_param = 'cprofile'
  46. def profiler(self):
  47. return cProfile.Profile()
  48. def stats(self):
  49. self.profile.dump_stats(self.tmpfile.name)
  50. return pstats.Stats(self.tmpfile.name)
  51. class HotshotMiddleware(BaseMiddleware):
  52. """
  53. Displays hotshot profiling for any view.
  54. http://yoursite.com/yourview/?prof
  55. Based on http://djangosnippets.org/snippets/186/
  56. """
  57. query_param = 'hotshot'
  58. def profiler(self):
  59. return hotshot.Profile(self.tmpfile.name)
  60. def stats(self):
  61. self.profile.close()
  62. return hotshot.stats.load(self.tmpfile.name)