From 7a24088d0d4316e113387d229ed0491e31226348 Mon Sep 17 00:00:00 2001
From: bkonkle
Date: Fri, 9 Sep 2011 10:22:19 -0700
Subject: If a stacktrace frame is not in the expected format, skip over it
---
debug_toolbar/panels/sql.py | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py
index 841aaac..9687a5c 100644
--- a/debug_toolbar/panels/sql.py
+++ b/debug_toolbar/panels/sql.py
@@ -190,11 +190,15 @@ class SQLDebugPanel(DebugPanel):
query['start_offset'] = width_ratio_tally
query['end_offset'] = query['width_ratio'] + query['start_offset']
width_ratio_tally += query['width_ratio']
-
+
stacktrace = []
for frame in query['stacktrace']:
params = map(escape, frame[0].rsplit('/', 1) + list(frame[1:]))
- stacktrace.append(u'{0}/{1} in {3}({2})\n {4}'.format(*params))
+ try:
+ stacktrace.append(u'{0}/{1} in {3}({2})\n {4}'.format(*params))
+ except IndexError:
+ # This frame doesn't have the expected format, so skip it and move on to the next one
+ continue
query['stacktrace'] = mark_safe('\n'.join(stacktrace))
i += 1
--
cgit v1.2.3
From 358d2364f95d859bf75f0194b3ea2b66642f0529 Mon Sep 17 00:00:00 2001
From: Yann Malet
Date: Fri, 9 Sep 2011 23:48:35 +0200
Subject: Revert some of the previous changes and modify slightly the panels to
separate the gneration of the stats and the generation of the content.
---
debug_toolbar/middleware.py | 13 +++++++------
debug_toolbar/panels/cache.py | 12 ++++++++----
debug_toolbar/panels/sql.py | 35 +++++++++++++++++++----------------
3 files changed, 34 insertions(+), 26 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/middleware.py b/debug_toolbar/middleware.py
index f49a29f..1d332c0 100644
--- a/debug_toolbar/middleware.py
+++ b/debug_toolbar/middleware.py
@@ -5,7 +5,6 @@ import imp
import thread
from django.conf import settings
-from django.conf.urls.defaults import include, patterns
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.utils.encoding import smart_unicode
@@ -97,6 +96,7 @@ class DebugToolbarMiddleware(object):
for panel in toolbar.panels:
panel.process_request(request)
self.__class__.debug_toolbars[thread.get_ident()] = toolbar
+ request.debug_toolbar = toolbar
def process_view(self, request, view_func, view_args, view_kwargs):
__traceback_hide__ = True
@@ -124,13 +124,14 @@ class DebugToolbarMiddleware(object):
)
response.cookies = cookies
if 'gzip' not in response.get('Content-Encoding', '') and \
- response.get('Content-Type', '').split(';')[0] in _HTML_TYPES:
+ response.get('Content-Type', '').split(';')[0] in _HTML_TYPES:
+ toolbar.stats = {}
for panel in toolbar.panels:
- panel.process_response(request, response)
+ panel.process_response(request, response)
response.content = replace_insensitive(
- smart_unicode(response.content),
- self.tag,
- smart_unicode(toolbar.render_toolbar() + self.tag))
+ smart_unicode(response.content),
+ self.tag,
+ smart_unicode(toolbar.render_toolbar() + self.tag))
if response.get('Content-Length', None):
response['Content-Length'] = len(response.content)
del self.__class__.debug_toolbars[ident]
diff --git a/debug_toolbar/panels/cache.py b/debug_toolbar/panels/cache.py
index 5617ec2..c03971d 100644
--- a/debug_toolbar/panels/cache.py
+++ b/debug_toolbar/panels/cache.py
@@ -95,11 +95,15 @@ class CacheDebugPanel(DebugPanel):
def url(self):
return ''
- def content(self):
- context = self.context.copy()
- context.update({
+ def process_response(self, request, response):
+ self.stats = {
'cache_calls': len(self.cache.calls),
'cache_time': self.cache.total_time,
'cache': self.cache,
- })
+ }
+ request.debug_toolbar.stats['cache'] = self.stats
+
+ def content(self):
+ context = self.context.copy()
+ context.update(self.stats)
return render_to_string('debug_toolbar/panels/cache.html', context)
diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py
index 9687a5c..2eced7c 100644
--- a/debug_toolbar/panels/sql.py
+++ b/debug_toolbar/panels/sql.py
@@ -23,7 +23,7 @@ def cursor(func, self):
if not djdt:
return result
logger = djdt.get_panel(SQLDebugPanel)
-
+
return CursorWrapper(result, self, logger=logger)
def get_isolation_level_display(engine, level):
@@ -38,7 +38,7 @@ def get_isolation_level_display(engine, level):
}
else:
raise ValueError(engine)
-
+
return choices.get(level)
def get_transaction_status_display(engine, level):
@@ -53,7 +53,7 @@ def get_transaction_status_display(engine, level):
}
else:
raise ValueError(engine)
-
+
return choices.get(level)
class SQLDebugPanel(DebugPanel):
@@ -73,7 +73,7 @@ class SQLDebugPanel(DebugPanel):
self._databases = {}
self._transaction_status = {}
self._transaction_ids = {}
-
+
def get_transaction_id(self, alias):
conn = connections[alias].connection
if not conn:
@@ -97,9 +97,9 @@ class SQLDebugPanel(DebugPanel):
self._transaction_ids[alias] = uuid.uuid4().hex
else:
self._transaction_ids[alias] = None
-
+
return self._transaction_ids[alias]
-
+
def record(self, alias, **kwargs):
self._queries.append((alias, kwargs))
if alias not in self._databases:
@@ -126,7 +126,7 @@ class SQLDebugPanel(DebugPanel):
def title(self):
count = len(self._databases)
-
+
return __('SQL Queries from %(count)d connection', 'SQL Queries from %(count)d connections', count) % dict(
count=count,
)
@@ -134,7 +134,7 @@ class SQLDebugPanel(DebugPanel):
def url(self):
return ''
- def content(self):
+ def process_response(self, request, response):
if self._queries:
width_ratio_tally = 0
colors = [
@@ -157,14 +157,14 @@ class SQLDebugPanel(DebugPanel):
nn = 0
rgb[nn] = nc
db['rgb_color'] = rgb
-
+
trans_ids = {}
trans_id = None
i = 0
for alias, query in self._queries:
trans_id = query.get('trans_id')
last_trans_id = trans_ids.get(alias)
-
+
if trans_id != last_trans_id:
if last_trans_id:
self._queries[i-1][1]['ends_trans'] = True
@@ -173,7 +173,7 @@ class SQLDebugPanel(DebugPanel):
query['starts_trans'] = True
if trans_id:
query['in_trans'] = True
-
+
query['alias'] = alias
if 'iso_level' in query:
query['iso_level'] = get_isolation_level_display(query['engine'], query['iso_level'])
@@ -190,7 +190,7 @@ class SQLDebugPanel(DebugPanel):
query['start_offset'] = width_ratio_tally
query['end_offset'] = query['width_ratio'] + query['start_offset']
width_ratio_tally += query['width_ratio']
-
+
stacktrace = []
for frame in query['stacktrace']:
params = map(escape, frame[0].rsplit('/', 1) + list(frame[1:]))
@@ -204,14 +204,17 @@ class SQLDebugPanel(DebugPanel):
if trans_id:
self._queries[i-1][1]['ends_trans'] = True
-
- context = self.context.copy()
- context.update({
+
+ self.stats = {
'databases': sorted(self._databases.items(), key=lambda x: -x[1]['time_spent']),
'queries': [q for a, q in self._queries],
'sql_time': self._sql_time,
- })
+ }
+ request.debug_toolbar.stats['sql'] = getattr(self, 'stats', None)
+ def content(self):
+ context = self.context.copy()
+ context.update(self.stats)
return render_to_string('debug_toolbar/panels/sql.html', context)
class BoldKeywordFilter(sqlparse.filters.Filter):
--
cgit v1.2.3
From 970e084055c1210ff6251965bc87ad1b0d72ea0e Mon Sep 17 00:00:00 2001
From: Yann Malet
Date: Sat, 10 Sep 2011 00:01:15 +0200
Subject: Populate the stats['headers'] on the request.debug_toolbar
---
debug_toolbar/panels/headers.py | 3 +++
1 file changed, 3 insertions(+)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/panels/headers.py b/debug_toolbar/panels/headers.py
index 1e929f6..cedd3ee 100644
--- a/debug_toolbar/panels/headers.py
+++ b/debug_toolbar/panels/headers.py
@@ -46,6 +46,9 @@ class HeaderDebugPanel(DebugPanel):
[(k, request.META[k]) for k in self.header_filter if k in request.META]
)
+ def process_response(self, request, response):
+ request.debug_toolbar.stats['headers'] = self.headers
+
def content(self):
context = self.context.copy()
context.update({
--
cgit v1.2.3
From a08238af1ec07e077a0ee0f816d82c62c3f0ac63 Mon Sep 17 00:00:00 2001
From: Yann Malet
Date: Sat, 10 Sep 2011 01:24:32 +0200
Subject: Revert some of the previous changes and modify slightly the panels to
separate the gneration of the stats and the generation of the content.
---
debug_toolbar/panels/cache.py | 1 +
debug_toolbar/panels/profiling.py | 47 ++++++++++++++++++++-------------------
debug_toolbar/panels/sql.py | 1 +
3 files changed, 26 insertions(+), 23 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/panels/cache.py b/debug_toolbar/panels/cache.py
index c03971d..4cc783e 100644
--- a/debug_toolbar/panels/cache.py
+++ b/debug_toolbar/panels/cache.py
@@ -102,6 +102,7 @@ class CacheDebugPanel(DebugPanel):
'cache': self.cache,
}
request.debug_toolbar.stats['cache'] = self.stats
+ return response
def content(self):
context = self.context.copy()
diff --git a/debug_toolbar/panels/profiling.py b/debug_toolbar/panels/profiling.py
index 289e1f7..623b27a 100644
--- a/debug_toolbar/panels/profiling.py
+++ b/debug_toolbar/panels/profiling.py
@@ -8,9 +8,9 @@ from debug_toolbar.panels import DebugPanel
try:
from line_profiler import LineProfiler, show_func
DJ_PROFILE_USE_LINE_PROFILER = True
-except ImportError:
+except ImportError:
DJ_PROFILE_USE_LINE_PROFILER = False
-
+
from cStringIO import StringIO
import cProfile
@@ -20,7 +20,7 @@ import os
class DjangoDebugToolbarStats(Stats):
__root = None
-
+
def get_root_func(self):
if self.__root is None:
for func, (cc, nc, tt, ct, callers) in self.stats.iteritems():
@@ -28,7 +28,7 @@ class DjangoDebugToolbarStats(Stats):
self.__root = func
break
return self.__root
-
+
class FunctionCall(object):
def __init__(self, statobj, func, depth=0, stats=None, id=0, parent_ids=[], hsv=(0,0.5,1)):
self.statobj = statobj
@@ -42,14 +42,14 @@ class FunctionCall(object):
self.parent_ids = parent_ids
self.hsv = hsv
self._line_stats_text = None
-
+
def parent_classes(self):
return self.parent_classes
-
+
def background(self):
r,g,b = hsv_to_rgb(*self.hsv)
return 'rgb(%f%%,%f%%,%f%%)' %(r*100, g*100, b*100)
-
+
def func_std_string(self): # match what old profile produced
func_name = self.func
if func_name[:2] == ('~', 0):
@@ -64,16 +64,16 @@ class FunctionCall(object):
idx = file_name.find('/site-packages/')
if idx > -1:
file_name=file_name[idx+14:]
-
+
file_path, file_name = file_name.rsplit(os.sep, 1)
-
+
return mark_safe('{0}/{1} in {3}({2})'.format(
file_path,
file_name,
line_num,
method,
))
-
+
def subfuncs(self):
i=0
h,s,v = self.hsv
@@ -86,23 +86,23 @@ class FunctionCall(object):
else:
s1 = s*(stats[3]/self.stats[3])
yield FunctionCall(self.statobj,
- func,
- self.depth+1,
+ func,
+ self.depth+1,
stats=stats,
id=str(self.id) + '_' + str(i),
parent_ids=self.parent_ids + [self.id],
hsv=(h1,s1,1))
-
+
def count(self):
return self.stats[1]
-
+
def tottime(self):
return self.stats[2]
-
+
def cumtime(self):
cc, nc, tt, ct = self.stats
return self.stats[3]
-
+
def tottime_per_call(self):
cc, nc, tt, ct = self.stats
@@ -110,7 +110,7 @@ class FunctionCall(object):
return 0
return tt/nc
-
+
def cumtime_per_call(self):
cc, nc, tt, ct = self.stats
@@ -121,7 +121,7 @@ class FunctionCall(object):
def indent(self):
return 16 * self.depth
-
+
def line_stats_text(self):
if self._line_stats_text is None:
lstats = self.statobj.line_stats
@@ -146,7 +146,7 @@ class ProfilingDebugPanel(DebugPanel):
def url(self):
return ''
-
+
def title(self):
return _('Profiling')
@@ -179,6 +179,8 @@ class ProfilingDebugPanel(DebugPanel):
self.stats = DjangoDebugToolbarStats(self.profiler)
if DJ_PROFILE_USE_LINE_PROFILER:
self.stats.line_stats = self.line_profiler.get_stats()
+ self.stats.calc_callees()
+ request.debug_toolbar.stats['profiling'] = self.stats
return response
def add_node(self, func_list, func, max_depth, cum_time=0.1):
@@ -189,12 +191,11 @@ class ProfilingDebugPanel(DebugPanel):
if subfunc.stats[3] >= cum_time or (subfunc.func in self.stats.line_stats.timings):
func.has_subfuncs = True
self.add_node(func_list, subfunc, max_depth, cum_time=cum_time)
-
+
def content(self):
-
- self.stats.calc_callees()
+ import ipdb; ipdb.set_trace()
root = FunctionCall(self.stats, self.stats.get_root_func(), depth=0)
-
+
func_list = []
self.add_node(func_list, root, 10, root.stats[3]/8)
context = self.context.copy()
diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py
index 2eced7c..bfe52d9 100644
--- a/debug_toolbar/panels/sql.py
+++ b/debug_toolbar/panels/sql.py
@@ -211,6 +211,7 @@ class SQLDebugPanel(DebugPanel):
'sql_time': self._sql_time,
}
request.debug_toolbar.stats['sql'] = getattr(self, 'stats', None)
+ return response
def content(self):
context = self.context.copy()
--
cgit v1.2.3
From dddfb118720733a0956440663d659653875b2dd9 Mon Sep 17 00:00:00 2001
From: Yann Malet
Date: Sat, 10 Sep 2011 02:25:53 +0200
Subject: Apply the same changes to the timer panel
---
debug_toolbar/panels/timer.py | 64 ++++++++++++++++++++++++-------------------
1 file changed, 36 insertions(+), 28 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/panels/timer.py b/debug_toolbar/panels/timer.py
index d866166..ef32988 100644
--- a/debug_toolbar/panels/timer.py
+++ b/debug_toolbar/panels/timer.py
@@ -27,10 +27,38 @@ class TimerDebugPanel(DebugPanel):
self._start_rusage = resource.getrusage(resource.RUSAGE_SELF)
def process_response(self, request, response):
- self.total_time = (time.time() - self._start_time) * 1000
+ total_time = (time.time() - self._start_time) * 1000
if self.has_resource:
self._end_rusage = resource.getrusage(resource.RUSAGE_SELF)
+ utime = 1000 * self._elapsed_ru('ru_utime')
+ stime = 1000 * self._elapsed_ru('ru_stime')
+ vcsw = self._elapsed_ru('ru_nvcsw')
+ ivcsw = self._elapsed_ru('ru_nivcsw')
+ minflt = self._elapsed_ru('ru_minflt')
+ majflt = self._elapsed_ru('ru_majflt')
+# these are documented as not meaningful under Linux. If you're running BSD
+# feel free to enable them, and add any others that I hadn't gotten to before
+# I noticed that I was getting nothing but zeroes and that the docs agreed. :-(
+#
+# blkin = self._elapsed_ru('ru_inblock')
+# blkout = self._elapsed_ru('ru_oublock')
+# swap = self._elapsed_ru('ru_nswap')
+# rss = self._end_rusage.ru_maxrss
+# srss = self._end_rusage.ru_ixrss
+# urss = self._end_rusage.ru_idrss
+# usrss = self._end_rusage.ru_isrss
+
+ self.stats = {
+ 'total_time': total_time,
+ 'utime': utime,
+ 'stime': stime,
+ 'vcsw': vcsw,
+ 'ivcsw': ivcsw,
+ 'minflt': minflt,
+ 'majflt': majflt,
+ }
+
def nav_title(self):
return _('Time')
@@ -39,9 +67,9 @@ class TimerDebugPanel(DebugPanel):
if self.has_resource:
utime = self._end_rusage.ru_utime - self._start_rusage.ru_utime
stime = self._end_rusage.ru_stime - self._start_rusage.ru_stime
- return 'CPU: %0.2fms (%0.2fms)' % ((utime + stime) * 1000.0, self.total_time)
+ return 'CPU: %0.2fms (%0.2fms)' % ((utime + stime) * 1000.0, self.stats['total_time'])
else:
- return 'TOTAL: %0.2fms' % (self.total_time)
+ return 'TOTAL: %0.2fms' % (self.stats[total_time])
def title(self):
return _('Resource Usage')
@@ -53,33 +81,13 @@ class TimerDebugPanel(DebugPanel):
return getattr(self._end_rusage, name) - getattr(self._start_rusage, name)
def content(self):
-
- utime = 1000 * self._elapsed_ru('ru_utime')
- stime = 1000 * self._elapsed_ru('ru_stime')
- vcsw = self._elapsed_ru('ru_nvcsw')
- ivcsw = self._elapsed_ru('ru_nivcsw')
- minflt = self._elapsed_ru('ru_minflt')
- majflt = self._elapsed_ru('ru_majflt')
-
-# these are documented as not meaningful under Linux. If you're running BSD
-# feel free to enable them, and add any others that I hadn't gotten to before
-# I noticed that I was getting nothing but zeroes and that the docs agreed. :-(
-#
-# blkin = self._elapsed_ru('ru_inblock')
-# blkout = self._elapsed_ru('ru_oublock')
-# swap = self._elapsed_ru('ru_nswap')
-# rss = self._end_rusage.ru_maxrss
-# srss = self._end_rusage.ru_ixrss
-# urss = self._end_rusage.ru_idrss
-# usrss = self._end_rusage.ru_isrss
-
# TODO l10n on values
rows = (
- (_('User CPU time'), '%0.3f msec' % utime),
- (_('System CPU time'), '%0.3f msec' % stime),
- (_('Total CPU time'), '%0.3f msec' % (utime + stime)),
- (_('Elapsed time'), '%0.3f msec' % self.total_time),
- (_('Context switches'), '%d voluntary, %d involuntary' % (vcsw, ivcsw)),
+ (_('User CPU time'), '%0.3f msec' % self.stats['utime']),
+ (_('System CPU time'), '%0.3f msec' % self.stats['stime']),
+ (_('Total CPU time'), '%0.3f msec' % (self.stats['utime'] + self.stats['stime'])),
+ (_('Elapsed time'), '%0.3f msec' % self.stats['total_time']),
+ (_('Context switches'), '%d voluntary, %d involuntary' % (self.stats['vcsw'], self.stats['ivcsw'])),
# ('Memory use', '%d max RSS, %d shared, %d unshared' % (rss, srss, urss + usrss)),
# ('Page faults', '%d no i/o, %d requiring i/o' % (minflt, majflt)),
# ('Disk operations', '%d in, %d out, %d swapout' % (blkin, blkout, swap)),
--
cgit v1.2.3
From 83357d374f6741a5cf50da5c4f3f29934ed3281b Mon Sep 17 00:00:00 2001
From: Yann Malet
Date: Sat, 10 Sep 2011 02:36:38 +0200
Subject: Also add the BSD specific value and comment them out
---
debug_toolbar/panels/timer.py | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/panels/timer.py b/debug_toolbar/panels/timer.py
index ef32988..43cc202 100644
--- a/debug_toolbar/panels/timer.py
+++ b/debug_toolbar/panels/timer.py
@@ -57,6 +57,13 @@ class TimerDebugPanel(DebugPanel):
'ivcsw': ivcsw,
'minflt': minflt,
'majflt': majflt,
+# 'blkin': blkin,
+# 'blkout': blkout,
+# 'swap': swap,
+# 'rss': rss,
+# 'urss': urss,
+# 'srss': srss,
+# 'usrss': usrss,
}
def nav_title(self):
@@ -88,9 +95,10 @@ class TimerDebugPanel(DebugPanel):
(_('Total CPU time'), '%0.3f msec' % (self.stats['utime'] + self.stats['stime'])),
(_('Elapsed time'), '%0.3f msec' % self.stats['total_time']),
(_('Context switches'), '%d voluntary, %d involuntary' % (self.stats['vcsw'], self.stats['ivcsw'])),
-# ('Memory use', '%d max RSS, %d shared, %d unshared' % (rss, srss, urss + usrss)),
-# ('Page faults', '%d no i/o, %d requiring i/o' % (minflt, majflt)),
-# ('Disk operations', '%d in, %d out, %d swapout' % (blkin, blkout, swap)),
+# ('Memory use', '%d max RSS, %d shared, %d unshared' % (self.stats['rss'], self.stats.['srss'],
+# self.stats['urss'] + self.stats['usrss'])),
+# ('Page faults', '%d no i/o, %d requiring i/o' % (self.stats['minflt'], self.stats['majflt'])),
+# ('Disk operations', '%d in, %d out, %d swapout' % (self.stats['blkin'], self.stats['blkout'], self.stats['swap'])),
)
context = self.context.copy()
--
cgit v1.2.3
From d3649d340a9a7e20235fa63615830b9b0b7edbdd Mon Sep 17 00:00:00 2001
From: Yann Malet
Date: Sun, 11 Sep 2011 05:16:47 +0200
Subject: Fix the profiling panel when the line_profiler module is not
available.
---
debug_toolbar/panels/profiling.py | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/panels/profiling.py b/debug_toolbar/panels/profiling.py
index 623b27a..e57aa97 100644
--- a/debug_toolbar/panels/profiling.py
+++ b/debug_toolbar/panels/profiling.py
@@ -123,7 +123,8 @@ class FunctionCall(object):
return 16 * self.depth
def line_stats_text(self):
- if self._line_stats_text is None:
+ if (self._line_stats_text is None and
+ DJ_PROFILE_USE_LINE_PROFILER):
lstats = self.statobj.line_stats
if self.func in lstats.timings:
out = StringIO()
@@ -188,12 +189,13 @@ class ProfilingDebugPanel(DebugPanel):
func.has_subfuncs = False
if func.depth < max_depth:
for subfunc in func.subfuncs():
- if subfunc.stats[3] >= cum_time or (subfunc.func in self.stats.line_stats.timings):
+ if (subfunc.stats[3] >= cum_time or
+ (hasattr(self.stats, 'line_stats') and
+ (subfunc.func in self.stats.line_stats.timings))):
func.has_subfuncs = True
self.add_node(func_list, subfunc, max_depth, cum_time=cum_time)
def content(self):
- import ipdb; ipdb.set_trace()
root = FunctionCall(self.stats, self.stats.get_root_func(), depth=0)
func_list = []
--
cgit v1.2.3
From 2682e29116522cb64fd6e7c9d776a1e3b4c25a3a Mon Sep 17 00:00:00 2001
From: Yann Malet
Date: Sun, 11 Sep 2011 05:30:17 +0200
Subject: pep 8 compliance
---
debug_toolbar/panels/profiling.py | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/panels/profiling.py b/debug_toolbar/panels/profiling.py
index e57aa97..01ae1e0 100644
--- a/debug_toolbar/panels/profiling.py
+++ b/debug_toolbar/panels/profiling.py
@@ -18,6 +18,7 @@ from pstats import Stats
from colorsys import hsv_to_rgb
import os
+
class DjangoDebugToolbarStats(Stats):
__root = None
@@ -29,8 +30,10 @@ class DjangoDebugToolbarStats(Stats):
break
return self.__root
+
class FunctionCall(object):
- def __init__(self, statobj, func, depth=0, stats=None, id=0, parent_ids=[], hsv=(0,0.5,1)):
+ def __init__(self, statobj, func, depth=0, stats=None,
+ id=0, parent_ids=[], hsv=(0,0.5,1)):
self.statobj = statobj
self.func = func
if stats:
@@ -50,7 +53,7 @@ class FunctionCall(object):
r,g,b = hsv_to_rgb(*self.hsv)
return 'rgb(%f%%,%f%%,%f%%)' %(r*100, g*100, b*100)
- def func_std_string(self): # match what old profile produced
+ def func_std_string(self): # match what old profile produced
func_name = self.func
if func_name[:2] == ('~', 0):
# special case for built-in functions
@@ -63,7 +66,7 @@ class FunctionCall(object):
file_name, line_num, method = self.func
idx = file_name.find('/site-packages/')
if idx > -1:
- file_name=file_name[idx+14:]
+ file_name = file_name[idx+14:]
file_path, file_name = file_name.rsplit(os.sep, 1)
@@ -76,7 +79,7 @@ class FunctionCall(object):
def subfuncs(self):
i=0
- h,s,v = self.hsv
+ h, s, v = self.hsv
count = len(self.statobj.all_callees[self.func])
for func, stats in self.statobj.all_callees[self.func].iteritems():
i += 1
--
cgit v1.2.3
From e0aa1e9dd987cc43996647b6096fb6a21b77ab29 Mon Sep 17 00:00:00 2001
From: Yann Malet
Date: Sun, 11 Sep 2011 06:01:08 +0200
Subject: linting- Remove unused import
---
debug_toolbar/panels/version.py | 1 -
1 file changed, 1 deletion(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/panels/version.py b/debug_toolbar/panels/version.py
index f0d8fbc..e042732 100644
--- a/debug_toolbar/panels/version.py
+++ b/debug_toolbar/panels/version.py
@@ -5,7 +5,6 @@ from django.conf import settings
from django.template.loader import render_to_string
from django.utils.translation import ugettext_lazy as _
-import debug_toolbar
from debug_toolbar.panels import DebugPanel
--
cgit v1.2.3
From 7dfb666ae92ba2831926a003d26480a00a5dff30 Mon Sep 17 00:00:00 2001
From: Yann Malet
Date: Sun, 11 Sep 2011 06:18:59 +0200
Subject: Modify the Version panel
---
debug_toolbar/panels/version.py | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/panels/version.py b/debug_toolbar/panels/version.py
index e042732..76e44ed 100644
--- a/debug_toolbar/panels/version.py
+++ b/debug_toolbar/panels/version.py
@@ -23,11 +23,11 @@ class VersionDebugPanel(DebugPanel):
def url(self):
return ''
-
+
def title(self):
return _('Versions')
- def content(self):
+ def process_response(self, request, response):
versions = {}
versions['Python'] = '%d.%d.%d' % sys.version_info[:3]
for app in settings.INSTALLED_APPS + ['django']:
@@ -49,11 +49,15 @@ class VersionDebugPanel(DebugPanel):
if isinstance(version, (list, tuple)):
version = '.'.join(str(o) for o in version)
versions[name] = version
+ self.stats = {
+ 'versions': versions,
+ 'paths': sys.path
+ }
+ request.debug_toolbar.stats['versions'] = self.stats['versions']
+ request.debug_toolbar.stats['paths'] = self.stats['paths']
+ return response
+ def content(self):
context = self.context.copy()
- context.update({
- 'versions': versions,
- 'paths': sys.path,
- })
-
+ context.update(self.stats)
return render_to_string('debug_toolbar/panels/versions.html', context)
--
cgit v1.2.3
From b77aec6160d66ee1ecff2687d74724ce74ea8ff5 Mon Sep 17 00:00:00 2001
From: bkonkle
Date: Mon, 12 Sep 2011 11:21:29 -0500
Subject: Don't add the toolbar to the request object until the end of the
process_response method
---
debug_toolbar/middleware.py | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/middleware.py b/debug_toolbar/middleware.py
index 1d332c0..b014f33 100644
--- a/debug_toolbar/middleware.py
+++ b/debug_toolbar/middleware.py
@@ -96,7 +96,6 @@ class DebugToolbarMiddleware(object):
for panel in toolbar.panels:
panel.process_request(request)
self.__class__.debug_toolbars[thread.get_ident()] = toolbar
- request.debug_toolbar = toolbar
def process_view(self, request, view_func, view_args, view_kwargs):
__traceback_hide__ = True
@@ -127,12 +126,15 @@ class DebugToolbarMiddleware(object):
response.get('Content-Type', '').split(';')[0] in _HTML_TYPES:
toolbar.stats = {}
for panel in toolbar.panels:
- panel.process_response(request, response)
+ panel.process_response(request, response)
response.content = replace_insensitive(
- smart_unicode(response.content),
- self.tag,
- smart_unicode(toolbar.render_toolbar() + self.tag))
+ smart_unicode(response.content),
+ self.tag,
+ smart_unicode(toolbar.render_toolbar() + self.tag))
if response.get('Content-Length', None):
response['Content-Length'] = len(response.content)
+ # Add the toolbar to the request object, so that the stats are
+ # available to subsequent middleware classes.
+ request.debug_toolbar = toolbar
del self.__class__.debug_toolbars[ident]
return response
--
cgit v1.2.3
From 74a7c2f3209b8561e71a140842877ee89fc6c725 Mon Sep 17 00:00:00 2001
From: bkonkle
Date: Mon, 12 Sep 2011 11:25:35 -0500
Subject: Update the cache panel to use the toolbar object
---
debug_toolbar/panels/cache.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/panels/cache.py b/debug_toolbar/panels/cache.py
index 4cc783e..bbfed66 100644
--- a/debug_toolbar/panels/cache.py
+++ b/debug_toolbar/panels/cache.py
@@ -5,6 +5,7 @@ from django.core import cache
from django.core.cache.backends.base import BaseCache
from django.template.loader import render_to_string
from django.utils.translation import ugettext_lazy as _
+from debug_toolbar.middleware import DebugToolbarMiddleware
from debug_toolbar.panels import DebugPanel
class CacheStatTracker(BaseCache):
@@ -101,8 +102,8 @@ class CacheDebugPanel(DebugPanel):
'cache_time': self.cache.total_time,
'cache': self.cache,
}
- request.debug_toolbar.stats['cache'] = self.stats
- return response
+ toolbar = DebugToolbarMiddleware.get_current()
+ toolbar.stats['cache'] = self.stats
def content(self):
context = self.context.copy()
--
cgit v1.2.3
From d9e9d8bbddb9986db79047a40194232f1baadf50 Mon Sep 17 00:00:00 2001
From: bkonkle
Date: Mon, 12 Sep 2011 11:33:18 -0500
Subject: Tweaked the sql panel
---
debug_toolbar/panels/sql.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py
index bfe52d9..2c36336 100644
--- a/debug_toolbar/panels/sql.py
+++ b/debug_toolbar/panels/sql.py
@@ -210,8 +210,8 @@ class SQLDebugPanel(DebugPanel):
'queries': [q for a, q in self._queries],
'sql_time': self._sql_time,
}
- request.debug_toolbar.stats['sql'] = getattr(self, 'stats', None)
- return response
+ toolbar = DebugToolbarMiddleware.get_current()
+ toolbar.stats['sql'] = self.stats
def content(self):
context = self.context.copy()
--
cgit v1.2.3
From 48dca6e339b6e22de0ae2a570c0c71ff98831886 Mon Sep 17 00:00:00 2001
From: bkonkle
Date: Mon, 12 Sep 2011 11:38:46 -0500
Subject: Cleaned up whitespace in the SQL and cache panels
---
debug_toolbar/panels/cache.py | 24 ++++++++++-----------
debug_toolbar/panels/sql.py | 50 +++++++++++++++++++++----------------------
2 files changed, 37 insertions(+), 37 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/panels/cache.py b/debug_toolbar/panels/cache.py
index bbfed66..ad3f844 100644
--- a/debug_toolbar/panels/cache.py
+++ b/debug_toolbar/panels/cache.py
@@ -13,7 +13,7 @@ class CacheStatTracker(BaseCache):
def __init__(self, cache):
self.cache = cache
self.reset()
-
+
def reset(self):
self.calls = []
self.hits = 0
@@ -23,11 +23,11 @@ class CacheStatTracker(BaseCache):
self.get_many = 0
self.deletes = 0
self.total_time = 0
-
+
def _get_func_info(self):
stack = inspect.stack()[2]
return (stack[1], stack[2], stack[3], stack[4])
-
+
def get(self, key, default=None):
t = time.time()
value = self.cache.get(key, default)
@@ -40,7 +40,7 @@ class CacheStatTracker(BaseCache):
self.gets += 1
self.calls.append((this_time, 'get', (key,), self._get_func_info()))
return value
-
+
def set(self, key, value, timeout=None):
t = time.time()
self.cache.set(key, value, timeout)
@@ -48,7 +48,7 @@ class CacheStatTracker(BaseCache):
self.total_time += this_time * 1000
self.sets += 1
self.calls.append((this_time, 'set', (key, value, timeout), self._get_func_info()))
-
+
def delete(self, key):
t = time.time()
self.cache.delete(key)
@@ -56,7 +56,7 @@ class CacheStatTracker(BaseCache):
self.total_time += this_time * 1000
self.deletes += 1
self.calls.append((this_time, 'delete', (key,), self._get_func_info()))
-
+
def get_many(self, keys):
t = time.time()
results = self.cache.get_many(keys)
@@ -76,7 +76,7 @@ class CacheDebugPanel(DebugPanel):
"""
name = 'Cache'
has_content = True
-
+
def __init__(self, *args, **kwargs):
super(self.__class__, self).__init__(*args, **kwargs)
# This is hackish but to prevent threading issues is somewhat needed
@@ -86,16 +86,16 @@ class CacheDebugPanel(DebugPanel):
else:
self.cache = CacheStatTracker(cache.cache)
cache.cache = self.cache
-
+
def nav_title(self):
return _('Cache: %.2fms') % self.cache.total_time
-
+
def title(self):
return _('Cache Usage')
-
+
def url(self):
return ''
-
+
def process_response(self, request, response):
self.stats = {
'cache_calls': len(self.cache.calls),
@@ -104,7 +104,7 @@ class CacheDebugPanel(DebugPanel):
}
toolbar = DebugToolbarMiddleware.get_current()
toolbar.stats['cache'] = self.stats
-
+
def content(self):
context = self.context.copy()
context.update(self.stats)
diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py
index 2c36336..9527410 100644
--- a/debug_toolbar/panels/sql.py
+++ b/debug_toolbar/panels/sql.py
@@ -18,12 +18,12 @@ from debug_toolbar.utils.tracking import replace_call
@replace_call(BaseDatabaseWrapper.cursor)
def cursor(func, self):
result = func(self)
-
+
djdt = DebugToolbarMiddleware.get_current()
if not djdt:
return result
logger = djdt.get_panel(SQLDebugPanel)
-
+
return CursorWrapper(result, self, logger=logger)
def get_isolation_level_display(engine, level):
@@ -38,7 +38,7 @@ def get_isolation_level_display(engine, level):
}
else:
raise ValueError(engine)
-
+
return choices.get(level)
def get_transaction_status_display(engine, level):
@@ -53,7 +53,7 @@ def get_transaction_status_display(engine, level):
}
else:
raise ValueError(engine)
-
+
return choices.get(level)
class SQLDebugPanel(DebugPanel):
@@ -63,7 +63,7 @@ class SQLDebugPanel(DebugPanel):
"""
name = 'SQL'
has_content = True
-
+
def __init__(self, *args, **kwargs):
super(self.__class__, self).__init__(*args, **kwargs)
self._offset = dict((k, len(connections[k].queries)) for k in connections)
@@ -73,33 +73,33 @@ class SQLDebugPanel(DebugPanel):
self._databases = {}
self._transaction_status = {}
self._transaction_ids = {}
-
+
def get_transaction_id(self, alias):
conn = connections[alias].connection
if not conn:
return None
-
+
engine = conn.__class__.__module__.split('.', 1)[0]
if engine == 'psycopg2':
cur_status = conn.get_transaction_status()
else:
raise ValueError(engine)
-
+
last_status = self._transaction_status.get(alias)
self._transaction_status[alias] = cur_status
-
+
if not cur_status:
# No available state
return None
-
+
if cur_status != last_status:
if cur_status:
self._transaction_ids[alias] = uuid.uuid4().hex
else:
self._transaction_ids[alias] = None
-
+
return self._transaction_ids[alias]
-
+
def record(self, alias, **kwargs):
self._queries.append((alias, kwargs))
if alias not in self._databases:
@@ -112,10 +112,10 @@ class SQLDebugPanel(DebugPanel):
self._databases[alias]['num_queries'] += 1
self._sql_time += kwargs['duration']
self._num_queries += 1
-
+
def nav_title(self):
return _('SQL')
-
+
def nav_subtitle(self):
# TODO l10n: use ngettext
return "%d %s in %.2fms" % (
@@ -123,17 +123,17 @@ class SQLDebugPanel(DebugPanel):
(self._num_queries == 1) and 'query' or 'queries',
self._sql_time
)
-
+
def title(self):
count = len(self._databases)
-
+
return __('SQL Queries from %(count)d connection', 'SQL Queries from %(count)d connections', count) % dict(
count=count,
)
-
+
def url(self):
return ''
-
+
def process_response(self, request, response):
if self._queries:
width_ratio_tally = 0
@@ -157,14 +157,14 @@ class SQLDebugPanel(DebugPanel):
nn = 0
rgb[nn] = nc
db['rgb_color'] = rgb
-
+
trans_ids = {}
trans_id = None
i = 0
for alias, query in self._queries:
trans_id = query.get('trans_id')
last_trans_id = trans_ids.get(alias)
-
+
if trans_id != last_trans_id:
if last_trans_id:
self._queries[i-1][1]['ends_trans'] = True
@@ -173,7 +173,7 @@ class SQLDebugPanel(DebugPanel):
query['starts_trans'] = True
if trans_id:
query['in_trans'] = True
-
+
query['alias'] = alias
if 'iso_level' in query:
query['iso_level'] = get_isolation_level_display(query['engine'], query['iso_level'])
@@ -190,7 +190,7 @@ class SQLDebugPanel(DebugPanel):
query['start_offset'] = width_ratio_tally
query['end_offset'] = query['width_ratio'] + query['start_offset']
width_ratio_tally += query['width_ratio']
-
+
stacktrace = []
for frame in query['stacktrace']:
params = map(escape, frame[0].rsplit('/', 1) + list(frame[1:]))
@@ -201,10 +201,10 @@ class SQLDebugPanel(DebugPanel):
continue
query['stacktrace'] = mark_safe('\n'.join(stacktrace))
i += 1
-
+
if trans_id:
self._queries[i-1][1]['ends_trans'] = True
-
+
self.stats = {
'databases': sorted(self._databases.items(), key=lambda x: -x[1]['time_spent']),
'queries': [q for a, q in self._queries],
@@ -212,7 +212,7 @@ class SQLDebugPanel(DebugPanel):
}
toolbar = DebugToolbarMiddleware.get_current()
toolbar.stats['sql'] = self.stats
-
+
def content(self):
context = self.context.copy()
context.update(self.stats)
--
cgit v1.2.3
From f8759c9f0d64a90ac0e1942e735c27c662ab05b1 Mon Sep 17 00:00:00 2001
From: bkonkle
Date: Mon, 12 Sep 2011 11:54:19 -0500
Subject: Tweaked the profiling panel
---
debug_toolbar/panels/profiling.py | 64 +++++++++++++++++++--------------------
1 file changed, 32 insertions(+), 32 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/panels/profiling.py b/debug_toolbar/panels/profiling.py
index 01ae1e0..26f7888 100644
--- a/debug_toolbar/panels/profiling.py
+++ b/debug_toolbar/panels/profiling.py
@@ -21,7 +21,7 @@ import os
class DjangoDebugToolbarStats(Stats):
__root = None
-
+
def get_root_func(self):
if self.__root is None:
for func, (cc, nc, tt, ct, callers) in self.stats.iteritems():
@@ -45,15 +45,15 @@ class FunctionCall(object):
self.parent_ids = parent_ids
self.hsv = hsv
self._line_stats_text = None
-
+
def parent_classes(self):
return self.parent_classes
-
+
def background(self):
r,g,b = hsv_to_rgb(*self.hsv)
return 'rgb(%f%%,%f%%,%f%%)' %(r*100, g*100, b*100)
-
- def func_std_string(self): # match what old profile produced
+
+ def func_std_string(self): # match what old profile produced
func_name = self.func
if func_name[:2] == ('~', 0):
# special case for built-in functions
@@ -67,16 +67,16 @@ class FunctionCall(object):
idx = file_name.find('/site-packages/')
if idx > -1:
file_name = file_name[idx+14:]
-
+
file_path, file_name = file_name.rsplit(os.sep, 1)
-
+
return mark_safe('{0}/{1} in {3}({2})'.format(
file_path,
file_name,
line_num,
method,
))
-
+
def subfuncs(self):
i=0
h, s, v = self.hsv
@@ -95,39 +95,38 @@ class FunctionCall(object):
id=str(self.id) + '_' + str(i),
parent_ids=self.parent_ids + [self.id],
hsv=(h1,s1,1))
-
+
def count(self):
return self.stats[1]
-
+
def tottime(self):
return self.stats[2]
-
+
def cumtime(self):
cc, nc, tt, ct = self.stats
return self.stats[3]
-
+
def tottime_per_call(self):
cc, nc, tt, ct = self.stats
-
+
if nc == 0:
return 0
-
+
return tt/nc
-
+
def cumtime_per_call(self):
cc, nc, tt, ct = self.stats
-
+
if cc == 0:
return 0
-
+
return ct/cc
-
+
def indent(self):
return 16 * self.depth
-
+
def line_stats_text(self):
- if (self._line_stats_text is None and
- DJ_PROFILE_USE_LINE_PROFILER):
+ if self._line_stats_text is None and DJ_PROFILE_USE_LINE_PROFILER:
lstats = self.statobj.line_stats
if self.func in lstats.timings:
out = StringIO()
@@ -144,16 +143,16 @@ class ProfilingDebugPanel(DebugPanel):
"""
name = 'Profiling'
has_content = True
-
+
def nav_title(self):
return _('Profiling')
-
+
def url(self):
return ''
-
+
def title(self):
return _('Profiling')
-
+
def _unwrap_closure_and_profile(self, func):
if not hasattr(func, 'func_code'):
return
@@ -162,7 +161,7 @@ class ProfilingDebugPanel(DebugPanel):
for cell in func.func_closure:
if hasattr(cell.cell_contents, 'func_code'):
self._unwrap_closure_and_profile(cell.cell_contents)
-
+
def process_view(self, request, view_func, view_args, view_kwargs):
__traceback_hide__ = True
self.profiler = cProfile.Profile()
@@ -177,16 +176,17 @@ class ProfilingDebugPanel(DebugPanel):
self.line_profiler = None
out = self.profiler.runcall(view_func, *args, **view_kwargs)
return out
-
+
def process_response(self, request, response):
self.profiler.create_stats()
self.stats = DjangoDebugToolbarStats(self.profiler)
if DJ_PROFILE_USE_LINE_PROFILER:
self.stats.line_stats = self.line_profiler.get_stats()
self.stats.calc_callees()
- request.debug_toolbar.stats['profiling'] = self.stats
+ toolbar = DebugToolbarMiddleware.get_current()
+ toolbar.stats['profiling'] = self.stats
return response
-
+
def add_node(self, func_list, func, max_depth, cum_time=0.1):
func_list.append(func)
func.has_subfuncs = False
@@ -197,15 +197,15 @@ class ProfilingDebugPanel(DebugPanel):
(subfunc.func in self.stats.line_stats.timings))):
func.has_subfuncs = True
self.add_node(func_list, subfunc, max_depth, cum_time=cum_time)
-
+
def content(self):
root = FunctionCall(self.stats, self.stats.get_root_func(), depth=0)
-
+
func_list = []
self.add_node(func_list, root, 10, root.stats[3]/8)
context = self.context.copy()
context.update({
'func_list': func_list,
})
-
+
return render_to_string('debug_toolbar/panels/profiling.html', context)
--
cgit v1.2.3
From 6c005d703941fc60dd8ecc07ad8bdaf3e27b2950 Mon Sep 17 00:00:00 2001
From: bkonkle
Date: Mon, 12 Sep 2011 11:59:44 -0500
Subject: Tweaks to the timer panel, and a correction to the profiling panel
---
debug_toolbar/panels/profiling.py | 1 +
debug_toolbar/panels/timer.py | 34 +++++++++++++++++++---------------
2 files changed, 20 insertions(+), 15 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/panels/profiling.py b/debug_toolbar/panels/profiling.py
index 26f7888..e08591a 100644
--- a/debug_toolbar/panels/profiling.py
+++ b/debug_toolbar/panels/profiling.py
@@ -3,6 +3,7 @@ from __future__ import division
from django.template.loader import render_to_string
from django.utils.translation import ugettext_lazy as _
from django.utils.safestring import mark_safe
+from debug_toolbar.middleware import DebugToolbarMiddleware
from debug_toolbar.panels import DebugPanel
try:
diff --git a/debug_toolbar/panels/timer.py b/debug_toolbar/panels/timer.py
index 43cc202..1e44212 100644
--- a/debug_toolbar/panels/timer.py
+++ b/debug_toolbar/panels/timer.py
@@ -5,6 +5,7 @@ except ImportError:
import time
from django.template.loader import render_to_string
from django.utils.translation import ugettext_lazy as _
+from debug_toolbar.middleware import DebugToolbarMiddleware
from debug_toolbar.panels import DebugPanel
class TimerDebugPanel(DebugPanel):
@@ -50,21 +51,24 @@ class TimerDebugPanel(DebugPanel):
# usrss = self._end_rusage.ru_isrss
self.stats = {
- 'total_time': total_time,
- 'utime': utime,
- 'stime': stime,
- 'vcsw': vcsw,
- 'ivcsw': ivcsw,
- 'minflt': minflt,
- 'majflt': majflt,
-# 'blkin': blkin,
-# 'blkout': blkout,
-# 'swap': swap,
-# 'rss': rss,
-# 'urss': urss,
-# 'srss': srss,
-# 'usrss': usrss,
- }
+ 'total_time': total_time,
+ 'utime': utime,
+ 'stime': stime,
+ 'vcsw': vcsw,
+ 'ivcsw': ivcsw,
+ 'minflt': minflt,
+ 'majflt': majflt,
+# 'blkin': blkin,
+# 'blkout': blkout,
+# 'swap': swap,
+# 'rss': rss,
+# 'urss': urss,
+# 'srss': srss,
+# 'usrss': usrss,
+ }
+
+ toolbar = DebugToolbarMiddleware.get_current()
+ toolbar.stats['timer'] = self.stats
def nav_title(self):
return _('Time')
--
cgit v1.2.3
From e99c3acd249cc05e1e85ec9a60b5a87685a79f78 Mon Sep 17 00:00:00 2001
From: bkonkle
Date: Mon, 12 Sep 2011 12:02:25 -0500
Subject: Tweaks to the version panel, and whitespace corrections for the timer
panel
---
debug_toolbar/panels/timer.py | 24 ++++++++++++------------
debug_toolbar/panels/version.py | 14 ++++++++------
2 files changed, 20 insertions(+), 18 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/panels/timer.py b/debug_toolbar/panels/timer.py
index 1e44212..466e5c0 100644
--- a/debug_toolbar/panels/timer.py
+++ b/debug_toolbar/panels/timer.py
@@ -21,17 +21,17 @@ class TimerDebugPanel(DebugPanel):
else:
has_content = True
has_resource = True
-
+
def process_request(self, request):
self._start_time = time.time()
if self.has_resource:
self._start_rusage = resource.getrusage(resource.RUSAGE_SELF)
-
+
def process_response(self, request, response):
total_time = (time.time() - self._start_time) * 1000
if self.has_resource:
self._end_rusage = resource.getrusage(resource.RUSAGE_SELF)
-
+
utime = 1000 * self._elapsed_ru('ru_utime')
stime = 1000 * self._elapsed_ru('ru_stime')
vcsw = self._elapsed_ru('ru_nvcsw')
@@ -49,7 +49,7 @@ class TimerDebugPanel(DebugPanel):
# srss = self._end_rusage.ru_ixrss
# urss = self._end_rusage.ru_idrss
# usrss = self._end_rusage.ru_isrss
-
+
self.stats = {
'total_time': total_time,
'utime': utime,
@@ -69,10 +69,10 @@ class TimerDebugPanel(DebugPanel):
toolbar = DebugToolbarMiddleware.get_current()
toolbar.stats['timer'] = self.stats
-
+
def nav_title(self):
return _('Time')
-
+
def nav_subtitle(self):
# TODO l10n
if self.has_resource:
@@ -81,16 +81,16 @@ class TimerDebugPanel(DebugPanel):
return 'CPU: %0.2fms (%0.2fms)' % ((utime + stime) * 1000.0, self.stats['total_time'])
else:
return 'TOTAL: %0.2fms' % (self.stats[total_time])
-
+
def title(self):
return _('Resource Usage')
-
+
def url(self):
return ''
-
+
def _elapsed_ru(self, name):
return getattr(self._end_rusage, name) - getattr(self._start_rusage, name)
-
+
def content(self):
# TODO l10n on values
rows = (
@@ -104,10 +104,10 @@ class TimerDebugPanel(DebugPanel):
# ('Page faults', '%d no i/o, %d requiring i/o' % (self.stats['minflt'], self.stats['majflt'])),
# ('Disk operations', '%d in, %d out, %d swapout' % (self.stats['blkin'], self.stats['blkout'], self.stats['swap'])),
)
-
+
context = self.context.copy()
context.update({
'rows': rows,
})
-
+
return render_to_string('debug_toolbar/panels/timer.html', context)
diff --git a/debug_toolbar/panels/version.py b/debug_toolbar/panels/version.py
index 76e44ed..c18da63 100644
--- a/debug_toolbar/panels/version.py
+++ b/debug_toolbar/panels/version.py
@@ -5,6 +5,7 @@ from django.conf import settings
from django.template.loader import render_to_string
from django.utils.translation import ugettext_lazy as _
+from debug_toolbar.middleware import DebugToolbarMiddleware
from debug_toolbar.panels import DebugPanel
@@ -49,13 +50,14 @@ class VersionDebugPanel(DebugPanel):
if isinstance(version, (list, tuple)):
version = '.'.join(str(o) for o in version)
versions[name] = version
+
self.stats = {
- 'versions': versions,
- 'paths': sys.path
- }
- request.debug_toolbar.stats['versions'] = self.stats['versions']
- request.debug_toolbar.stats['paths'] = self.stats['paths']
- return response
+ 'versions': versions,
+ 'paths': sys.path,
+ }
+
+ toolbar = DebugToolbarMiddleware.get_current()
+ toolbar.stats['version'] = self.stats
def content(self):
context = self.context.copy()
--
cgit v1.2.3
From 2b3dc54bccff7463c100b689f84d2af259f1db77 Mon Sep 17 00:00:00 2001
From: bkonkle
Date: Mon, 12 Sep 2011 12:02:39 -0500
Subject: Minor whitespace correction for the version panel
---
debug_toolbar/panels/version.py | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/panels/version.py b/debug_toolbar/panels/version.py
index c18da63..6a7c54e 100644
--- a/debug_toolbar/panels/version.py
+++ b/debug_toolbar/panels/version.py
@@ -15,19 +15,19 @@ class VersionDebugPanel(DebugPanel):
"""
name = 'Version'
has_content = True
-
+
def nav_title(self):
return _('Versions')
-
+
def nav_subtitle(self):
return 'Django %s' % django.get_version()
-
+
def url(self):
return ''
-
+
def title(self):
return _('Versions')
-
+
def process_response(self, request, response):
versions = {}
versions['Python'] = '%d.%d.%d' % sys.version_info[:3]
@@ -58,7 +58,7 @@ class VersionDebugPanel(DebugPanel):
toolbar = DebugToolbarMiddleware.get_current()
toolbar.stats['version'] = self.stats
-
+
def content(self):
context = self.context.copy()
context.update(self.stats)
--
cgit v1.2.3
From 5f7a6aa2658c019eddf5696fec051199fe0e64ec Mon Sep 17 00:00:00 2001
From: bkonkle
Date: Mon, 12 Sep 2011 12:04:53 -0500
Subject: Updated the headers panel
---
debug_toolbar/panels/headers.py | 24 +++++++++++++++---------
1 file changed, 15 insertions(+), 9 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/panels/headers.py b/debug_toolbar/panels/headers.py
index cedd3ee..4c94dd9 100644
--- a/debug_toolbar/panels/headers.py
+++ b/debug_toolbar/panels/headers.py
@@ -1,6 +1,8 @@
from django.template.loader import render_to_string
from django.utils.translation import ugettext_lazy as _
from debug_toolbar.panels import DebugPanel
+from debug_toolbar.middleware import DebugToolbarMiddleware
+
class HeaderDebugPanel(DebugPanel):
"""
@@ -31,27 +33,31 @@ class HeaderDebugPanel(DebugPanel):
'SERVER_PROTOCOL',
'SERVER_SOFTWARE',
)
-
+
def nav_title(self):
return _('HTTP Headers')
-
+
def title(self):
return _('HTTP Headers')
-
+
def url(self):
return ''
-
+
def process_request(self, request):
self.headers = dict(
[(k, request.META[k]) for k in self.header_filter if k in request.META]
)
-
+ self.stats = {
+ 'headers': self.headers
+ }
+ toolbar = DebugToolbarMiddleware.get_current()
+ toolbar.stats['headers'] = self.stats
+
+
def process_response(self, request, response):
request.debug_toolbar.stats['headers'] = self.headers
-
+
def content(self):
context = self.context.copy()
- context.update({
- 'headers': self.headers
- })
+ context.update(self.stats)
return render_to_string('debug_toolbar/panels/headers.html', context)
--
cgit v1.2.3
From 12decd75ddaf805b8a2f333102f2752161338eb9 Mon Sep 17 00:00:00 2001
From: bkonkle
Date: Mon, 12 Sep 2011 12:07:01 -0500
Subject: Updated the logger panel
---
debug_toolbar/panels/logger.py | 39 ++++++++++++++++++++++-----------------
1 file changed, 22 insertions(+), 17 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/panels/logger.py b/debug_toolbar/panels/logger.py
index 5e82a13..ba34700 100644
--- a/debug_toolbar/panels/logger.py
+++ b/debug_toolbar/panels/logger.py
@@ -7,6 +7,7 @@ except ImportError:
from django.template.loader import render_to_string
from django.utils.translation import ugettext_lazy as _
from debug_toolbar.panels import DebugPanel
+from debug_toolbar.middleware import DebugToolbarMiddleware
class LogCollector(object):
@@ -15,15 +16,15 @@ class LogCollector(object):
raise NotImplementedError("threading module is not available, \
the logging panel cannot be used without it")
self.records = {} # a dictionary that maps threads to log records
-
+
def add_record(self, record, thread=None):
# Avoid logging SQL queries since they are already in the SQL panel
# TODO: Make this check whether SQL panel is enabled
if record.get('channel', '') == 'django.db.backends':
return
-
+
self.get_records(thread).append(record)
-
+
def get_records(self, thread=None):
"""
Returns a list of records for the provided thread, of if none is provided,
@@ -34,7 +35,7 @@ class LogCollector(object):
if thread not in self.records:
self.records[thread] = []
return self.records[thread]
-
+
def clear_records(self, thread=None):
if thread is None:
thread = threading.currentThread()
@@ -46,7 +47,7 @@ class ThreadTrackingHandler(logging.Handler):
def __init__(self, collector):
logging.Handler.__init__(self)
self.collector = collector
-
+
def emit(self, record):
record = {
'message': record.getMessage(),
@@ -76,7 +77,7 @@ if logbook_supported:
def __init__(self, collector):
logbook.handlers.Handler.__init__(self, bubble=True)
self.collector = collector
-
+
def emit(self, record):
record = {
'message': record.message,
@@ -88,39 +89,43 @@ if logbook_supported:
}
self.collector.add_record(record)
-
+
logbook_handler = LogbookThreadTrackingHandler(collector)
logbook_handler.push_application() # register with logbook
class LoggingPanel(DebugPanel):
name = 'Logging'
has_content = True
-
+
def process_request(self, request):
collector.clear_records()
-
+
+ def process_response(self, request, response):
+ records = self.get_and_delete()
+ self.stats = {'records': records}
+ toolbar = DebugToolbarMiddleware.get_current()
+ toolbar.stats['logger'] = self.stats
+
def get_and_delete(self):
records = collector.get_records()
collector.clear_records()
return records
-
+
def nav_title(self):
return _("Logging")
-
+
def nav_subtitle(self):
# FIXME l10n: use ngettext
return "%s message%s" % (len(collector.get_records()), (len(collector.get_records()) == 1) and '' or 's')
-
+
def title(self):
return _('Log Messages')
-
+
def url(self):
return ''
-
+
def content(self):
- records = self.get_and_delete()
context = self.context.copy()
- context.update({'records': records})
-
+ context.update(self.stats)
return render_to_string('debug_toolbar/panels/logger.html', context)
--
cgit v1.2.3
From 3e06ce8a73d03a9f1c7ab1a424c8dfd350d99ec4 Mon Sep 17 00:00:00 2001
From: bkonkle
Date: Mon, 12 Sep 2011 12:10:38 -0500
Subject: Updated the request_vars panel
---
debug_toolbar/panels/request_vars.py | 40 +++++++++++++++++++++---------------
1 file changed, 23 insertions(+), 17 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/panels/request_vars.py b/debug_toolbar/panels/request_vars.py
index 9033d48..80cd018 100644
--- a/debug_toolbar/panels/request_vars.py
+++ b/debug_toolbar/panels/request_vars.py
@@ -1,6 +1,7 @@
from django.template.loader import render_to_string
from django.utils.translation import ugettext_lazy as _
+from debug_toolbar.middleware import DebugToolbarMiddleware
from debug_toolbar.panels import DebugPanel
from debug_toolbar.utils import get_name_from_obj
@@ -10,53 +11,58 @@ class RequestVarsDebugPanel(DebugPanel):
"""
name = 'RequestVars'
has_content = True
-
+
def __init__(self, *args, **kwargs):
DebugPanel.__init__(self, *args, **kwargs)
self.view_func = None
self.view_args = None
self.view_kwargs = None
-
+
def nav_title(self):
return _('Request Vars')
-
+
def title(self):
return _('Request Vars')
-
+
def url(self):
return ''
-
+
def process_request(self, request):
self.request = request
-
+
def process_view(self, request, view_func, view_args, view_kwargs):
self.view_func = view_func
self.view_args = view_args
self.view_kwargs = view_kwargs
-
- def content(self):
- context = self.context.copy()
-
- context.update({
+
+ def process_response(self, request, response):
+ self.stats = {
'get': [(k, self.request.GET.getlist(k)) for k in self.request.GET],
'post': [(k, self.request.POST.getlist(k)) for k in self.request.POST],
'cookies': [(k, self.request.COOKIES.get(k)) for k in self.request.COOKIES],
- })
+ }
+
if hasattr(self, 'view_func'):
if self.view_func is not None:
name = get_name_from_obj(self.view_func)
else:
name = ''
-
- context.update({
+
+ self.stats.update({
'view_func': name,
'view_args': self.view_args,
'view_kwargs': self.view_kwargs
})
-
+
if hasattr(self.request, 'session'):
- context.update({
+ self.stats.update({
'session': [(k, self.request.session.get(k)) for k in self.request.session.iterkeys()]
})
-
+
+ toolbar = DebugToolbarMiddleware.get_current()
+ toolbar.stats['request_vars'] = self.stats
+
+ def content(self):
+ context = self.context.copy()
+ context.update(self.stats)
return render_to_string('debug_toolbar/panels/request_vars.html', context)
--
cgit v1.2.3
From fa8e9aab09cd47370749e1a03f2e90e6a7a93faf Mon Sep 17 00:00:00 2001
From: bkonkle
Date: Mon, 12 Sep 2011 12:11:38 -0500
Subject: Updated the settings_vars panel
---
debug_toolbar/panels/settings_vars.py | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/panels/settings_vars.py b/debug_toolbar/panels/settings_vars.py
index ebb4464..029496e 100644
--- a/debug_toolbar/panels/settings_vars.py
+++ b/debug_toolbar/panels/settings_vars.py
@@ -2,6 +2,7 @@ from django.conf import settings
from django.template.loader import render_to_string
from django.views.debug import get_safe_settings
from django.utils.translation import ugettext_lazy as _
+from debug_toolbar.middleware import DebugToolbarMiddleware
from debug_toolbar.panels import DebugPanel
@@ -11,19 +12,24 @@ class SettingsVarsDebugPanel(DebugPanel):
"""
name = 'SettingsVars'
has_content = True
-
+
def nav_title(self):
return _('Settings')
-
+
def title(self):
return _('Settings from %s') % settings.SETTINGS_MODULE
-
+
def url(self):
return ''
-
+
+ def process_response(self, request, response):
+ self.stats = {
+ 'settings': get_safe_settings(),
+ }
+ toolbar = DebugToolbarMiddleware.get_current()
+ toolbar.stats['settings_vars'] = self.stats
+
def content(self):
context = self.context.copy()
- context.update({
- 'settings': get_safe_settings(),
- })
+ context.update(self.stats)
return render_to_string('debug_toolbar/panels/settings_vars.html', context)
--
cgit v1.2.3
From 2519b2cc5cda4b462de108cac1d9dd2fae2e9dd4 Mon Sep 17 00:00:00 2001
From: bkonkle
Date: Mon, 12 Sep 2011 12:12:58 -0500
Subject: Updated the signals panel
---
debug_toolbar/panels/signals.py | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/panels/signals.py b/debug_toolbar/panels/signals.py
index dbd3725..9855299 100644
--- a/debug_toolbar/panels/signals.py
+++ b/debug_toolbar/panels/signals.py
@@ -14,12 +14,13 @@ try:
except ImportError:
connection_created = None
+from debug_toolbar.middleware import DebugToolbarMiddleware
from debug_toolbar.panels import DebugPanel
class SignalDebugPanel(DebugPanel):
name = "Signals"
has_content = True
-
+
SIGNALS = {
'request_started': request_started,
'request_finished': request_finished,
@@ -34,16 +35,16 @@ class SignalDebugPanel(DebugPanel):
'post_delete': post_delete,
'post_syncdb': post_syncdb,
}
-
+
def nav_title(self):
return _("Signals")
-
+
def title(self):
return _("Signals")
-
+
def url(self):
return ''
-
+
def signals(self):
signals = self.SIGNALS.copy()
if hasattr(settings, 'DEBUG_TOOLBAR_CONFIG'):
@@ -57,8 +58,8 @@ class SignalDebugPanel(DebugPanel):
signals[parts[-1]] = getattr(sys.modules[path], parts[-1])
return signals
signals = property(signals)
-
- def content(self):
+
+ def process_response(self, request, response):
signals = []
keys = self.signals.keys()
keys.sort()
@@ -80,8 +81,12 @@ class SignalDebugPanel(DebugPanel):
text = "function %s" % receiver.__name__
receivers.append(text)
signals.append((name, signal, receivers))
-
+
+ self.stats = {'signals': signals}
+ toolbar = DebugToolbarMiddleware.get_current()
+ toolbar.stats['signals'] = self.stats
+
+ def content(self):
context = self.context.copy()
- context.update({'signals': signals})
-
+ context.update(self.stats)
return render_to_string('debug_toolbar/panels/signals.html', context)
--
cgit v1.2.3
From 5b4553713775a35634594a65502e5ca8ba58dae9 Mon Sep 17 00:00:00 2001
From: bkonkle
Date: Mon, 12 Sep 2011 12:31:25 -0500
Subject: Updated the template panel, and corrected an issue in the headers
panel
---
debug_toolbar/middleware.py | 2 +-
debug_toolbar/panels/headers.py | 6 ++----
debug_toolbar/panels/template.py | 34 ++++++++++++++++++++--------------
3 files changed, 23 insertions(+), 19 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/middleware.py b/debug_toolbar/middleware.py
index b014f33..03b2804 100644
--- a/debug_toolbar/middleware.py
+++ b/debug_toolbar/middleware.py
@@ -123,7 +123,7 @@ class DebugToolbarMiddleware(object):
)
response.cookies = cookies
if 'gzip' not in response.get('Content-Encoding', '') and \
- response.get('Content-Type', '').split(';')[0] in _HTML_TYPES:
+ response.get('Content-Type', '').split(';')[0] in _HTML_TYPES:
toolbar.stats = {}
for panel in toolbar.panels:
panel.process_response(request, response)
diff --git a/debug_toolbar/panels/headers.py b/debug_toolbar/panels/headers.py
index 4c94dd9..a88fbd9 100644
--- a/debug_toolbar/panels/headers.py
+++ b/debug_toolbar/panels/headers.py
@@ -47,16 +47,14 @@ class HeaderDebugPanel(DebugPanel):
self.headers = dict(
[(k, request.META[k]) for k in self.header_filter if k in request.META]
)
+
+ def process_response(self, request, response):
self.stats = {
'headers': self.headers
}
toolbar = DebugToolbarMiddleware.get_current()
toolbar.stats['headers'] = self.stats
-
- def process_response(self, request, response):
- request.debug_toolbar.stats['headers'] = self.headers
-
def content(self):
context = self.context.copy()
context.update(self.stats)
diff --git a/debug_toolbar/panels/template.py b/debug_toolbar/panels/template.py
index d620a38..d0ab6cc 100644
--- a/debug_toolbar/panels/template.py
+++ b/debug_toolbar/panels/template.py
@@ -7,6 +7,7 @@ from django.template.context import get_standard_processors
from django.template.loader import render_to_string
from django.test.signals import template_rendered
from django.utils.translation import ugettext_lazy as _
+from debug_toolbar.middleware import DebugToolbarMiddleware
from debug_toolbar.panels import DebugPanel
# Code taken and adapted from Simon Willison and Django Snippets:
@@ -40,15 +41,15 @@ class TemplateDebugPanel(DebugPanel):
"""
name = 'Template'
has_content = True
-
+
def __init__(self, *args, **kwargs):
super(self.__class__, self).__init__(*args, **kwargs)
self.templates = []
template_rendered.connect(self._store_template_info)
-
+
def _store_template_info(self, sender, **kwargs):
context_data = kwargs['context']
-
+
context_list = []
for context_layer in context_data.dicts:
temp_layer = {}
@@ -74,22 +75,22 @@ class TemplateDebugPanel(DebugPanel):
pass
kwargs['context'] = context_list
self.templates.append(kwargs)
-
+
def nav_title(self):
return _('Templates')
-
+
def title(self):
num_templates = len([t for t in self.templates
if not (t['template'].name and t['template'].name.startswith('debug_toolbar/'))])
return _('Templates (%(num_templates)s rendered)') % {'num_templates': num_templates}
-
+
def url(self):
return ''
-
+
def process_request(self, request):
self.request = request
-
- def content(self):
+
+ def process_response(self, request, response):
context_processors = dict(
[
("%s.%s" % (k.__module__, k.__name__),
@@ -116,12 +117,17 @@ class TemplateDebugPanel(DebugPanel):
context_list = template_data.get('context', [])
info['context'] = '\n'.join(context_list)
template_context.append(info)
-
- context = self.context.copy()
- context.update({
+
+ self.stats = {
'templates': template_context,
'template_dirs': [normpath(x) for x in settings.TEMPLATE_DIRS],
'context_processors': context_processors,
- })
-
+ }
+
+ toolbar = DebugToolbarMiddleware.get_current()
+ toolbar.stats['template'] = self.stats
+
+ def content(self):
+ context = self.context.copy()
+ context.update(self.stats)
return render_to_string('debug_toolbar/panels/templates.html', context)
--
cgit v1.2.3
From 0ef39192ecf7ebc359f3ad3a87fbf962b568397b Mon Sep 17 00:00:00 2001
From: bkonkle
Date: Mon, 12 Sep 2011 13:11:08 -0500
Subject: Don't add the entire toolbar to the request object, just the stats
---
debug_toolbar/middleware.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/middleware.py b/debug_toolbar/middleware.py
index 03b2804..ccd4778 100644
--- a/debug_toolbar/middleware.py
+++ b/debug_toolbar/middleware.py
@@ -135,6 +135,6 @@ class DebugToolbarMiddleware(object):
response['Content-Length'] = len(response.content)
# Add the toolbar to the request object, so that the stats are
# available to subsequent middleware classes.
- request.debug_toolbar = toolbar
+ request.debug_toolbar_stats = toolbar.stats
del self.__class__.debug_toolbars[ident]
return response
--
cgit v1.2.3
From 36a2f1d85d615db3c8eda65ccbd3ee14702b1397 Mon Sep 17 00:00:00 2001
From: bkonkle
Date: Thu, 15 Sep 2011 09:33:51 -0500
Subject: Don't add to the request object, because get_current can be used to
obtain the current toolbar
---
debug_toolbar/middleware.py | 3 ---
1 file changed, 3 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/middleware.py b/debug_toolbar/middleware.py
index ccd4778..59194dc 100644
--- a/debug_toolbar/middleware.py
+++ b/debug_toolbar/middleware.py
@@ -133,8 +133,5 @@ class DebugToolbarMiddleware(object):
smart_unicode(toolbar.render_toolbar() + self.tag))
if response.get('Content-Length', None):
response['Content-Length'] = len(response.content)
- # Add the toolbar to the request object, so that the stats are
- # available to subsequent middleware classes.
- request.debug_toolbar_stats = toolbar.stats
del self.__class__.debug_toolbars[ident]
return response
--
cgit v1.2.3
From 03cd2ded38bb6ccd3c97e11fcd1f99bd967dc996 Mon Sep 17 00:00:00 2001
From: bkonkle
Date: Thu, 15 Sep 2011 09:37:18 -0500
Subject: Revert the middleware back to its original state, because no changes
are actually needed
---
debug_toolbar/middleware.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/middleware.py b/debug_toolbar/middleware.py
index 59194dc..f49a29f 100644
--- a/debug_toolbar/middleware.py
+++ b/debug_toolbar/middleware.py
@@ -5,6 +5,7 @@ import imp
import thread
from django.conf import settings
+from django.conf.urls.defaults import include, patterns
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.utils.encoding import smart_unicode
@@ -123,8 +124,7 @@ class DebugToolbarMiddleware(object):
)
response.cookies = cookies
if 'gzip' not in response.get('Content-Encoding', '') and \
- response.get('Content-Type', '').split(';')[0] in _HTML_TYPES:
- toolbar.stats = {}
+ response.get('Content-Type', '').split(';')[0] in _HTML_TYPES:
for panel in toolbar.panels:
panel.process_response(request, response)
response.content = replace_insensitive(
--
cgit v1.2.3
From 78a8b4415163b8215d2a434a5dab4994871a4fc4 Mon Sep 17 00:00:00 2001
From: bkonkle
Date: Thu, 15 Sep 2011 10:03:37 -0500
Subject: Added convenience methods to make it easier to work with panel stats
---
debug_toolbar/panels/__init__.py | 35 ++++++++++++++++++++++-------------
debug_toolbar/toolbar/loader.py | 19 ++++++++++---------
2 files changed, 32 insertions(+), 22 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/panels/__init__.py b/debug_toolbar/panels/__init__.py
index fa2e4b6..584ddb7 100644
--- a/debug_toolbar/panels/__init__.py
+++ b/debug_toolbar/panels/__init__.py
@@ -1,4 +1,6 @@
-"""Base DebugPanel class"""
+from django.template.defaultfilters import slugify
+from debug_toolbar.middleware import DebugToolbarMiddleware
+
class DebugPanel(object):
"""
@@ -6,43 +8,50 @@ class DebugPanel(object):
"""
# name = Base
has_content = False # If content returns something, set to true in subclass
-
+
# We'll maintain a local context instance so we can expose our template
# context variables to panels which need them:
context = {}
-
+
# Panel methods
def __init__(self, context={}):
self.context.update(context)
-
+ self.toolbar = DebugToolbarMiddleware.get_current()
+ self.slug = slugify(self.name)
+
def dom_id(self):
return 'djDebug%sPanel' % (self.name.replace(' ', ''))
-
+
def nav_title(self):
"""Title showing in toolbar"""
raise NotImplementedError
-
+
def nav_subtitle(self):
"""Subtitle showing until title in toolbar"""
return ''
-
+
def title(self):
"""Title showing in panel"""
raise NotImplementedError
-
+
def url(self):
raise NotImplementedError
-
+
def content(self):
raise NotImplementedError
-
+
+ def record_stats(self, stats):
+ self.toolbar.stats[self.slug].update(stats)
+
+ def get_stats(self):
+ return self.toolbar.stats[self.slug]
+
# Standard middleware methods
def process_request(self, request):
pass
-
+
def process_view(self, request, view_func, view_args, view_kwargs):
pass
-
+
def process_response(self, request, response):
pass
-
diff --git a/debug_toolbar/toolbar/loader.py b/debug_toolbar/toolbar/loader.py
index 3501c69..cf7a243 100644
--- a/debug_toolbar/toolbar/loader.py
+++ b/debug_toolbar/toolbar/loader.py
@@ -9,7 +9,7 @@ from django.utils.datastructures import SortedDict
from django.utils.safestring import mark_safe
class DebugToolbar(object):
-
+
def __init__(self, request):
self.request = request
self._panels = SortedDict()
@@ -38,25 +38,26 @@ class DebugToolbar(object):
'debug_toolbar.panels.logger.LoggingPanel',
)
self.load_panels()
+ self.stats = {}
def _get_panels(self):
return self._panels.values()
panels = property(_get_panels)
-
+
def get_panel(self, cls):
return self._panels[cls]
-
+
def load_panels(self):
"""
Populate debug panels
"""
from django.conf import settings
from django.core import exceptions
-
+
# Check if settings has a DEBUG_TOOLBAR_PANELS, otherwise use default
if hasattr(settings, 'DEBUG_TOOLBAR_PANELS'):
self.default_panels = settings.DEBUG_TOOLBAR_PANELS
-
+
for panel_path in self.default_panels:
try:
dot = panel_path.rindex('.')
@@ -71,14 +72,14 @@ class DebugToolbar(object):
panel_class = getattr(mod, panel_classname)
except AttributeError:
raise exceptions.ImproperlyConfigured, 'Toolbar Panel module "%s" does not define a "%s" class' % (panel_module, panel_classname)
-
+
try:
panel_instance = panel_class(context=self.template_context)
except:
raise # Bubble up problem loading panel
-
+
self._panels[panel_class] = panel_instance
-
+
def render_toolbar(self):
"""
Renders the overall Toolbar with panels inside.
@@ -91,5 +92,5 @@ class DebugToolbar(object):
'js': mark_safe(open(os.path.join(media_path, 'js', 'toolbar.min.js'), 'r').read()),
'css': mark_safe(open(os.path.join(media_path, 'css', 'toolbar.min.css'), 'r').read()),
})
-
+
return render_to_string('debug_toolbar/base.html', context)
--
cgit v1.2.3
From c20e83fc946c8898d40b0210f71286575891ae94 Mon Sep 17 00:00:00 2001
From: bkonkle
Date: Thu, 15 Sep 2011 10:09:53 -0500
Subject: Correct some issues with the stats methods
---
debug_toolbar/panels/__init__.py | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/panels/__init__.py b/debug_toolbar/panels/__init__.py
index 584ddb7..baebf02 100644
--- a/debug_toolbar/panels/__init__.py
+++ b/debug_toolbar/panels/__init__.py
@@ -41,10 +41,14 @@ class DebugPanel(object):
raise NotImplementedError
def record_stats(self, stats):
- self.toolbar.stats[self.slug].update(stats)
+ panel_stats = self.toolbar.stats.get(self.slug)
+ if panel_stats:
+ panel_stats.update(stats)
+ else:
+ self.toolbar.stats[self.slug] = stats
def get_stats(self):
- return self.toolbar.stats[self.slug]
+ return self.toolbar.stats.get(self.slug, {})
# Standard middleware methods
def process_request(self, request):
--
cgit v1.2.3
From ed9bca7c00f6f326842d79e843f678787fac8b15 Mon Sep 17 00:00:00 2001
From: bkonkle
Date: Thu, 15 Sep 2011 10:26:00 -0500
Subject: Add a default 'content' method, since the method is now identical on
every panel
---
debug_toolbar/panels/__init__.py | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/panels/__init__.py b/debug_toolbar/panels/__init__.py
index baebf02..e44d388 100644
--- a/debug_toolbar/panels/__init__.py
+++ b/debug_toolbar/panels/__init__.py
@@ -1,4 +1,5 @@
from django.template.defaultfilters import slugify
+from django.template.loader import render_to_string
from debug_toolbar.middleware import DebugToolbarMiddleware
@@ -6,7 +7,8 @@ class DebugPanel(object):
"""
Base class for debug panels.
"""
- # name = Base
+ # name = 'Base'
+ # template = 'debug_toolbar/panels/base.html'
has_content = False # If content returns something, set to true in subclass
# We'll maintain a local context instance so we can expose our template
@@ -38,7 +40,10 @@ class DebugPanel(object):
raise NotImplementedError
def content(self):
- raise NotImplementedError
+ if self.has_content:
+ context = self.context.copy()
+ context.update(self.get_stats())
+ return render_to_string(self.template, context)
def record_stats(self, stats):
panel_stats = self.toolbar.stats.get(self.slug)
--
cgit v1.2.3
From 717dc6815a9d4ddcd30efc17db11ade0f8f38354 Mon Sep 17 00:00:00 2001
From: bkonkle
Date: Thu, 15 Sep 2011 10:36:11 -0500
Subject: Edited all of the panels to use the stats API and not override the
content method
---
debug_toolbar/panels/cache.py | 14 +++---------
debug_toolbar/panels/headers.py | 14 +++---------
debug_toolbar/panels/logger.py | 15 +++---------
debug_toolbar/panels/profiling.py | 27 ++++++++--------------
debug_toolbar/panels/request_vars.py | 19 ++++------------
debug_toolbar/panels/settings_vars.py | 14 +++---------
debug_toolbar/panels/signals.py | 12 ++--------
debug_toolbar/panels/sql.py | 20 ++++++++--------
debug_toolbar/panels/template.py | 17 ++++----------
debug_toolbar/panels/timer.py | 43 +++++++++++++++++------------------
debug_toolbar/panels/version.py | 15 +++---------
11 files changed, 67 insertions(+), 143 deletions(-)
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/panels/cache.py b/debug_toolbar/panels/cache.py
index ad3f844..c9dae6d 100644
--- a/debug_toolbar/panels/cache.py
+++ b/debug_toolbar/panels/cache.py
@@ -3,9 +3,7 @@ import inspect
from django.core import cache
from django.core.cache.backends.base import BaseCache
-from django.template.loader import render_to_string
from django.utils.translation import ugettext_lazy as _
-from debug_toolbar.middleware import DebugToolbarMiddleware
from debug_toolbar.panels import DebugPanel
class CacheStatTracker(BaseCache):
@@ -75,6 +73,7 @@ class CacheDebugPanel(DebugPanel):
Panel that displays the cache statistics.
"""
name = 'Cache'
+ template = 'debug_toolbar/panels/cache.html'
has_content = True
def __init__(self, *args, **kwargs):
@@ -97,15 +96,8 @@ class CacheDebugPanel(DebugPanel):
return ''
def process_response(self, request, response):
- self.stats = {
+ self.record_stats({
'cache_calls': len(self.cache.calls),
'cache_time': self.cache.total_time,
'cache': self.cache,
- }
- toolbar = DebugToolbarMiddleware.get_current()
- toolbar.stats['cache'] = self.stats
-
- def content(self):
- context = self.context.copy()
- context.update(self.stats)
- return render_to_string('debug_toolbar/panels/cache.html', context)
+ })
diff --git a/debug_toolbar/panels/headers.py b/debug_toolbar/panels/headers.py
index a88fbd9..181e88d 100644
--- a/debug_toolbar/panels/headers.py
+++ b/debug_toolbar/panels/headers.py
@@ -1,7 +1,5 @@
-from django.template.loader import render_to_string
from django.utils.translation import ugettext_lazy as _
from debug_toolbar.panels import DebugPanel
-from debug_toolbar.middleware import DebugToolbarMiddleware
class HeaderDebugPanel(DebugPanel):
@@ -9,6 +7,7 @@ class HeaderDebugPanel(DebugPanel):
A panel to display HTTP headers.
"""
name = 'Header'
+ template = 'debug_toolbar/panels/headers.html'
has_content = True
# List of headers we want to display
header_filter = (
@@ -49,13 +48,6 @@ class HeaderDebugPanel(DebugPanel):
)
def process_response(self, request, response):
- self.stats = {
+ self.record_stats({
'headers': self.headers
- }
- toolbar = DebugToolbarMiddleware.get_current()
- toolbar.stats['headers'] = self.stats
-
- def content(self):
- context = self.context.copy()
- context.update(self.stats)
- return render_to_string('debug_toolbar/panels/headers.html', context)
+ })
diff --git a/debug_toolbar/panels/logger.py b/debug_toolbar/panels/logger.py
index ba34700..55ae9bd 100644
--- a/debug_toolbar/panels/logger.py
+++ b/debug_toolbar/panels/logger.py
@@ -4,10 +4,8 @@ try:
import threading
except ImportError:
threading = None
-from django.template.loader import render_to_string
from django.utils.translation import ugettext_lazy as _
from debug_toolbar.panels import DebugPanel
-from debug_toolbar.middleware import DebugToolbarMiddleware
class LogCollector(object):
@@ -88,13 +86,14 @@ if logbook_supported:
'channel': record.channel,
}
self.collector.add_record(record)
-
+
logbook_handler = LogbookThreadTrackingHandler(collector)
logbook_handler.push_application() # register with logbook
class LoggingPanel(DebugPanel):
name = 'Logging'
+ template = 'debug_toolbar/panels/logger.html'
has_content = True
def process_request(self, request):
@@ -102,9 +101,7 @@ class LoggingPanel(DebugPanel):
def process_response(self, request, response):
records = self.get_and_delete()
- self.stats = {'records': records}
- toolbar = DebugToolbarMiddleware.get_current()
- toolbar.stats['logger'] = self.stats
+ self.record_stats({'records': records})
def get_and_delete(self):
records = collector.get_records()
@@ -123,9 +120,3 @@ class LoggingPanel(DebugPanel):
def url(self):
return ''
-
- def content(self):
- context = self.context.copy()
- context.update(self.stats)
- return render_to_string('debug_toolbar/panels/logger.html', context)
-
diff --git a/debug_toolbar/panels/profiling.py b/debug_toolbar/panels/profiling.py
index e08591a..8913621 100644
--- a/debug_toolbar/panels/profiling.py
+++ b/debug_toolbar/panels/profiling.py
@@ -1,9 +1,7 @@
from __future__ import division
-from django.template.loader import render_to_string
from django.utils.translation import ugettext_lazy as _
from django.utils.safestring import mark_safe
-from debug_toolbar.middleware import DebugToolbarMiddleware
from debug_toolbar.panels import DebugPanel
try:
@@ -143,6 +141,7 @@ class ProfilingDebugPanel(DebugPanel):
Panel that displays the Django version.
"""
name = 'Profiling'
+ template = 'debug_toolbar/panels/profiling.html'
has_content = True
def nav_title(self):
@@ -178,16 +177,6 @@ class ProfilingDebugPanel(DebugPanel):
out = self.profiler.runcall(view_func, *args, **view_kwargs)
return out
- def process_response(self, request, response):
- self.profiler.create_stats()
- self.stats = DjangoDebugToolbarStats(self.profiler)
- if DJ_PROFILE_USE_LINE_PROFILER:
- self.stats.line_stats = self.line_profiler.get_stats()
- self.stats.calc_callees()
- toolbar = DebugToolbarMiddleware.get_current()
- toolbar.stats['profiling'] = self.stats
- return response
-
def add_node(self, func_list, func, max_depth, cum_time=0.1):
func_list.append(func)
func.has_subfuncs = False
@@ -199,14 +188,16 @@ class ProfilingDebugPanel(DebugPanel):
func.has_subfuncs = True
self.add_node(func_list, subfunc, max_depth, cum_time=cum_time)
- def content(self):
+ def process_response(self, request, response):
+ self.profiler.create_stats()
+ self.stats = DjangoDebugToolbarStats(self.profiler)
+ if DJ_PROFILE_USE_LINE_PROFILER:
+ self.stats.line_stats = self.line_profiler.get_stats()
+ self.stats.calc_callees()
+
root = FunctionCall(self.stats, self.stats.get_root_func(), depth=0)
func_list = []
self.add_node(func_list, root, 10, root.stats[3]/8)
- context = self.context.copy()
- context.update({
- 'func_list': func_list,
- })
- return render_to_string('debug_toolbar/panels/profiling.html', context)
+ self.stats_record({'func_list': func_list})
diff --git a/debug_toolbar/panels/request_vars.py b/debug_toolbar/panels/request_vars.py
index 80cd018..ee9cdc5 100644
--- a/debug_toolbar/panels/request_vars.py
+++ b/debug_toolbar/panels/request_vars.py
@@ -1,7 +1,5 @@
-from django.template.loader import render_to_string
from django.utils.translation import ugettext_lazy as _
-from debug_toolbar.middleware import DebugToolbarMiddleware
from debug_toolbar.panels import DebugPanel
from debug_toolbar.utils import get_name_from_obj
@@ -10,6 +8,7 @@ class RequestVarsDebugPanel(DebugPanel):
A panel to display request variables (POST/GET, session, cookies).
"""
name = 'RequestVars'
+ template = 'debug_toolbar/panels/request_vars.html'
has_content = True
def __init__(self, *args, **kwargs):
@@ -36,11 +35,11 @@ class RequestVarsDebugPanel(DebugPanel):
self.view_kwargs = view_kwargs
def process_response(self, request, response):
- self.stats = {
+ self.record_stats({
'get': [(k, self.request.GET.getlist(k)) for k in self.request.GET],
'post': [(k, self.request.POST.getlist(k)) for k in self.request.POST],
'cookies': [(k, self.request.COOKIES.get(k)) for k in self.request.COOKIES],
- }
+ })
if hasattr(self, 'view_func'):
if self.view_func is not None:
@@ -48,21 +47,13 @@ class RequestVarsDebugPanel(DebugPanel):
else:
name = ''
- self.stats.update({
+ self.record_stats({
'view_func': name,
'view_args': self.view_args,
'view_kwargs': self.view_kwargs
})
if hasattr(self.request, 'session'):
- self.stats.update({
+ self.record_stats({
'session': [(k, self.request.session.get(k)) for k in self.request.session.iterkeys()]
})
-
- toolbar = DebugToolbarMiddleware.get_current()
- toolbar.stats['request_vars'] = self.stats
-
- def content(self):
- context = self.context.copy()
- context.update(self.stats)
- return render_to_string('debug_toolbar/panels/request_vars.html', context)
diff --git a/debug_toolbar/panels/settings_vars.py b/debug_toolbar/panels/settings_vars.py
index 029496e..e154dda 100644
--- a/debug_toolbar/panels/settings_vars.py
+++ b/debug_toolbar/panels/settings_vars.py
@@ -1,8 +1,6 @@
from django.conf import settings
-from django.template.loader import render_to_string
from django.views.debug import get_safe_settings
from django.utils.translation import ugettext_lazy as _
-from debug_toolbar.middleware import DebugToolbarMiddleware
from debug_toolbar.panels import DebugPanel
@@ -11,6 +9,7 @@ class SettingsVarsDebugPanel(DebugPanel):
A panel to display all variables in django.conf.settings
"""
name = 'SettingsVars'
+ template = 'debug_toolbar/panels/settings_vars.html'
has_content = True
def nav_title(self):
@@ -23,13 +22,6 @@ class SettingsVarsDebugPanel(DebugPanel):
return ''
def process_response(self, request, response):
- self.stats = {
+ self.record_stats({
'settings': get_safe_settings(),
- }
- toolbar = DebugToolbarMiddleware.get_current()
- toolbar.stats['settings_vars'] = self.stats
-
- def content(self):
- context = self.context.copy()
- context.update(self.stats)
- return render_to_string('debug_toolbar/panels/settings_vars.html', context)
+ })
diff --git a/debug_toolbar/panels/signals.py b/debug_toolbar/panels/signals.py
index 9855299..205b3c5 100644
--- a/debug_toolbar/panels/signals.py
+++ b/debug_toolbar/panels/signals.py
@@ -6,7 +6,6 @@ from django.core.signals import request_started, request_finished, \
from django.db.models.signals import class_prepared, pre_init, post_init, \
pre_save, post_save, pre_delete, post_delete, post_syncdb
from django.dispatch.dispatcher import WEAKREF_TYPES
-from django.template.loader import render_to_string
from django.utils.translation import ugettext_lazy as _
try:
@@ -14,11 +13,11 @@ try:
except ImportError:
connection_created = None
-from debug_toolbar.middleware import DebugToolbarMiddleware
from debug_toolbar.panels import DebugPanel
class SignalDebugPanel(DebugPanel):
name = "Signals"
+ template = 'debug_toolbar/panels/signals.html'
has_content = True
SIGNALS = {
@@ -82,11 +81,4 @@ class SignalDebugPanel(DebugPanel):
receivers.append(text)
signals.append((name, signal, receivers))
- self.stats = {'signals': signals}
- toolbar = DebugToolbarMiddleware.get_current()
- toolbar.stats['signals'] = self.stats
-
- def content(self):
- context = self.context.copy()
- context.update(self.stats)
- return render_to_string('debug_toolbar/panels/signals.html', context)
+ self.record_stats({'signals': signals})
diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py
index 9527410..188e1eb 100644
--- a/debug_toolbar/panels/sql.py
+++ b/debug_toolbar/panels/sql.py
@@ -2,7 +2,6 @@ import re
import uuid
from django.db.backends import BaseDatabaseWrapper
-from django.template.loader import render_to_string
from django.utils.html import escape
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _, ungettext_lazy as __
@@ -14,6 +13,7 @@ from debug_toolbar.utils import sqlparse
from debug_toolbar.utils.tracking.db import CursorWrapper
from debug_toolbar.utils.tracking import replace_call
+
# Inject our tracking cursor
@replace_call(BaseDatabaseWrapper.cursor)
def cursor(func, self):
@@ -26,6 +26,7 @@ def cursor(func, self):
return CursorWrapper(result, self, logger=logger)
+
def get_isolation_level_display(engine, level):
if engine == 'psycopg2':
import psycopg2.extensions
@@ -41,6 +42,7 @@ def get_isolation_level_display(engine, level):
return choices.get(level)
+
def get_transaction_status_display(engine, level):
if engine == 'psycopg2':
import psycopg2.extensions
@@ -56,12 +58,14 @@ def get_transaction_status_display(engine, level):
return choices.get(level)
+
class SQLDebugPanel(DebugPanel):
"""
Panel that displays information about the SQL queries run while processing
the request.
"""
name = 'SQL'
+ template = 'debug_toolbar/panels/sql.html'
has_content = True
def __init__(self, *args, **kwargs):
@@ -205,18 +209,12 @@ class SQLDebugPanel(DebugPanel):
if trans_id:
self._queries[i-1][1]['ends_trans'] = True
- self.stats = {
+ self.record_stats({
'databases': sorted(self._databases.items(), key=lambda x: -x[1]['time_spent']),
'queries': [q for a, q in self._queries],
'sql_time': self._sql_time,
- }
- toolbar = DebugToolbarMiddleware.get_current()
- toolbar.stats['sql'] = self.stats
-
- def content(self):
- context = self.context.copy()
- context.update(self.stats)
- return render_to_string('debug_toolbar/panels/sql.html', context)
+ })
+
class BoldKeywordFilter(sqlparse.filters.Filter):
"""sqlparse filter to bold SQL keywords"""
@@ -230,10 +228,12 @@ class BoldKeywordFilter(sqlparse.filters.Filter):
if is_keyword:
yield sqlparse.tokens.Text, ''
+
def swap_fields(sql):
return re.sub('SELECT (.*) FROM', 'SELECT ••• ' +
'\g<1> FROM', sql)
+
def reformat_sql(sql):
stack = sqlparse.engine.FilterStack()
stack.preprocess.append(BoldKeywordFilter()) # add our custom filter
diff --git a/debug_toolbar/panels/template.py b/debug_toolbar/panels/template.py
index d0ab6cc..41e0afc 100644
--- a/debug_toolbar/panels/template.py
+++ b/debug_toolbar/panels/template.py
@@ -4,10 +4,8 @@ from pprint import pformat
from django import http
from django.conf import settings
from django.template.context import get_standard_processors
-from django.template.loader import render_to_string
from django.test.signals import template_rendered
from django.utils.translation import ugettext_lazy as _
-from debug_toolbar.middleware import DebugToolbarMiddleware
from debug_toolbar.panels import DebugPanel
# Code taken and adapted from Simon Willison and Django Snippets:
@@ -28,6 +26,7 @@ else:
Template.original_render = Template._render
Template._render = instrumented_test_render
+
# MONSTER monkey-patch
old_template_init = Template.__init__
def new_template_init(self, template_string, origin=None, name=''):
@@ -35,11 +34,13 @@ def new_template_init(self, template_string, origin=None, name='