Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

middleware.py 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. from __future__ import print_function
  2. from __future__ import print_function
  3. import sys
  4. import tempfile
  5. import hotshot
  6. import hotshot.stats
  7. from cStringIO import StringIO
  8. import cProfile
  9. import pstats
  10. def profile_this(fn):
  11. def profiled_fn(*args, **kwargs):
  12. filepath = "/tmp/%s.profile" % fn.__name__
  13. prof = cProfile.Profile()
  14. ret = prof.runcall(fn, *args, **kwargs)
  15. print("Writing to %s" % filepath)
  16. prof.dump_stats(filepath)
  17. print("Printing stats")
  18. stats = pstats.Stats(filepath)
  19. stats.sort_stats('cumulative')
  20. stats.print_stats()
  21. return ret
  22. return profiled_fn
  23. class BaseMiddleware(object):
  24. query_param = None
  25. def show_profile(self, request):
  26. return self.query_param in request.GET
  27. def process_request(self, request):
  28. if self.show_profile(request):
  29. if 'prof_file' in request.GET:
  30. # It's sometimes useful to generate a file of output that can
  31. # converted for use with kcachegrind. To convert this file,
  32. # use:
  33. #
  34. # pyprof2calltree -o /tmp/callgrind.stats -i /tmp/out.stats
  35. #
  36. # then open the file in kcachegrind.
  37. self.tmpfile = open('/tmp/out.stats', 'w')
  38. else:
  39. self.tmpfile = tempfile.NamedTemporaryFile()
  40. self.profile = self.profiler()
  41. def profiler(self):
  42. return None
  43. def process_view(self, request, callback, callback_args, callback_kwargs):
  44. # We profile the view call - note that this misses the rest of Django's
  45. # request processing (eg middleware etc)
  46. if self.show_profile(request):
  47. return self.profile.runcall(
  48. callback, request, *callback_args, **callback_kwargs)
  49. def process_response(self, request, response):
  50. if self.show_profile(request):
  51. stats = self.stats()
  52. if 'prof_strip' in request.GET:
  53. stats.strip_dirs()
  54. if 'prof_sort' in request.GET:
  55. # See
  56. # http://docs.python.org/2/library/profile.html#pstats.Stats.sort_stats # noqa
  57. # for the fields you can sort on.
  58. stats.sort_stats(*request.GET['prof_sort'].split(','))
  59. else:
  60. stats.sort_stats('time', 'calls')
  61. # Capture STDOUT temporarily
  62. old_stdout = sys.stdout
  63. out = StringIO()
  64. sys.stdout = out
  65. stats.print_stats()
  66. stats_str = out.getvalue()
  67. sys.stdout.close()
  68. sys.stdout = old_stdout
  69. # Print status within PRE block
  70. if response and response.content and stats_str:
  71. response.content = "<pre>" + stats_str + "</pre>"
  72. return response
  73. class ProfileMiddleware(BaseMiddleware):
  74. query_param = 'cprofile'
  75. def profiler(self):
  76. return cProfile.Profile()
  77. def stats(self):
  78. self.profile.dump_stats(self.tmpfile.name)
  79. return pstats.Stats(self.tmpfile.name)
  80. class HotshotMiddleware(BaseMiddleware):
  81. """
  82. Displays hotshot profiling for any view.
  83. http://yoursite.com/yourview/?prof
  84. Based on http://djangosnippets.org/snippets/186/
  85. """
  86. query_param = 'hotshot'
  87. def profiler(self):
  88. return hotshot.Profile(self.tmpfile.name)
  89. def stats(self):
  90. self.profile.close()
  91. return hotshot.stats.load(self.tmpfile.name)