forked from 0x2620/pandora
log backend errors into db
This commit is contained in:
parent
36d5001608
commit
e458fed035
5 changed files with 71 additions and 12 deletions
|
@ -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
63
pandora/app/log.py
Normal 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()
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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,
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue