1 # -*- coding: utf-8 -*-
2 # Original version taken from http://www.djangosnippets.org/snippets/186/
3 # Original author: udfalkso
4 # Modified by: Shwagroo Team
15 from django.conf import settings
16 from django.db import connection
19 words_re = re.compile(r'\s+')
22 re.compile("^.*/django/[^/]+"),
23 re.compile("^(.*)/[^/]+$"), # extract module path
24 re.compile(".*"), # catch strange entries
28 class ProfileMiddleware(object):
30 Displays hotshot profiling for any view.
31 http://yoursite.com/yourview/?prof
33 Add the "prof" key to query string by appending ?prof (or &prof=)
34 and you'll see the profiling results in your browser.
35 It's set up to only be available in django's debug mode, is available for superuser otherwise,
36 but you really shouldn't add this middleware to any production configuration.
38 WARNING: It uses hotshot profiler which is not thread safe.
40 def process_request(self, request):
41 if (settings.DEBUG or request.user.is_superuser) and 'prof' in request.GET:
42 connection.queries = []
43 self.tmpfile = tempfile.mktemp()
44 self.prof = hotshot.Profile(self.tmpfile)
46 def process_view(self, request, callback, callback_args, callback_kwargs):
47 if (settings.DEBUG or request.user.is_superuser) and 'prof' in request.GET:
48 return self.prof.runcall(callback, request, *callback_args, **callback_kwargs)
50 def get_group(self, file):
51 for g in group_prefix_re:
52 name = g.findall(file)
56 def get_summary(self, results_dict, sum):
57 list = [(item[1], item[0]) for item in results_dict.items()]
58 list.sort(reverse=True)
67 res += "%4.1f%% %7.3f %s\n" % (foo, item[0], item[1])
71 def summary_for_files(self, stats_str):
72 stats_str = stats_str.split("\n")[5:]
80 fields = words_re.split(s)
82 time = float(fields[2])
84 file = fields[6].split(":")[0]
86 if file not in mystats:
90 group = self.get_group(file)
91 if group not in mygroups:
93 mygroups[group] += time
96 " ---- By file ----\n\n" + self.get_summary(mystats, sum) + "\n" + \
97 " ---- By group ---\n\n" + self.get_summary(mygroups, sum) + \
100 def process_response(self, request, response):
101 if (settings.DEBUG or request.user.is_superuser) and 'prof' in request.GET:
104 out = StringIO.StringIO()
105 old_stdout = sys.stdout
108 stats = hotshot.stats.load(self.tmpfile)
109 stats.sort_stats('time', 'calls')
112 sys.stdout = old_stdout
113 stats_str = out.getvalue()
115 if response and response.content and stats_str:
116 response.content = "<pre>" + stats_str + "</pre>"
118 response.content = "\n".join(response.content.split("\n")[:40])
120 response.content += self.summary_for_files(stats_str)
122 os.unlink(self.tmpfile)
124 response.content += '\n%d SQL Queries:\n' % len(connection.queries)
125 response.content += pprint.pformat(connection.queries)