1

I am trying to send a mail to ADMIN when any exception is occurred in django. So i tried but not able to find the solution. I don't have a clear idea about how to send a error mail to admin Any help would be appreciated.

Views.py

def emit(self, record):
    try:
        request = record.request
        subject = '%s (%s IP): %s' % (
            record.levelname,
            ('internal' if request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS
            else 'EXTERNAL'),
            record.getMessage()
        )
        filter = get_exception_reporter_filter(request)
        request_repr = '\n{}'.format(force_text(filter.get_request_repr(request)))
    except Exception:
        subject = '%s: %s' % (
            record.levelname,
            record.getMessage()
        )
        request = None
        request_repr = "unavailable"
    subject = self.format_subject(subject)

    if record.exc_info:
        exc_info = record.exc_info
    else:
        exc_info = (None, record.getMessage(), None)

    message = "%s\n\nRequest repr(): %s" % (self.format(record), request_repr)
    reporter = ExceptionReporter(request, is_email=True, *exc_info)
    html_message = reporter.get_traceback_html() if self.include_html else None
    self.send_mail(subject, message, fail_silently=True, html_message=html_message)

def send_mail(self, subject, message, *args, **kwargs):
    mail.mail_admins(subject, message, *args, connection=self.connection(), **kwargs)


def connection(self):
    return get_connection(backend=self.email_backend, fail_silently=True)

def format_subject(self, subject):
    """
    Escape CR and LF characters, and limit length.
    RFC 2822's hard limit is 998 characters per line. So, minus "Subject: "
    the actual subject must be no longer than 989 characters.
    """
    formatted_subject = subject.replace('\n', '\\n').replace('\r', '\\r')
    return formatted_subject[:989]

def test_view(request):
    try:
        raise Exception
    except Exception as e:
        send_mail(self, subject, message, *args, **kwargs)

logger_setting.py

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse',
        },
        'require_debug_true': {
            '()': 'django.utils.log.RequireDebugTrue',
        },
    },
    'handlers': {
        'console': {
            'level': 'INFO',
            'filters': ['require_debug_true'],
            'class': 'logging.StreamHandler',
        },
        'null': {
            'class': 'logging.NullHandler',
        },
        'mail_admins': {
            'level': 'ERROR',
            'filters': ['require_debug_false'],
            'class': 'django.utils.log.AdminEmailHandler'
        }
    },
    'loggers': {
        'django': {
            'handlers': ['console'],
        },
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': False,
        },
        'django.security': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': False,
        },
        'py.warnings': {
            'handlers': ['console'],
        },
    }
}

I also tried by changing my view.py code as following but didn't any error mail

import sys
import traceback
from django.core import mail
from django.views.debug import ExceptionReporter

def send_manually_exception_email(request, e):
    exc_info = sys.exc_info()
    reporter = ExceptionReporter(request, is_email=True, *exc_info)
    subject = e.message.replace('\n', '\\n').replace('\r', '\\r')[:989]
    message = "%s\n\n%s" % (
        '\n'.join(traceback.format_exception(*exc_info)),
        reporter.filter.get_request_repr(request)
    )
    mail.mail_admins(
        subject, message, fail_silently=True,
        html_message=reporter.get_traceback_html()
    )

Generating a test exception-

def test_view(request):
    try:
        raise Exception
    except Exception as e:
        send_manually_exception_email(request, e)
Prashant
  • 402
  • 1
  • 8
  • 24

1 Answers1

4

First follow these instructions: https://docs.djangoproject.com/en/dev/howto/error-reporting/#email-reports

and set the settings for EMAIL_HOST, EMAIL_HOST_USER, EMAIL_HOST_PASSWORD, ADMINS, and SERVER_EMAIL.

You'll also need to set an email server. For starters, any of these will do:

  • an email program (like sendmail)
  • an email server (like Sendgrid)
  • the python debugging email server python -m smtpd -n -c DebuggingServer localhost:1025

The values for your settings must match the email server that you choose.

Don't worry about the using email with logging until you get the simple case configured from settings first.

Mark Chackerian
  • 21,866
  • 6
  • 108
  • 99
  • Yes, all very true. And if the thing still does not work, read this: https://stackoverflow.com/questions/20282521/django-request-logger-not-propagated-to-root/22336174#22336174 – Chris Apr 18 '18 at 12:15