Imported Upstream version 0+git200812222307
SVN-Git Migration
8 years ago
7 | 7 | Matt George <matt.george@myemma.com> |
8 | 8 | Adam Gomaa <adam@adam.gomaa.us> |
9 | 9 | Jacob Kaplan-Moss <jacob@jacobian.org> |
10 | Russell Keith-Magee <freakboy3742@gmail.com> | |
10 | 11 | Jannis Leidel <jannis@leidel.info> |
12 | Martin Maney <maney@two14.net> | |
11 | 13 | Nowell Strite <nowell@strite.org> |
12 | 14 | Malcolm Tredinnick <malcolm@pointy-stick.com> |
13 | 15 | Bryan Veloso <bryan@revyver.com> |
0 | include AUTHORS | |
1 | include LICENSE | |
2 | include README.rst | |
3 | recursive-include debug_toolbar/media * | |
4 | recursive-include debug_toolbar/templates * |
67 | 67 | panels you want to display. And you can include panels that you have created |
68 | 68 | or that are specific to your project. |
69 | 69 | |
70 | TODO | |
71 | ==== | |
72 | - Panel idea: AJAX call to show cprofile data similar to the ?prof idea | |
73 | - CSS Stylings | |
74 | - Restructure panels to popular context that pushes up to the toolbar | |
75 | - Make the trigger whether to display the toolbar configurable with options such | |
76 | as if: DEBUG is true, IP is in INTERNAL_IPS, authenticated user is_superuser, | |
77 | etc. | |
70 | TODOs and BUGS | |
71 | ============== | |
72 | See: http://code.google.com/p/django-debug-toolbar/issues/list |
43 | 43 | return True |
44 | 44 | |
45 | 45 | def process_request(self, request): |
46 | if self.override_url: | |
47 | debug_toolbar.urls.urlpatterns += self.original_pattern | |
48 | self.override_url = False | |
49 | request.urlconf = 'debug_toolbar.urls' | |
46 | if self.show_toolbar(request): | |
47 | if self.override_url: | |
48 | debug_toolbar.urls.urlpatterns += self.original_pattern | |
49 | self.override_url = False | |
50 | request.urlconf = 'debug_toolbar.urls' | |
50 | 51 | |
51 | if self.show_toolbar(request): | |
52 | 52 | self.debug_toolbar = DebugToolbar(request) |
53 | 53 | for panel in self.debug_toolbar.panels: |
54 | 54 | panel.process_request(request) |
47 | 47 | |
48 | 48 | def title(self): |
49 | 49 | self._sql_time = sum(map(lambda q: float(q['time']), connection.queries)) |
50 | num_queries = len(connection.queries) - self._offset | |
50 | 51 | return '%d SQL %s (%.2fms)' % ( |
51 | len(connection.queries), | |
52 | (len(connection.queries) == 1) and 'query' or 'queries', | |
52 | num_queries, | |
53 | (num_queries == 1) and 'query' or 'queries', | |
53 | 54 | self._sql_time |
54 | 55 | ) |
55 | 56 | |
64 | 65 | context = { |
65 | 66 | 'queries': sql_queries, |
66 | 67 | 'sql_time': self._sql_time, |
68 | 'is_mysql': settings.DATABASE_ENGINE == 'mysql', | |
67 | 69 | } |
68 | 70 | return render_to_string('debug_toolbar/panels/sql.html', context) |
69 | 71 | |
73 | 75 | sql = sql.replace('` FROM ', '`\nFROM\n\t') |
74 | 76 | sql = sql.replace(' WHERE ', '\nWHERE\n\t') |
75 | 77 | sql = sql.replace(' INNER JOIN ', '\nINNER JOIN\n\t') |
76 | sql = sql.replace(' OUTER JOIN ', '\nOUTER JOIN\n\t') | |
78 | sql = sql.replace(' LEFT OUTER JOIN ', '\nLEFT OUTER JOIN\n\t') | |
77 | 79 | sql = sql.replace(' ORDER BY ', '\nORDER BY\n\t') |
78 | 80 | # Use Pygments to highlight SQL if it's available |
79 | 81 | try: |
0 | try: | |
1 | import resource | |
2 | except ImportError: | |
3 | pass # Will fail on Win32 systems | |
0 | 4 | import time |
5 | from django.template.loader import render_to_string | |
1 | 6 | from debug_toolbar.panels import DebugPanel |
7 | ||
2 | 8 | |
3 | 9 | class TimerDebugPanel(DebugPanel): |
4 | 10 | """ |
5 | 11 | Panel that displays the time a response took in milliseconds. |
6 | 12 | """ |
7 | 13 | name = 'Timer' |
14 | try: # if resource module not available, don't show content panel | |
15 | resource | |
16 | except NameError: | |
17 | has_content = False | |
18 | has_resource = False | |
19 | else: | |
20 | has_content = True | |
21 | has_resource = True | |
8 | 22 | |
9 | 23 | def process_request(self, request): |
10 | 24 | self._start_time = time.time() |
25 | if self.has_resource: | |
26 | self._start_rusage = resource.getrusage(resource.RUSAGE_SELF) | |
11 | 27 | |
12 | 28 | def process_response(self, request, response): |
13 | 29 | self.total_time = (time.time() - self._start_time) * 1000 |
30 | if self.has_resource: | |
31 | self._end_rusage = resource.getrusage(resource.RUSAGE_SELF) | |
14 | 32 | |
15 | 33 | def title(self): |
16 | return 'Time: %0.2fms' % (self.total_time) | |
34 | if self.has_resource: | |
35 | utime = self._end_rusage.ru_utime - self._start_rusage.ru_utime | |
36 | stime = self._end_rusage.ru_stime - self._start_rusage.ru_stime | |
37 | return 'Time: %0.2fms, %0.2fms CPU' % (self.total_time, (utime + stime) * 1000.0) | |
38 | else: | |
39 | return 'Time: %0.2fms' % (self.total_time) | |
17 | 40 | |
18 | 41 | def url(self): |
19 | 42 | return '' |
20 | 43 | |
44 | def _elapsed_ru(self, name): | |
45 | return getattr(self._end_rusage, name) - getattr(self._start_rusage, name) | |
46 | ||
21 | 47 | def content(self): |
22 | return '' | |
48 | ||
49 | utime = 1000 * self._elapsed_ru('ru_utime') | |
50 | stime = 1000 * self._elapsed_ru('ru_stime') | |
51 | vcsw = self._elapsed_ru('ru_nvcsw') | |
52 | ivcsw = self._elapsed_ru('ru_nivcsw') | |
53 | minflt = self._elapsed_ru('ru_minflt') | |
54 | majflt = self._elapsed_ru('ru_majflt') | |
55 | ||
56 | # these are documented as not meaningful under Linux. If you're running BSD | |
57 | # feel free to enable them, and add any others that I hadn't gotten to before | |
58 | # I noticed that I was getting nothing but zeroes and that the docs agreed. :-( | |
59 | # | |
60 | # blkin = self._elapsed_ru('ru_inblock') | |
61 | # blkout = self._elapsed_ru('ru_oublock') | |
62 | # swap = self._elapsed_ru('ru_nswap') | |
63 | # rss = self._end_rusage.ru_maxrss | |
64 | # srss = self._end_rusage.ru_ixrss | |
65 | # urss = self._end_rusage.ru_idrss | |
66 | # usrss = self._end_rusage.ru_isrss | |
67 | ||
68 | rows = ( | |
69 | ('User CPU time', '%0.3f msec' % utime), | |
70 | ('System CPU time', '%0.3f msec' % stime), | |
71 | ('Total CPU time', '%0.3f msec' % (utime + stime)), | |
72 | ('Elapsed time', '%0.3f msec' % self.total_time), | |
73 | ('Context switches', '%d voluntary, %d involuntary' % (vcsw, ivcsw)), | |
74 | # ('Memory use', '%d max RSS, %d shared, %d unshared' % (rss, srss, urss + usrss)), | |
75 | # ('Page faults', '%d no i/o, %d requiring i/o' % (minflt, majflt)), | |
76 | # ('Disk operations', '%d in, %d out, %d swapout' % (blkin, blkout, swap)), | |
77 | ) | |
78 | context = { | |
79 | 'rows': rows, | |
80 | } | |
81 | return render_to_string('debug_toolbar/panels/timer.html', context) |
14 | 14 | {% if query.params %} |
15 | 15 | <a class="remoteCall" href="/__debug__/sql_select/?sql={{ query.raw_sql|urlencode }}¶ms={{ query.params|urlencode }}&time={{ query.time|floatformat:"2"|urlencode }}&hash={{ query.hash }}">SELECT</a> |
16 | 16 | <a class="remoteCall" href="/__debug__/sql_explain/?sql={{ query.raw_sql|urlencode }}¶ms={{ query.params|urlencode }}&time={{ query.time|floatformat:"2"|urlencode }}&hash={{ query.hash }}">EXPLAIN</a> |
17 | <a class="remoteCall" href="/__debug__/sql_profile/?sql={{ query.raw_sql|urlencode }}¶ms={{ query.params|urlencode }}&time={{ query.time|floatformat:"2"|urlencode }}&hash={{ query.hash }}">PROFILE</a> | |
17 | {% if is_mysql %} | |
18 | <a class="remoteCall" href="/__debug__/sql_profile/?sql={{ query.raw_sql|urlencode }}¶ms={{ query.params|urlencode }}&time={{ query.time|floatformat:"2"|urlencode }}&hash={{ query.hash }}">PROFILE</a> | |
19 | {% endif %} | |
18 | 20 | {% endif %} |
19 | 21 | </td> |
20 | 22 | <td class="syntax">{{ query.sql|safe }}</td> |
0 | <h3>Resource Usage</h3> | |
1 | <table> | |
2 | <colgroup> | |
3 | <col style="width:20%"/> | |
4 | <col/> | |
5 | </colgroup> | |
6 | <thead> | |
7 | <tr> | |
8 | <th>Key</th> | |
9 | <th>Value</th> | |
10 | </tr> | |
11 | </thead> | |
12 | <tbody> | |
13 | {% for key, value in rows %} | |
14 | <tr class="{% cycle 'odd' 'even' %}"> | |
15 | <td>{{ key|escape }}</td> | |
16 | <td>{{ value|escape }}</td> | |
17 | </tr> | |
18 | {% endfor %} | |
19 | </tbody> | |
20 | </table> |
0 | from setuptools import setup, find_packages | |
1 | ||
2 | setup( | |
3 | name='django-debug-toolbar', | |
4 | version=__import__('debug_toolbar').__version__, | |
5 | description='A configurable set of panels that display various debug information about the current request/response.', | |
6 | long_description=open('README.rst').read(), | |
7 | # Get more strings from http://www.python.org/pypi?:action=list_classifiers | |
8 | author='Rob Hudson', | |
9 | author_email='rob@cogit8.org', | |
10 | url='http://rob.cogit8.org/blog/2008/Sep/19/introducing-django-debug-toolbar/', | |
11 | #download_url='http://github.com/robhudson/django-debug-toolbar/tree/master', | |
12 | license='BSD', | |
13 | packages=find_packages(exclude=['ez_setup']), | |
14 | include_package_data=True, | |
15 | zip_safe=False, # because we're including media that Django needs | |
16 | classifiers=[ | |
17 | 'Development Status :: 4 - Beta', | |
18 | 'Environment :: Web Environment', | |
19 | 'Framework :: Django', | |
20 | 'Intended Audience :: Developers', | |
21 | 'License :: OSI Approved :: BSD License', | |
22 | 'Operating System :: OS Independent', | |
23 | 'Programming Language :: Python', | |
24 | 'Topic :: Software Development :: Libraries :: Python Modules', | |
25 | ], | |
26 | ) |