diff options
| -rw-r--r-- | README.rst | 2 | ||||
| -rw-r--r-- | debug_toolbar/panels/logger.py | 78 | ||||
| -rw-r--r-- | debug_toolbar/templates/debug_toolbar/panels/logger.html | 2 | 
3 files changed, 61 insertions, 21 deletions
| @@ -16,7 +16,7 @@ Currently, the following panels have been written and are working:  - Templates and context used, and their template paths  - SQL queries including time to execute and links to EXPLAIN each query  - List of signals, their args and receivers -- Logging output via Python's built-in logging module +- Logging output via Python's built-in logging, or via the `logbook <http://logbook.pocoo.org>`_ module  There is also one Django management command currently: diff --git a/debug_toolbar/panels/logger.py b/debug_toolbar/panels/logger.py index 620102e..0ddbfb1 100644 --- a/debug_toolbar/panels/logger.py +++ b/debug_toolbar/panels/logger.py @@ -8,16 +8,16 @@ from django.template.loader import render_to_string  from django.utils.translation import ugettext_lazy as _  from debug_toolbar.panels import DebugPanel -class ThreadTrackingHandler(logging.Handler): + +class LogCollector(object):      def __init__(self):          if threading is None:              raise NotImplementedError("threading module is not available, \                  the logging panel cannot be used without it") -        logging.Handler.__init__(self)          self.records = {} # a dictionary that maps threads to log records -    def emit(self, record): -        self.get_records().append(record) +    def add_record(self, record, thread=None): +        self.get_records(thread).append(record)      def get_records(self, thread=None):          """ @@ -36,20 +36,67 @@ class ThreadTrackingHandler(logging.Handler):          if thread in self.records:              del self.records[thread] -handler = ThreadTrackingHandler() + +class ThreadTrackingHandler(logging.Handler): +    def __init__(self, collector): +        logging.Handler.__init__(self) +        self.collector = collector + +    def emit(self, record): +        record = { +            'message': record.getMessage(), +            'time': datetime.datetime.fromtimestamp(record.created), +            'level': record.levelname, +            'file': record.pathname, +            'line': record.lineno, +            'channel': record.name, +        } +        self.collector.add_record(record) + + +collector = LogCollector() +logging_handler = ThreadTrackingHandler(collector)  logging.root.setLevel(logging.NOTSET) -logging.root.addHandler(handler) +logging.root.addHandler(logging_handler)  # register with logging + +try: +    import logbook +    logbook_supported = True +except ImportError: +    # logbook support is optional, so fail silently +    logbook_supported = False + +if logbook_supported: +    class LogbookThreadTrackingHandler(logbook.handlers.Handler): +        def __init__(self, collector): +            logbook.handlers.Handler.__init__(self, bubble=True) +            self.collector = collector + +        def emit(self, record): +            record = { +                'message': record.message, +                'time': record.time, +                'level': record.level_name, +                'file': record.filename, +                'line': record.lineno, +                'channel': record.channel, +            } +            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): -        handler.clear_records() +        collector.clear_records()      def get_and_delete(self): -        records = handler.get_records() -        handler.clear_records() +        records = collector.get_records() +        collector.clear_records()          return records      def nav_title(self): @@ -57,7 +104,7 @@ class LoggingPanel(DebugPanel):      def nav_subtitle(self):          # FIXME l10n: use ngettext -        return "%s message%s" % (len(handler.get_records()), (len(handler.get_records()) == 1) and '' or 's') +        return "%s message%s" % (len(collector.get_records()), (len(collector.get_records()) == 1) and '' or 's')      def title(self):          return _('Log Messages') @@ -66,16 +113,7 @@ class LoggingPanel(DebugPanel):          return ''      def content(self): -        records = [] -        for record in self.get_and_delete(): -            records.append({ -                'message': record.getMessage(), -                'time': datetime.datetime.fromtimestamp(record.created), -                'level': record.levelname, -                'file': record.pathname, -                'line': record.lineno, -            }) - +        records = self.get_and_delete()          context = self.context.copy()          context.update({'records': records}) diff --git a/debug_toolbar/templates/debug_toolbar/panels/logger.html b/debug_toolbar/templates/debug_toolbar/panels/logger.html index 5e8b652..c41749e 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/logger.html +++ b/debug_toolbar/templates/debug_toolbar/panels/logger.html @@ -5,6 +5,7 @@  			<tr>  				<th>{% trans "Level" %}</th>  				<th>{% trans "Time" %}</th> +				<th>{% trans "Channel" %}</th>  				<th>{% trans "Message" %}</th>  				<th>{% trans "Location" %}</th>  			</tr> @@ -14,6 +15,7 @@  				<tr class="{% cycle 'djDebugOdd' 'djDebugEven' %}">  					<td>{{ record.level }}</td>  					<td>{{ record.time|date:"h:i:s m/d/Y" }}</td> +					<td>{{ record.channel|default:"-" }}</td>  					<td>{{ record.message }}</td>  					<td>{{ record.file }}:{{ record.line }}</td>  				</tr> | 
