Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to add a header to the email django sends to admins when a 500 is generated?

I'm using a third party to send email, and they allow me to categorize my email by adding headers to the emails i send through them.

Is it possible to either add a header to the exception email before it gets sent? Or at least, I'll managing sending the email by catching the exception in the middleware, but how do I generate the nice email response django sends me on a 500?

EDIT: I know how to add headers to emails, I know how to process exception through middleware. I am interested in how to generate the same email that django sends on exception, so that i can add a header.

like image 603
MattoTodd Avatar asked Jan 06 '12 02:01

MattoTodd


People also ask

How do I send an email notification in Django REST framework?

Inside of the “send_mail.py”, create a function that takes in the following arguments. def send_mail(html,text='Email_body',subject='Hello word',from_email='',to_emails=[]): The next step would be to make sure that the “to_emails” argument is always a “list of emails” and not a string or any other data type.

How do I send an email to multiple recipients in Django?

How to send multiple mass emails django. We need to create a Tuple of messages and send them using send mass mail. In this tutorial, we create a project which sends email using Django. We fill the data in the form and send it using Django Email.


1 Answers

  1. Subclass AdminEmailHandler (defined in django.utils.log).
  2. Configure logging accordingly.

Here is how AdminEmailHandler works:

class AdminEmailHandler(logging.Handler):
    """An exception log handler that emails log entries to site admins.

    If the request is passed as the first argument to the log record,
    request data will be provided in the email report.
    """

    def __init__(self, include_html=False):
        logging.Handler.__init__(self)
        self.include_html = include_html

    def emit(self, record):
        try:
            request = record.request
            subject = '%s (%s IP): %s' % (
                record.levelname,
                (request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS and 'internal' or 'EXTERNAL'),
                record.msg
            )
            filter = get_exception_reporter_filter(request)
            request_repr = filter.get_request_repr(request)
        except:
            subject = '%s: %s' % (
                record.levelname,
                record.getMessage()
            )
            request = None
            request_repr = "Request repr() unavailable."

        if record.exc_info:
            exc_info = record.exc_info
            stack_trace = '\n'.join(traceback.format_exception(*record.exc_info))
        else:
            exc_info = (None, record.getMessage(), None)
            stack_trace = 'No stack trace available'

        message = "%s\n\n%s" % (stack_trace, request_repr)
        reporter = ExceptionReporter(request, is_email=True, *exc_info)
        html_message = self.include_html and reporter.get_traceback_html() or None
        mail.mail_admins(subject, message, fail_silently=True, html_message=html_message)

For reference only: my previous answer.

  1. Create a custom middleware: take inspiration from CommonMiddleware in https://code.djangoproject.com/browser/django/trunk/django/middleware/common.py (have a look at process_response)
  2. Create a function send_mail_with_exception_header based on https://code.djangoproject.com/browser/django/trunk/django/core/mail/message.py

Here is an example:

# Custom middleware

class MyErrorMiddleware(object):
    def process_response(self, request, response):
        if response.status_code == 404:
            domain = request.get_host()
            referer = request.META.get('HTTP_REFERER', None)
            is_internal = _is_internal_request(domain, referer)
            path = request.get_full_path()
                if referer and not _is_ignorable_404(path) and (is_internal or '?' not in referer):
                    ua = request.META.get('HTTP_USER_AGENT', '<none>')
                    ip = request.META.get('REMOTE_ADDR', '<none>')
                    mail_error("Broken %slink on %s" % ((is_internal and 'INTERNAL ' or ''), domain),
                        "Referrer: %s\nRequested URL: %s\nUser agent: %s\nIP address: %s\n" \
                                  % (referer, request.get_full_path(), ua, ip),
                                  fail_silently=True)
                return response

# Custom mail_error function

def mail_error(subject, message, fail_silently=False, connection=None,
                  html_message=None):
    """Sends a message to the managers, as defined by the MANAGERS setting."""
    if not settings.MANAGERS:
        return

    # put your extra headers here
    mail = EmailMultiAlternatives(u'%s%s' % (settings.EMAIL_SUBJECT_PREFIX, subject),
                message, settings.SERVER_EMAIL, [a[1] for a in settings.MANAGERS],
                connection=connection, header={})
    mail
    if html_message:
        mail.attach_alternative(html_message, 'text/html')
    mail.send(fail_silently=fail_silently)
like image 124
charlax Avatar answered Sep 26 '22 12:09

charlax