2012-12-06 22:00:34 +01:00
|
|
|
import sys
|
|
|
|
import logging
|
|
|
|
import traceback
|
|
|
|
|
|
|
|
from django.utils.timezone import now
|
|
|
|
from django.views.debug import get_exception_reporter_filter
|
|
|
|
|
|
|
|
|
|
|
|
class AdminHumbugHandler(logging.Handler):
|
|
|
|
"""An exception log handler that Humbugs log entries to the Humbug realm.
|
|
|
|
|
|
|
|
If the request is passed as the first argument to the log record,
|
|
|
|
request data will be provided in the email report.
|
|
|
|
"""
|
|
|
|
|
|
|
|
# adapted in part from django/utils/log.py
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
logging.Handler.__init__(self)
|
|
|
|
|
|
|
|
def emit(self, record):
|
|
|
|
# We have to defer imports to avoid circular imports in settings.py.
|
|
|
|
from zephyr.models import Message, UserProfile, Recipient, \
|
2012-12-06 23:43:15 +01:00
|
|
|
create_stream_if_needed, get_client, internal_send_message
|
2012-12-06 22:00:34 +01:00
|
|
|
from django.conf import settings
|
|
|
|
|
|
|
|
try:
|
|
|
|
request = record.request
|
2012-12-11 21:02:49 +01:00
|
|
|
subject = '%s: %s' % (
|
|
|
|
request.META["SERVER_NAME"],
|
2012-12-06 22:00:34 +01:00
|
|
|
record.getMessage()
|
|
|
|
)
|
2012-12-11 21:19:06 +01:00
|
|
|
request_repr = "Request info:\n\n"
|
2012-12-19 08:35:10 +01:00
|
|
|
|
|
|
|
|
|
|
|
filter = get_exception_reporter_filter(request)
|
2012-12-11 21:19:06 +01:00
|
|
|
request_repr += "- path: %s\n" % (request.path,)
|
|
|
|
if request.method == "GET":
|
|
|
|
request_repr += "- GET: %s\n" % (request.GET,)
|
|
|
|
elif request.method == "POST":
|
2012-12-19 08:35:10 +01:00
|
|
|
request_repr += "- POST: %s\n" % (filter.get_post_parameters(request),)
|
2012-12-11 21:19:06 +01:00
|
|
|
for field in ["REMOTE_ADDR", "QUERY_STRING"]:
|
|
|
|
request_repr += "- %s: %s\n" % (field, request.META.get(field, "(None)"))
|
2012-12-06 22:00:34 +01:00
|
|
|
except Exception:
|
|
|
|
subject = '%s: %s' % (
|
2012-12-11 21:02:49 +01:00
|
|
|
request.META["SERVER_NAME"],
|
2012-12-06 22:00:34 +01:00
|
|
|
record.getMessage()
|
|
|
|
)
|
|
|
|
request = None
|
|
|
|
request_repr = "Request repr() unavailable."
|
2012-12-06 23:43:15 +01:00
|
|
|
subject = self.format_subject(subject)
|
2012-12-06 22:00:34 +01:00
|
|
|
|
|
|
|
if record.exc_info:
|
2012-12-11 21:00:04 +01:00
|
|
|
stack_trace = ''.join(traceback.format_exception(*record.exc_info))
|
2012-12-06 22:00:34 +01:00
|
|
|
else:
|
|
|
|
stack_trace = 'No stack trace available'
|
|
|
|
|
2012-12-06 23:43:15 +01:00
|
|
|
internal_send_message("humbug+errors@humbughq.com",
|
|
|
|
Recipient.STREAM, "devel", subject,
|
2012-12-11 21:19:06 +01:00
|
|
|
"~~~~ pytb\n%s\n\n~~~~\n%s" % (stack_trace, request_repr))
|
2012-12-06 22:00:34 +01:00
|
|
|
|
|
|
|
def format_subject(self, subject):
|
|
|
|
"""
|
2012-12-07 01:05:14 +01:00
|
|
|
Escape CR and LF characters, and limit length to MAX_SUBJECT_LENGTH.
|
2012-12-06 22:00:34 +01:00
|
|
|
"""
|
2012-12-07 01:05:14 +01:00
|
|
|
from zephyr.models import MAX_SUBJECT_LENGTH
|
2012-12-06 22:00:34 +01:00
|
|
|
formatted_subject = subject.replace('\n', '\\n').replace('\r', '\\r')
|
2012-12-07 01:05:14 +01:00
|
|
|
return formatted_subject[:MAX_SUBJECT_LENGTH]
|
2012-12-06 22:00:34 +01:00
|
|
|
|