http://127.0.0.1:8000/anything/?prof
http://127.0.0.1:8000/anything/?cprof
http://127.0.0.1:8000/anything/?cprof=cumulative
cprof="cprofile_collums_to_sort"
http://127.0.0.1:8000/anything/?prof
http://127.0.0.1:8000/anything/?cprof
http://127.0.0.1:8000/anything/?cprof=cumulative
cprof="cprofile_collums_to_sort"
MIDDLEWARE_CLASSES = MIDDLEWARE_CLASSES + ( | |
'yourapp.middleware.ProfileMiddleware', | |
'yourapp.middleware.CProfileMiddleware' | |
) |
# Orignal version taken from http://www.djangosnippets.org/snippets/186/ | |
# Original author: udfalkso | |
# Modified by: Shwagroo Team and Gun.io | |
import sys | |
import os | |
import re | |
import hotshot | |
import hotshot.stats | |
import tempfile | |
import StringIO | |
from django.conf import settings | |
import cProfile | |
import pstats | |
import cStringIO | |
words_re = re.compile(r'\s+') | |
group_prefix_re = [ | |
re.compile("^.*/django/[^/]+"), | |
re.compile("^(.*)/[^/]+$"), # extract module path | |
re.compile(".*"), # catch strange entries | |
] | |
class ProfileMiddleware(object): | |
""" | |
Displays hotshot profiling for any view. | |
http://yoursite.com/yourview/?prof | |
Add the "prof" key to query string by appending ?prof (or &prof=) | |
and you'll see the profiling results in your browser. | |
It's set up to only be available in django's debug mode, is available for superuser otherwise, | |
but you really shouldn't add this middleware to any production configuration. | |
WARNING: It uses hotshot profiler which is not thread safe. | |
""" | |
def process_request(self, request): | |
if (settings.DEBUG or request.user.is_superuser) and 'prof' in request.GET: | |
self.tmpfile = tempfile.mktemp() | |
self.prof = hotshot.Profile(self.tmpfile) | |
def process_view(self, request, callback, callback_args, callback_kwargs): | |
if (settings.DEBUG or request.user.is_superuser) and 'prof' in request.GET: | |
return self.prof.runcall(callback, request, *callback_args, **callback_kwargs) | |
def get_group(self, file): | |
for g in group_prefix_re: | |
name = g.findall(file) | |
if name: | |
return name[0] | |
def get_summary(self, results_dict, sum): | |
list = [(item[1], item[0]) for item in results_dict.items()] | |
list.sort(reverse=True) | |
list = list[:40] | |
res = " tottime\n" | |
for item in list: | |
res += "%4.1f%% %7.3f %s\n" % (100*item[0]/sum if sum else 0, item[0], item[1]) | |
return res | |
def summary_for_files(self, stats_str): | |
stats_str = stats_str.split("\n")[5:] | |
mystats = {} | |
mygroups = {} | |
sum = 0 | |
for s in stats_str: | |
fields = words_re.split(s) | |
if len(fields) == 7: | |
time = float(fields[2]) | |
sum += time | |
file = fields[6].split(":")[0] | |
if not file in mystats: | |
mystats[file] = 0 | |
mystats[file] += time | |
group = self.get_group(file) | |
if not group in mygroups: | |
mygroups[group] = 0 | |
mygroups[group] += time | |
return "<pre>" + \ | |
" ---- By file ----\n\n" + self.get_summary(mystats, sum) + "\n" + \ | |
" ---- By group ---\n\n" + self.get_summary(mygroups, sum) + \ | |
"</pre>" | |
def process_response(self, request, response): | |
if (settings.DEBUG or request.user.is_superuser) and 'prof' in request.GET: | |
self.prof.close() | |
out = StringIO.StringIO() | |
old_stdout = sys.stdout | |
sys.stdout = out | |
stats = hotshot.stats.load(self.tmpfile) | |
stats.sort_stats('time', 'calls') | |
stats.print_stats() | |
sys.stdout = old_stdout | |
stats_str = out.getvalue() | |
if response and response.content and stats_str: | |
response.content = "<pre>" + stats_str + "</pre>" | |
response.content = "\n".join(response.content.split("\n")[:40]) | |
response.content += self.summary_for_files(stats_str) | |
os.unlink(self.tmpfile) | |
return response | |
class CProfileMiddleware(object): | |
def process_view(self, request, callback, callback_args, callback_kwargs): | |
if settings.DEBUG and 'cprof' in request.GET: | |
self.profiler = cProfile.Profile() | |
args = (request,) + callback_args | |
return self.profiler.runcall(callback, *args, **callback_kwargs) | |
def process_response(self, request, response): | |
if settings.DEBUG and 'cprof' in request.GET: | |
(fd, self.profiler_file) = tempfile.mkstemp() | |
self.profiler.dump_stats(self.profiler_file) | |
out = cStringIO.StringIO() | |
stats = pstats.Stats(self.profiler_file, stream=out) | |
stats.strip_dirs() # Must happen prior to sort_stats | |
if request.GET['cprof']: | |
stats.sort_stats(request.GET['cprof']) | |
stats.print_stats() | |
os.unlink(self.profiler_file) | |
response.content = '<pre>%s</pre>' % out.getvalue() | |
return response |