diff options
Diffstat (limited to 'debug_toolbar/panels')
| -rw-r--r-- | debug_toolbar/panels/__init__.py | 28 | ||||
| -rw-r--r-- | debug_toolbar/panels/cache.py | 24 | ||||
| -rw-r--r-- | debug_toolbar/panels/headers.py | 10 | ||||
| -rw-r--r-- | debug_toolbar/panels/logger.py | 34 | ||||
| -rw-r--r-- | debug_toolbar/panels/profiling.py | 27 | ||||
| -rw-r--r-- | debug_toolbar/panels/request_vars.py | 21 | ||||
| -rw-r--r-- | debug_toolbar/panels/settings_vars.py | 8 | ||||
| -rw-r--r-- | debug_toolbar/panels/signals.py | 1 | ||||
| -rw-r--r-- | debug_toolbar/panels/sql.py | 67 | ||||
| -rw-r--r-- | debug_toolbar/panels/template.py | 22 | ||||
| -rw-r--r-- | debug_toolbar/panels/timer.py | 6 | ||||
| -rw-r--r-- | debug_toolbar/panels/version.py | 12 |
12 files changed, 131 insertions, 129 deletions
diff --git a/debug_toolbar/panels/__init__.py b/debug_toolbar/panels/__init__.py index b4f11fb..f1751d8 100644 --- a/debug_toolbar/panels/__init__.py +++ b/debug_toolbar/panels/__init__.py @@ -9,41 +9,41 @@ class DebugPanel(object): """ # name = 'Base' # template = 'debug_toolbar/panels/base.html' - has_content = False # If content returns something, set to true in subclass - + 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.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): 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): toolbar = DebugToolbarMiddleware.get_current() panel_stats = toolbar.stats.get(self.slug) @@ -51,17 +51,17 @@ class DebugPanel(object): panel_stats.update(stats) else: toolbar.stats[self.slug] = stats - + def get_stats(self): toolbar = DebugToolbarMiddleware.get_current() return toolbar.stats.get(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/panels/cache.py b/debug_toolbar/panels/cache.py index 620be86..ace343b 100644 --- a/debug_toolbar/panels/cache.py +++ b/debug_toolbar/panels/cache.py @@ -6,12 +6,13 @@ from django.core.cache.backends.base import BaseCache from django.utils.translation import ugettext_lazy as _ from debug_toolbar.panels import DebugPanel + class CacheStatTracker(BaseCache): """A small class used to track cache calls.""" def __init__(self, cache): self.cache = cache self.reset() - + def reset(self): self.calls = [] self.hits = 0 @@ -21,11 +22,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) @@ -38,7 +39,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) @@ -46,7 +47,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) @@ -54,7 +55,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) @@ -68,6 +69,7 @@ class CacheStatTracker(BaseCache): self.hits += 1 self.calls.append((this_time, 'get_many', (keys,), self._get_func_info())) + class CacheDebugPanel(DebugPanel): """ Panel that displays the cache statistics. @@ -75,7 +77,7 @@ class CacheDebugPanel(DebugPanel): name = 'Cache' template = 'debug_toolbar/panels/cache.html' has_content = True - + def __init__(self, *args, **kwargs): super(CacheDebugPanel, self).__init__(*args, **kwargs) # This is hackish but to prevent threading issues is somewhat needed @@ -85,16 +87,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.record_stats({ 'cache_calls': len(self.cache.calls), diff --git a/debug_toolbar/panels/headers.py b/debug_toolbar/panels/headers.py index 181e88d..9824d0e 100644 --- a/debug_toolbar/panels/headers.py +++ b/debug_toolbar/panels/headers.py @@ -32,21 +32,21 @@ 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] ) - + def process_response(self, request, response): self.record_stats({ 'headers': self.headers diff --git a/debug_toolbar/panels/logger.py b/debug_toolbar/panels/logger.py index 55ae9bd..e894b50 100644 --- a/debug_toolbar/panels/logger.py +++ b/debug_toolbar/panels/logger.py @@ -13,16 +13,16 @@ class LogCollector(object): if threading is None: 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 - + 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, @@ -33,7 +33,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() @@ -45,7 +45,7 @@ class ThreadTrackingHandler(logging.Handler): def __init__(self, collector): logging.Handler.__init__(self) self.collector = collector - + def emit(self, record): record = { 'message': record.getMessage(), @@ -75,7 +75,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, @@ -86,37 +86,37 @@ if logbook_supported: 'channel': record.channel, } self.collector.add_record(record) - - + logbook_handler = LogbookThreadTrackingHandler(collector) - logbook_handler.push_application() # register with logbook + 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): collector.clear_records() - + def process_response(self, request, response): records = self.get_and_delete() self.record_stats({'records': records}) - + 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 '' diff --git a/debug_toolbar/panels/profiling.py b/debug_toolbar/panels/profiling.py index d07fd2a..f21c345 100644 --- a/debug_toolbar/panels/profiling.py +++ b/debug_toolbar/panels/profiling.py @@ -32,7 +32,7 @@ class DjangoDebugToolbarStats(Stats): class FunctionCall(object): def __init__(self, statobj, func, depth=0, stats=None, - id=0, parent_ids=[], hsv=(0,0.5,1)): + id=0, parent_ids=[], hsv=(0, 0.5, 1)): self.statobj = statobj self.func = func if stats: @@ -49,10 +49,10 @@ class FunctionCall(object): 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) + 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 @@ -65,7 +65,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) @@ -77,23 +77,23 @@ class FunctionCall(object): )) def subfuncs(self): - i=0 + i = 0 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 - h1 = h + (i/count)/(self.depth+1) + h1 = h + (i / count) / (self.depth + 1) if stats[3] == 0: s1 = 0 else: - s1 = s*(stats[3]/self.stats[3]) + s1 = s * (stats[3] / self.stats[3]) yield FunctionCall(self.statobj, func, - self.depth+1, + self.depth + 1, stats=stats, id=str(self.id) + '_' + str(i), parent_ids=self.parent_ids + [self.id], - hsv=(h1,s1,1)) + hsv=(h1, s1, 1)) def count(self): return self.stats[1] @@ -111,7 +111,7 @@ class FunctionCall(object): if nc == 0: return 0 - return tt/nc + return tt / nc def cumtime_per_call(self): cc, nc, tt, ct = self.stats @@ -119,7 +119,7 @@ class FunctionCall(object): if cc == 0: return 0 - return ct/cc + return ct / cc def indent(self): return 16 * self.depth @@ -136,6 +136,7 @@ class FunctionCall(object): self._line_stats_text = False return self._line_stats_text + class ProfilingDebugPanel(DebugPanel): """ Panel that displays the Django version. @@ -201,6 +202,6 @@ class ProfilingDebugPanel(DebugPanel): root = FunctionCall(self.stats, self.stats.get_root_func(), depth=0) func_list = [] - self.add_node(func_list, root, 10, root.stats[3]/8) + self.add_node(func_list, root, 10, root.stats[3] / 8) self.record_stats({'func_list': func_list}) diff --git a/debug_toolbar/panels/request_vars.py b/debug_toolbar/panels/request_vars.py index ee9cdc5..4f85052 100644 --- a/debug_toolbar/panels/request_vars.py +++ b/debug_toolbar/panels/request_vars.py @@ -3,6 +3,7 @@ from django.utils.translation import ugettext_lazy as _ from debug_toolbar.panels import DebugPanel from debug_toolbar.utils import get_name_from_obj + class RequestVarsDebugPanel(DebugPanel): """ A panel to display request variables (POST/GET, session, cookies). @@ -10,49 +11,49 @@ class RequestVarsDebugPanel(DebugPanel): name = 'RequestVars' template = 'debug_toolbar/panels/request_vars.html' 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 process_response(self, request, response): 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: name = get_name_from_obj(self.view_func) else: name = '<no view>' - + self.record_stats({ 'view_func': name, 'view_args': self.view_args, 'view_kwargs': self.view_kwargs }) - + if hasattr(self.request, 'session'): self.record_stats({ 'session': [(k, self.request.session.get(k)) for k in self.request.session.iterkeys()] diff --git a/debug_toolbar/panels/settings_vars.py b/debug_toolbar/panels/settings_vars.py index e154dda..194295e 100644 --- a/debug_toolbar/panels/settings_vars.py +++ b/debug_toolbar/panels/settings_vars.py @@ -11,16 +11,16 @@ class SettingsVarsDebugPanel(DebugPanel): name = 'SettingsVars' template = 'debug_toolbar/panels/settings_vars.html' has_content = True - + def nav_title(self): return _('Settings') - + def title(self): return _('Settings from <code>%s</code>') % settings.SETTINGS_MODULE - + def url(self): return '' - + def process_response(self, request, response): self.record_stats({ 'settings': get_safe_settings(), diff --git a/debug_toolbar/panels/signals.py b/debug_toolbar/panels/signals.py index 1d60292..b7dbffe 100644 --- a/debug_toolbar/panels/signals.py +++ b/debug_toolbar/panels/signals.py @@ -15,6 +15,7 @@ except ImportError: from debug_toolbar.panels import DebugPanel + class SignalDebugPanel(DebugPanel): name = "Signals" template = 'debug_toolbar/panels/signals.html' diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py index b27e6c0..18fffdc 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) @@ -39,7 +39,7 @@ def get_isolation_level_display(engine, level): } else: raise ValueError(engine) - + return choices.get(level) @@ -55,7 +55,7 @@ def get_transaction_status_display(engine, level): } else: raise ValueError(engine) - + return choices.get(level) @@ -67,7 +67,7 @@ class SQLDebugPanel(DebugPanel): name = 'SQL' template = 'debug_toolbar/panels/sql.html' has_content = True - + def __init__(self, *args, **kwargs): super(SQLDebugPanel, self).__init__(*args, **kwargs) self._offset = dict((k, len(connections[k].queries)) for k in connections) @@ -77,33 +77,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: @@ -116,10 +116,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" % ( @@ -127,30 +127,25 @@ 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 - colors = [ - (256, 0, 0), # red - (0, 256, 0), # blue - (0, 0, 256), # green - ] - factor = int(256.0/(len(self._databases)*2.5)) + factor = int(256.0 / (len(self._databases) * 2.5)) for n, db in enumerate(self._databases.itervalues()): rgb = [0, 0, 0] color = n % 3 - rgb[color] = 256 - n/3*factor + rgb[color] = 256 - n / 3 * factor nn = color # XXX: pretty sure this is horrible after so many aliases while rgb[color] < factor: @@ -161,23 +156,23 @@ 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 + self._queries[(i - 1)][1]['ends_trans'] = True trans_ids[alias] = trans_id if trans_id: 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']) @@ -187,14 +182,14 @@ class SQLDebugPanel(DebugPanel): query['rgb_color'] = self._databases[alias]['rgb_color'] try: query['width_ratio'] = (query['duration'] / self._sql_time) * 100 - query['width_ratio_relative'] = 100.0 * query['width_ratio'] / (100.0 - width_ratio_tally) + query['width_ratio_relative'] = 100.0 * query['width_ratio'] / (100.0 - width_ratio_tally) except ZeroDivisionError: query['width_ratio'] = 0 query['width_ratio_relative'] = 0 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:])) @@ -205,10 +200,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._queries[(i - 1)][1]['ends_trans'] = True + self.record_stats({ 'databases': sorted(self._databases.items(), key=lambda x: -x[1]['time_spent']), 'queries': [q for a, q in self._queries], @@ -236,6 +231,6 @@ def swap_fields(sql): def reformat_sql(sql): stack = sqlparse.engine.FilterStack() - stack.preprocess.append(BoldKeywordFilter()) # add our custom filter - stack.postprocess.append(sqlparse.filters.SerializerUnicode()) # tokens -> strings + stack.preprocess.append(BoldKeywordFilter()) # add our custom filter + stack.postprocess.append(sqlparse.filters.SerializerUnicode()) # tokens -> strings return swap_fields(''.join(stack.run(sql))) diff --git a/debug_toolbar/panels/template.py b/debug_toolbar/panels/template.py index a69b42a..48225a0 100644 --- a/debug_toolbar/panels/template.py +++ b/debug_toolbar/panels/template.py @@ -19,7 +19,7 @@ from debug_toolbar.utils.tracking.db import recording, SQLQueryTriggered from django.test.utils import instrumented_test_render from django.template import Template -if not hasattr(Template, '_render'): # Django < 1.2 +if not hasattr(Template, '_render'): # Django < 1.2 if Template.render != instrumented_test_render: Template.original_render = Template.render Template.render = instrumented_test_render @@ -31,6 +31,8 @@ else: # MONSTER monkey-patch old_template_init = Template.__init__ + + def new_template_init(self, template_string, origin=None, name='<Unknown Template>'): old_template_init(self, template_string, origin, name) self.origin = origin @@ -44,18 +46,18 @@ class TemplateDebugPanel(DebugPanel): name = 'Template' template = 'debug_toolbar/panels/templates.html' has_content = True - + def __init__(self, *args, **kwargs): super(TemplateDebugPanel, self).__init__(*args, **kwargs) self.templates = [] template_rendered.connect(self._store_template_info) - + def _store_template_info(self, sender, **kwargs): t = kwargs['template'] if t.name and t.name.startswith('debug_toolbar/'): return # skip templates that we are generating through the debug toolbar. context_data = kwargs['context'] - + context_list = [] for context_layer in context_data.dicts: temp_layer = {} @@ -95,20 +97,20 @@ class TemplateDebugPanel(DebugPanel): pass kwargs['context'] = context_list self.templates.append(kwargs) - + def nav_title(self): return _('Templates') - + def title(self): num_templates = len(self.templates) return _('Templates (%(num_templates)s rendered)') % {'num_templates': num_templates} - + def url(self): return '' - + def process_request(self, request): self.request = request - + def process_response(self, request, response): context_processors = dict( [ @@ -133,7 +135,7 @@ class TemplateDebugPanel(DebugPanel): context_list = template_data.get('context', []) info['context'] = '\n'.join(context_list) template_context.append(info) - + self.record_stats({ 'templates': template_context, 'template_dirs': [normpath(x) for x in settings.TEMPLATE_DIRS], diff --git a/debug_toolbar/panels/timer.py b/debug_toolbar/panels/timer.py index 943dd8a..7428e83 100644 --- a/debug_toolbar/panels/timer.py +++ b/debug_toolbar/panels/timer.py @@ -1,7 +1,7 @@ try: import resource except ImportError: - pass # Will fail on Win32 systems + pass # Will fail on Win32 systems import time from django.template.loader import render_to_string from django.utils.translation import ugettext_lazy as _ @@ -14,7 +14,7 @@ class TimerDebugPanel(DebugPanel): """ name = 'Timer' template = 'debug_toolbar/panels/timer.html' - try: # if resource module not available, don't show content panel + try: # if resource module not available, don't show content panel resource except NameError: has_content = False @@ -92,5 +92,5 @@ class TimerDebugPanel(DebugPanel): ) context = self.context.copy() - context.update({'rows': rows,}) + context.update({'rows': rows}) return render_to_string(self.template, context) diff --git a/debug_toolbar/panels/version.py b/debug_toolbar/panels/version.py index 8ac0e82..3d4303d 100644 --- a/debug_toolbar/panels/version.py +++ b/debug_toolbar/panels/version.py @@ -14,19 +14,19 @@ class VersionDebugPanel(DebugPanel): name = 'Version' template = 'debug_toolbar/panels/versions.html' 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] @@ -49,7 +49,7 @@ class VersionDebugPanel(DebugPanel): if isinstance(version, (list, tuple)): version = '.'.join(str(o) for o in version) versions[name] = version - + self.record_stats({ 'versions': versions, 'paths': sys.path, |
