production-taskbar / backend / config / utils / log.py
log.py
Raw
from copy import copy

from django.conf import settings
from django.http.request import QueryDict
from django.utils.log import AdminEmailHandler
from django.views.debug import ExceptionReporter


# DRF Custom exception handling
def custom_exception_handler(exc, context):
    from rest_framework import views

    response = views.exception_handler(exc, context)

    # Replace the POST data of the Django request with the parsed data from the DRF
    if context['request'].method == 'POST':
        try:
            context['request']._request.POST = QueryDict(
                str(context['request'].data))
        except Exception as e:
            context['request']._request.POST = QueryDict(str(e))

    return response


class CustomExceptionReporter(ExceptionReporter):

    def get_traceback_data(self):
        data = super().get_traceback_data()

        # remove unnecessary settings
        del data['settings']
        del data['sys_path']
        del data['request_meta']

        return data


class CustomAdminEmailHandler(AdminEmailHandler):

    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(),
            )
        except Exception:
            subject = "%s: %s" % (record.levelname, record.getMessage())
            request = None
        subject = self.format_subject(subject)

        # Since we add a nicely formatted traceback on our own, create a copy
        # of the log record without the exception data.
        no_exc_record = copy(record)
        no_exc_record.exc_info = None
        no_exc_record.exc_text = None

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

        reporter = self.reporter_class(request, is_email=True, *exc_info)
        message = "%s\n%s" % (
            self.format(no_exc_record),
            reporter.get_traceback_text(),
        )
        html_message = reporter.get_traceback_html(
        ) if self.include_html else None
        self.send_mail(
            subject,
            message,
            fail_silently=True,
            html_message=html_message,
        )