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