From 0e262aefe7b272ac8d8725f2af2f304a26f20927 Mon Sep 17 00:00:00 2001 From: Apkawa Date: Wed, 26 Oct 2011 23:01:50 +0400 Subject: Fixed ProfilingDebugPanel; fixed example site if installed other debug_toolbar in system --- debug_toolbar/panels/profiling.py | 60 ++++++++++++++++++------------------- debug_toolbar/utils/tracking/db.py | 5 ++-- example/example.db | Bin 55296 -> 55296 bytes example/settings.py | 5 +++- 4 files changed, 36 insertions(+), 34 deletions(-) diff --git a/debug_toolbar/panels/profiling.py b/debug_toolbar/panels/profiling.py index 8913621..9683111 100644 --- a/debug_toolbar/panels/profiling.py +++ b/debug_toolbar/panels/profiling.py @@ -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(): @@ -44,14 +44,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): @@ -66,16 +66,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 @@ -94,36 +94,36 @@ 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: lstats = self.statobj.line_stats @@ -143,16 +143,16 @@ class ProfilingDebugPanel(DebugPanel): name = 'Profiling' template = 'debug_toolbar/panels/profiling.html' 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 @@ -161,9 +161,9 @@ 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 + print "process_view", view_func self.profiler = cProfile.Profile() args = (request,) + view_args if DJ_PROFILE_USE_LINE_PROFILER: @@ -176,7 +176,7 @@ class ProfilingDebugPanel(DebugPanel): self.line_profiler = None out = self.profiler.runcall(view_func, *args, **view_kwargs) return out - + def add_node(self, func_list, func, max_depth, cum_time=0.1): func_list.append(func) func.has_subfuncs = False @@ -187,17 +187,17 @@ 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 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) - - self.stats_record({'func_list': func_list}) + + self.record_stats({'func_list': func_list}) diff --git a/debug_toolbar/utils/tracking/db.py b/debug_toolbar/utils/tracking/db.py index a40976e..7370374 100644 --- a/debug_toolbar/utils/tracking/db.py +++ b/debug_toolbar/utils/tracking/db.py @@ -1,4 +1,3 @@ -import inspect import sys from datetime import datetime @@ -7,7 +6,7 @@ from threading import local from django.conf import settings from django.template import Node from django.utils import simplejson -from django.utils.encoding import force_unicode +from django.utils.encoding import force_unicode, smart_str from django.utils.hashcompat import sha_constructor from debug_toolbar.utils import ms_from_timedelta, tidy_stacktrace, get_template_info, \ @@ -113,7 +112,7 @@ class NormalCursorWrapper(object): 'duration': duration, 'raw_sql': sql, 'params': _params, - 'hash': sha_constructor(settings.SECRET_KEY + sql + _params).hexdigest(), + 'hash': sha_constructor(settings.SECRET_KEY + smart_str(sql) + _params).hexdigest(), 'stacktrace': stacktrace, 'start_time': start, 'stop_time': stop, diff --git a/example/example.db b/example/example.db index 7acdc0d..443f173 100644 Binary files a/example/example.db and b/example/example.db differ diff --git a/example/settings.py b/example/settings.py index fac99af..279db7e 100644 --- a/example/settings.py +++ b/example/settings.py @@ -1,5 +1,6 @@ import os PROJECT_PATH = os.path.realpath(os.path.dirname(__file__)) +os.sys.path.insert(0, os.path.dirname(PROJECT_PATH)) ADMIN_MEDIA_PREFIX = '/admin_media/' DATABASE_ENGINE = 'sqlite3' @@ -31,7 +32,9 @@ TEMPLATE_CONTEXT_PROCESSORS = ( 'django.core.context_processors.request', ) TEMPLATE_DEBUG = DEBUG -TEMPLATE_DIRS = (os.path.join(PROJECT_PATH, 'templates')) +TEMPLATE_DIRS = ( + os.path.join(PROJECT_PATH, 'templates'), + ) DEBUG_TOOLBAR_PANELS = ( 'debug_toolbar.panels.version.VersionDebugPanel', 'debug_toolbar.panels.timer.TimerDebugPanel', -- cgit v1.2.3 From e455bec46f7beb92526acf100d269d88c2ede064 Mon Sep 17 00:00:00 2001 From: Apkawa Date: Thu, 27 Oct 2011 00:08:23 +0400 Subject: fixed AttributeError on 404 page exception in ProfilerPanel.process_response --- debug_toolbar/middleware.py | 1 - debug_toolbar/panels/profiling.py | 5 ++++- example/example.db | Bin 55296 -> 55296 bytes example/settings.py | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/debug_toolbar/middleware.py b/debug_toolbar/middleware.py index f49a29f..8f0445a 100644 --- a/debug_toolbar/middleware.py +++ b/debug_toolbar/middleware.py @@ -74,7 +74,6 @@ class DebugToolbarMiddleware(object): def process_request(self, request): __traceback_hide__ = True if self.show_toolbar(request): - urlconf = getattr(request, 'urlconf', settings.ROOT_URLCONF) if isinstance(urlconf, basestring): urlconf = import_module(getattr(request, 'urlconf', settings.ROOT_URLCONF)) diff --git a/debug_toolbar/panels/profiling.py b/debug_toolbar/panels/profiling.py index 9683111..d07fd2a 100644 --- a/debug_toolbar/panels/profiling.py +++ b/debug_toolbar/panels/profiling.py @@ -163,7 +163,7 @@ class ProfilingDebugPanel(DebugPanel): self._unwrap_closure_and_profile(cell.cell_contents) def process_view(self, request, view_func, view_args, view_kwargs): - print "process_view", view_func + __traceback_hide__ = True self.profiler = cProfile.Profile() args = (request,) + view_args if DJ_PROFILE_USE_LINE_PROFILER: @@ -189,6 +189,9 @@ class ProfilingDebugPanel(DebugPanel): self.add_node(func_list, subfunc, max_depth, cum_time=cum_time) def process_response(self, request, response): + __traceback_hide__ = True + if not hasattr(self, 'profiler'): + return None self.profiler.create_stats() self.stats = DjangoDebugToolbarStats(self.profiler) if DJ_PROFILE_USE_LINE_PROFILER: diff --git a/example/example.db b/example/example.db index 443f173..dbbe0c9 100644 Binary files a/example/example.db and b/example/example.db differ diff --git a/example/settings.py b/example/settings.py index 279db7e..c421a62 100644 --- a/example/settings.py +++ b/example/settings.py @@ -51,4 +51,41 @@ DEBUG_TOOLBAR_PANELS = ( CACHE_BACKEND = 'dummy://' #CACHE_BACKEND = 'memcached://127.0.0.1:11211' +LOGGING = { + 'version': 1, + 'disable_existing_loggers': True, + 'formatters': { + 'verbose': { + 'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s' + }, + }, + 'handlers': { + 'null': { + 'level':'DEBUG', + 'class':'django.utils.log.NullHandler', + }, + 'console':{ + 'level':'DEBUG', + 'class':'logging.StreamHandler', + 'formatter': 'verbose' + }, + }, + 'loggers': { + 'django': { + 'handlers':['null'], + 'propagate': True, + 'level':'INFO', + }, + 'django.request': { + 'handlers': ['console'], + 'level': 'ERROR', + 'propagate': False, + }, + 'django.db.backends': { + 'handlers': ['console'], + 'level': 'DEBUG', + 'propagate': False, + }, + } +} -- cgit v1.2.3 From 9cb24492637aa8ef9e77f007016451d515f29d5d Mon Sep 17 00:00:00 2001 From: Andi Albrecht Date: Tue, 15 Nov 2011 15:01:17 +0100 Subject: Only call _elapsed_ru() in TimerPanel when resource module is available. --- debug_toolbar/panels/timer.py | 78 +++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 47 deletions(-) diff --git a/debug_toolbar/panels/timer.py b/debug_toolbar/panels/timer.py index 7c0febf..943dd8a 100644 --- a/debug_toolbar/panels/timer.py +++ b/debug_toolbar/panels/timer.py @@ -22,58 +22,42 @@ 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 + stats = {'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.record_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, - }) - + stats['utime'] = 1000 * self._elapsed_ru('ru_utime') + stats['stime'] = 1000 * self._elapsed_ru('ru_stime') + stats['vcsw'] = self._elapsed_ru('ru_nvcsw') + stats['ivcsw'] = self._elapsed_ru('ru_nivcsw') + stats['minflt'] = self._elapsed_ru('ru_minflt') + stats['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. :-( + # + # stats['blkin'] = self._elapsed_ru('ru_inblock') + # stats['blkout'] = self._elapsed_ru('ru_oublock') + # stats['swap'] = self._elapsed_ru('ru_nswap') + # stats['rss'] = self._end_rusage.ru_maxrss + # stats['srss'] = self._end_rusage.ru_ixrss + # stats['urss'] = self._end_rusage.ru_idrss + # stats['usrss'] = self._end_rusage.ru_isrss + + self.record_stats(stats) + def nav_title(self): return _('Time') - + def nav_subtitle(self): stats = self.get_stats() - + # TODO l10n if self.has_resource: utime = self._end_rusage.ru_utime - self._start_rusage.ru_utime @@ -81,19 +65,19 @@ class TimerDebugPanel(DebugPanel): return 'CPU: %0.2fms (%0.2fms)' % ((utime + stime) * 1000.0, stats['total_time']) else: return 'TOTAL: %0.2fms' % (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): stats = self.get_stats() - + # TODO l10n on values rows = ( (_('User CPU time'), '%0.3f msec' % stats['utime']), @@ -106,7 +90,7 @@ class TimerDebugPanel(DebugPanel): # ('Page faults', '%d no i/o, %d requiring i/o' % (stats['minflt'], stats['majflt'])), # ('Disk operations', '%d in, %d out, %d swapout' % (stats['blkin'], stats['blkout'], stats['swap'])), ) - + context = self.context.copy() context.update({'rows': rows,}) return render_to_string(self.template, context) -- cgit v1.2.3 From 5748f9b3e110b5f3621242f9fc262a4619e23d15 Mon Sep 17 00:00:00 2001 From: Chris Lamb Date: Wed, 30 Nov 2011 17:22:03 +0000 Subject: Don't blow up if INSTALLED_APPS is a tuple Since r17158 in Django trunk, INSTALLED_APPS is now not always co-erced to a list. In my projects I prefer to have INSTALLED_APPS as a tuple as it reinforces that it is not modifiable at runtime. However, this blows up in the VersionDebugPanel as it currently assumes it is a list. Signed-off-by: Chris Lamb --- debug_toolbar/panels/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debug_toolbar/panels/version.py b/debug_toolbar/panels/version.py index 4e58971..8ac0e82 100644 --- a/debug_toolbar/panels/version.py +++ b/debug_toolbar/panels/version.py @@ -30,7 +30,7 @@ class VersionDebugPanel(DebugPanel): def process_response(self, request, response): versions = {} versions['Python'] = '%d.%d.%d' % sys.version_info[:3] - for app in settings.INSTALLED_APPS + ['django']: + for app in list(settings.INSTALLED_APPS) + ['django']: name = app.split('.')[-1].replace('_', ' ').capitalize() __import__(app) app = sys.modules[app] -- cgit v1.2.3