log backend errors into db

This commit is contained in:
j 2011-10-27 14:26:05 +02:00
parent 36d5001608
commit e458fed035
5 changed files with 71 additions and 12 deletions

View file

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4 # vi:si:et:sw=4:sts=4:ts=4
from __future__ import division, with_statement from __future__ import division, with_statement

63
pandora/app/log.py Normal file
View file

@ -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()

View file

@ -24,7 +24,7 @@ class Log(models.Model):
text = models.TextField(blank=True) text = models.TextField(blank=True)
def __unicode__(self): def __unicode__(self):
return self.id return u"%s" % self.id
def json(self): def json(self):
return { return {

View file

@ -108,17 +108,18 @@ def log(request):
} }
''' '''
data = json.loads(request.POST['data']) data = json.loads(request.POST['data'])
if not request.user.is_authenticated: if request.user.is_authenticated():
user = request.user user = request.user
else: else:
user = None user = None
if 'text' in data: if 'text' in data:
l = models.Log( l = models.Log(
user=user,
text=data['text'], text=data['text'],
line=int(data.get('line', 0)), line=int(data.get('line', 0)),
url=data.get('url', '') url=data.get('url', '')
) )
if user:
l.user = user
l.save() l.save()
response = json_response() response = json_response()
return render_to_json_response(response) return render_to_json_response(response)

View file

@ -144,23 +144,19 @@ INSTALLED_APPS = (
'urlalias', 'urlalias',
) )
# A sample logging configuration. The only tangible logging # Log errors into db
# 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.
LOGGING = { LOGGING = {
'version': 1, 'version': 1,
'disable_existing_loggers': False, 'disable_existing_loggers': False,
'handlers': { 'handlers': {
'mail_admins': { 'errors': {
'level': 'ERROR', 'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler' 'class': 'pandora.app.log.ErrorHandler'
} }
}, },
'loggers': { 'loggers': {
'django.request': { 'django.request': {
'handlers': ['mail_admins'], 'handlers': ['errors'],
'level': 'ERROR', 'level': 'ERROR',
'propagate': True, 'propagate': True,
}, },