121 |
130 |
122 def get_stats_from_global_or_request(request_obj): |
131 def get_stats_from_global_or_request(request_obj): |
123 "get pstats for a key, or the global pstats" |
132 "get pstats for a key, or the global pstats" |
124 key = request_obj.get('key', '') |
133 key = request_obj.get('key', '') |
125 if key: |
134 if key: |
126 return load_pstats_from_memcache(key) |
135 gp = GAEProfiler() |
|
136 gp.profile_obj = load_pstats_from_memcache(key) |
|
137 gp.profile_key = key |
|
138 return gp |
127 else: |
139 else: |
128 gp = get_global_profiler() |
140 gp = get_global_profiler() |
129 if not gp.has_profiler(): |
141 if not gp.has_profiler(): |
130 return None |
142 return None |
131 return gp.get_pstats() |
143 return gp |
|
144 |
|
145 def mime_upload_data_as_file(field_name, filename, body): |
|
146 part = Message() |
|
147 part['Content-Disposition'] = 'form-data; name="%s"; filename="%s"' % (field_name, filename) |
|
148 part['Content-Transfer-Encoding'] = 'binary' |
|
149 part['Content-Type'] = 'application/octet-stream' |
|
150 part['Content-Length'] = str(len(body)) |
|
151 part.set_payload(body) |
|
152 return part |
|
153 |
|
154 def mime_form_value(name, value): |
|
155 part = Message() |
|
156 part['Content-Disposition'] = 'form-data; name="%s"' % name |
|
157 part.set_payload(value) |
|
158 return part |
132 |
159 |
133 class show_profile(webapp.RequestHandler): |
160 class show_profile(webapp.RequestHandler): |
134 def get(self): |
161 def get(self): |
135 ps = get_stats_from_global_or_request(self.request) |
162 ps = get_stats_from_global_or_request(self.request) |
136 if not ps: |
163 if not ps: |
137 self.response.out.write("<body><html><h3>No profiler.</h3><html></body>") |
164 self.response.out.write("<body><html><h3>No profiler.</h3><html></body>") |
138 return |
165 return |
139 |
166 |
140 ps.set_output(self.response.out) |
167 ps.profile_obj.set_output(self.response.out) |
141 sort = self.request.get('sort', 'time') |
168 sort = self.request.get('sort', 'time') |
142 ps.sort_stats(sort) |
169 ps.profile_obj.sort_stats(sort) |
143 self.response.out.write("<body><html><pre>\n") |
170 self.response.out.write("<body><html><pre>\n") |
144 ps.print_stats(30) |
171 ps.profile_obj.print_stats(30) |
145 self.response.out.write("</pre></html></body>") |
172 self.response.out.write("</pre></html></body>") |
146 |
173 |
147 class download_profile_data(webapp.RequestHandler): |
174 class download_profile_data(webapp.RequestHandler): |
148 def get(self): |
175 def get(self): |
149 ps = get_stats_from_global_or_request(self.request) |
176 ps = get_stats_from_global_or_request(self.request) |
150 if not ps: |
177 if not ps: |
151 self.response.out.write("<body><html><h3>No profiler.</h3><html></body>") |
178 self.response.out.write("<body><html><h3>No profiler.</h3><html></body>") |
152 return |
179 return |
153 |
180 |
154 output = ps.dump_stats_pickle() |
181 output = ps.profile_obj.dump_stats_pickle() |
155 |
182 |
156 self.response.headers['Content-Type'] = 'application/octet-stream' |
183 self.response.headers['Content-Type'] = 'application/octet-stream' |
157 |
184 |
158 self.response.out.write(output) |
185 self.response.out.write(output) |
159 |
186 |
|
187 class send_profile_data(webapp.RequestHandler): |
|
188 def get(self): |
|
189 ps = get_stats_from_global_or_request(self.request) |
|
190 if not ps: |
|
191 self.response.out.write("<body><html><h3>No profiler.</h3><html></body>") |
|
192 return |
|
193 |
|
194 dest = self.request.get('dest', '') |
|
195 if not dest: |
|
196 self.response.out.write("<body><html>No destination</html></body>") |
|
197 |
|
198 upload_form = MIMEMultipart('form-data') |
|
199 |
|
200 upload_filename = 'profile.%s.pstats' % ps.profile_key |
|
201 upload_field_name = 'profile_file' |
|
202 |
|
203 upload_form.attach(mime_upload_data_as_file('profile_file', upload_field_name, zlib.compress(ps.profile_obj.dump_stats_pickle()))) |
|
204 upload_form.attach(mime_form_value('key_only', '1')) |
|
205 |
|
206 http_conn = httplib.HTTPConnection(dest) |
|
207 http_conn.connect() |
|
208 http_conn.request('POST', '/upload_profile', upload_form.as_string(), |
|
209 {'Content-Type': 'multipart/form-data; boundary=%s' % upload_form.get_boundary()}) |
|
210 |
|
211 http_resp = http_conn.getresponse() |
|
212 remote_data = http_resp.read() |
|
213 if http_resp.status == 200: |
|
214 remote_url = "http://%s/view_profile?key=%s" % (dest, remote_data) |
|
215 self.response.out.write("<html><body>Success! <a href='%s'>%s</a></body></html>" % (remote_url, remote_url)) |
|
216 else: |
|
217 self.response.out.write("Failure!\n%s: %s\n%s" % (http_resp.status, http_resp.reason, remote_data)) |
|
218 |
160 class show_profiler_status(webapp.RequestHandler): |
219 class show_profiler_status(webapp.RequestHandler): |
161 def get(self): |
220 def get(self): |
162 gp = get_global_profiler() |
221 gp = get_global_profiler() |
163 if not gp.has_profiler: |
222 if not gp.has_profiler: |
164 self.response.out.write("<body><html><h3>No profiler.</h3><html></body>") |
223 self.response.out.write("<body><html><h3>No profiler.</h3><html></body>") |
172 self.response.out.write("<b>Request regex:</b> %s<br>" % gp.request_regex) |
231 self.response.out.write("<b>Request regex:</b> %s<br>" % gp.request_regex) |
173 self.response.out.write("</body></html>") |
232 self.response.out.write("</body></html>") |
174 |
233 |
175 class start_profiler(webapp.RequestHandler): |
234 class start_profiler(webapp.RequestHandler): |
176 def get(self): |
235 def get(self): |
177 gp = get_global_profiler() |
236 gp = new_global_profiler() |
178 gp.start_profiling() |
237 gp.start_profiling() |
179 self.response.out.write("<html><body>") |
238 self.response.headers['Content-Type'] = "text/plain" |
180 self.response.out.write("Started profiling (key: %s). <br />" % gp.profile_key) |
239 self.response.out.write("Started profiling (key: %s).\n" % gp.profile_key) |
181 self.response.out.write("Retrieve saved results at " |
240 self.response.out.write("Retrieve saved results at <a href='/profiler/show?key=%(key)s'>/profiler/show?key=%(key)s).\n" % {'key':gp.profile_key}) |
182 "<a href='/profiler/show?key=%(key)s'>/profiler/show?key=%(key)s</a>. <br />" % {'key':gp.profile_key}) |
|
183 self.response.out.write("</body></html>") |
|
184 |
241 |
185 class stop_profiler(webapp.RequestHandler): |
242 class stop_profiler(webapp.RequestHandler): |
186 def get(self): |
243 def get(self): |
187 gp = get_global_profiler() |
244 gp = get_global_profiler() |
188 gp.stop_profiling() |
245 gp.stop_profiling() |
229 [('/profiler/start', start_profiler), |
286 [('/profiler/start', start_profiler), |
230 ('/profiler/stop', stop_profiler), |
287 ('/profiler/stop', stop_profiler), |
231 ('/profiler/show', show_profile), |
288 ('/profiler/show', show_profile), |
232 ('/profiler/download', download_profile_data), |
289 ('/profiler/download', download_profile_data), |
233 ('/profiler/status', show_profiler_status), |
290 ('/profiler/status', show_profiler_status), |
|
291 ('/profiler/send', send_profile_data), |
234 ], |
292 ], |
235 debug=True) |
293 debug=True) |
236 |
294 |
237 |
295 |
238 def main(): |
296 def main(): |