From e458fed035cf19a924d0ff2fd9158e797c83be3f Mon Sep 17 00:00:00 2001 From: j <0x006A@0x2620.org> Date: Thu, 27 Oct 2011 14:26:05 +0200 Subject: [PATCH] log backend errors into db --- pandora/app/config.py | 1 - pandora/app/log.py | 63 +++++++++++++++++++++++++++++++++++++++++++ pandora/app/models.py | 2 +- pandora/app/views.py | 5 ++-- pandora/settings.py | 12 +++------ 5 files changed, 71 insertions(+), 12 deletions(-) create mode 100644 pandora/app/log.py diff --git a/pandora/app/config.py b/pandora/app/config.py index 0eded561..875cb1a4 100644 --- a/pandora/app/config.py +++ b/pandora/app/config.py @@ -1,4 +1,3 @@ - # -*- coding: utf-8 -*- # vi:si:et:sw=4:sts=4:ts=4 from __future__ import division, with_statement diff --git a/pandora/app/log.py b/pandora/app/log.py new file mode 100644 index 00000000..715e8692 --- /dev/null +++ b/pandora/app/log.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# vi:si:et:sw=4:sts=4:ts=4 +from __future__ import division, with_statement + +import logging +import sys + + +class ErrorHandler(logging.Handler): + def __init__(self): + logging.Handler.__init__(self) + + """An exception log handler that log entries into log database. + + If the request is passed as the first argument to the log record, + request data will be provided in the + """ + def emit(self, record): + import traceback + from django.views.debug import ExceptionReporter + from django.conf import settings + import models + user = None + line = 0 + text = '' + url = '' + try: + if sys.version_info < (2,5): + # A nasty workaround required because Python 2.4's logging + # module doesn't support passing in extra context. + # For this handler, the only extra data we need is the + # request, and that's in the top stack frame. + request = record.exc_info[2].tb_frame.f_locals['request'] + else: + request = record.request + + request_repr = repr(request) + if request.user.is_authenticated(): + user = request.user + url = request.META.get('PATH_INFO', '') + except: + request = None + request_repr = "%s %s\n\nRequest repr() unavailable" % (record.levelname, record.msg) + + if record.exc_info: + stack_trace = '\n'.join(traceback.format_exception(*record.exc_info)) + stack_info = traceback.extract_tb(record.exc_info[2]) + if stack_info: + url = stack_info[-1][0] + line = stack_info[-1][1] + else: + stack_trace = 'No stack trace available' + + text = "%s\n\n%s" % (stack_trace, request_repr) + if text: + l = models.Log( + text=text, + line=line, + url=url + ) + if user: + l.user = user + l.save() diff --git a/pandora/app/models.py b/pandora/app/models.py index 1f6a8ab6..1b134435 100644 --- a/pandora/app/models.py +++ b/pandora/app/models.py @@ -24,7 +24,7 @@ class Log(models.Model): text = models.TextField(blank=True) def __unicode__(self): - return self.id + return u"%s" % self.id def json(self): return { diff --git a/pandora/app/views.py b/pandora/app/views.py index c6c86a68..f07e49ff 100644 --- a/pandora/app/views.py +++ b/pandora/app/views.py @@ -108,17 +108,18 @@ def log(request): } ''' data = json.loads(request.POST['data']) - if not request.user.is_authenticated: + if request.user.is_authenticated(): user = request.user else: user = None if 'text' in data: l = models.Log( - user=user, text=data['text'], line=int(data.get('line', 0)), url=data.get('url', '') ) + if user: + l.user = user l.save() response = json_response() return render_to_json_response(response) diff --git a/pandora/settings.py b/pandora/settings.py index 0615aba0..e4cda557 100644 --- a/pandora/settings.py +++ b/pandora/settings.py @@ -144,23 +144,19 @@ INSTALLED_APPS = ( 'urlalias', ) -# A sample logging configuration. The only tangible logging -# performed by this configuration is to send an email to -# the site admins on every HTTP 500 error. -# See http://docs.djangoproject.com/en/dev/topics/logging for -# more details on how to customize your logging configuration. +# Log errors into db LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { - 'mail_admins': { + 'errors': { 'level': 'ERROR', - 'class': 'django.utils.log.AdminEmailHandler' + 'class': 'pandora.app.log.ErrorHandler' } }, 'loggers': { 'django.request': { - 'handlers': ['mail_admins'], + 'handlers': ['errors'], 'level': 'ERROR', 'propagate': True, },