bbangert /
dozer
WSGI middleware fork of Robert Brewer's Dowser
Clone URL : http://bitbucket.org/bbangert/dozer/ (size: 146.1 KB)
| commit 36: | f1f70b805ed4 |
| parent 30: | 8b8e6861e08f |
| branch: | trunk |
added delete and show all actions
4 months ago
Changed (Δ1.0 KB):
raw changeset »
dozer/profile.py (41 lines added, 11 lines removed)
Up to file-list dozer/profile.py:
| … | … | @@ -50,14 +50,14 @@ class Profiler(object): |
50 |
50 |
if not getattr(method, 'exposed', False): |
51 |
51 |
return exc.HTTPForbidden('Access to %r is forbidden' % next_part) |
52 |
52 |
return method(req) |
53 |
||
53 |
||
54 |
54 |
def media(self, req): |
55 |
55 |
"""Static path where images and other files live""" |
56 |
56 |
path = resource_filename('dozer', 'media') |
57 |
57 |
app = urlparser.StaticURLParser(path) |
58 |
58 |
return app |
59 |
59 |
media.exposed = True |
60 |
||
60 |
||
61 |
61 |
def show(self, req): |
62 |
62 |
profile_id = req.path_info_pop() |
63 |
63 |
if not profile_id: |
| … | … | @@ -73,10 +73,40 @@ class Profiler(object): |
73 |
73 |
return res |
74 |
74 |
show.exposed = True |
75 |
75 |
|
76 |
def all(self, req): |
|
77 |
dir_name = self.profile_path |
|
78 |
link = '<a href="/_profiler/show/%(pid)s">%(pid)s</a>' |
|
79 |
profiles = [] |
|
80 |
for profile_file in os.listdir(dir_name): |
|
81 |
if profile_file.endswith('.pkl'): |
|
82 |
modified = os.stat( |
|
83 |
os.path.join(self.profile_path, profile_file) |
|
84 |
).st_mtime |
|
85 |
profiles.append((modified, profile_file)) |
|
86 |
profiles.sort(reverse=True) |
|
87 |
res = Response() |
|
88 |
if profiles: |
|
89 |
delete_link = ['<a href="/_profiler/delete">delete all profiles</a>'] |
|
90 |
res.body = '<br>'.join(delete_link + [link % {'pid': name[:-4]} for (m, name) in profiles]) |
|
91 |
else: |
|
92 |
res.body = 'no profiles' |
|
93 |
return res |
|
94 |
all.exposed = True |
|
95 |
||
96 |
def delete(self, req): |
|
97 |
for filename in os.listdir(self.profile_path): |
|
98 |
if filename.endswith('.pkl') or filename.endswith('.gz'): |
|
99 |
os.unlink(os.path.join(self.profile_path, filename)) |
|
100 |
res = Response() |
|
101 |
res.location = '/_profiler/all' |
|
102 |
res.status_int = 302 |
|
103 |
return res |
|
104 |
||
105 |
||
76 |
106 |
def render(self, name, **vars): |
77 |
107 |
tmpl = self.mako.get_template(name) |
78 |
108 |
return tmpl.render(**vars) |
79 |
||
109 |
||
80 |
110 |
def run_profile(self, environ, start_response): |
81 |
111 |
"""Run the profile over the request and save it""" |
82 |
112 |
prof = cProfile.Profile() |
| … | … | @@ -98,7 +128,7 @@ class Profiler(object): |
98 |
128 |
body = ''.join(response_body) |
99 |
129 |
results = prof.getstats() |
100 |
130 |
tree = buildtree(results) |
101 |
||
131 |
||
102 |
132 |
# Pull out 'safe' bits from environ |
103 |
133 |
safe_environ = {} |
104 |
134 |
for k, v in environ.iteritems(): |
| … | … | @@ -112,7 +142,7 @@ class Profiler(object): |
112 |
142 |
environ=safe_environ) |
113 |
143 |
fname_base = str(time.time()).replace('.', '_') |
114 |
144 |
prof_file = fname_base + '.pkl' |
115 |
||
145 |
||
116 |
146 |
dir_name = self.profile_path or '' |
117 |
147 |
cPickle.dump(profile_run, open(os.path.join(dir_name, prof_file), 'wb')) |
118 |
148 |
write_dot_graph(results, tree, os.path.join(dir_name, fname_base+'.gv')) |
| … | … | @@ -138,13 +168,13 @@ def setup_time(t): |
138 |
168 |
def setup_time(t): |
139 |
169 |
"""Takes a time generally assumed to be quite small and blows it |
140 |
170 |
up into millisecond time. |
141 |
||
171 |
||
142 |
172 |
For example: |
143 |
173 |
0.004 seconds -> 4 ms |
144 |
174 |
0.00025 seconds -> 0.25 ms |
145 |
||
175 |
||
146 |
176 |
The result is returned as a string. |
147 |
||
177 |
||
148 |
178 |
""" |
149 |
179 |
t = t*1000 |
150 |
180 |
t = '%0.2f' % t |
| … | … | @@ -155,13 +185,13 @@ def write_dot_graph(data, tree, filename |
155 |
185 |
f.write('digraph prof {\n') |
156 |
186 |
f.write('\tsize="11,9"; ratio = fill;\n') |
157 |
187 |
f.write('\tnode [style=filled];\n') |
158 |
||
188 |
||
159 |
189 |
# Find the largest time |
160 |
190 |
highest = 0.00 |
161 |
191 |
for entry in tree.values(): |
162 |
192 |
if float(entry['cost']) > highest: |
163 |
193 |
highest = float(entry['cost']) |
164 |
||
194 |
||
165 |
195 |
for entry in data: |
166 |
196 |
code = entry.code |
167 |
197 |
entry_name = graphlabel(code) |
| … | … | @@ -203,7 +233,7 @@ def buildtree(data): |
203 |
233 |
node['line_no'] = code.co_firstlineno |
204 |
234 |
node['cost'] = setup_time(entry.totaltime) |
205 |
235 |
node['function'] = label(code) |
206 |
||
236 |
||
207 |
237 |
if entry.calls: |
208 |
238 |
for subentry in entry.calls: |
209 |
239 |
subnode = {} |
