当服务器错误时,同时将邮件请求主体发送给Django管理员

10

我在Django中使用默认记录器,其配置如下:

LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
    '()': 'django.utils.log.RequireDebugFalse'
    }
},
'handlers': {
    'mail_admins': {
        'level': 'ERROR',
        'filters': ['require_debug_false'],
        'class': 'django.utils.log.AdminEmailHandler'
    },
    'console': {
        'level': 'DEBUG',
        'class': 'logging.StreamHandler'
    }
},
'loggers': {
    'django.request': {
        'handlers': ['mail_admins', 'console'],
        'level': 'ERROR',
        'propagate': True,
    },
}
所以每当我收到500错误时,我会在管理员电子邮件中正确收到邮件,但它不会发送POST请求JSON数据。我发送的请求如下:
}

curl -X POST -H 'Content-Type: application/json'  http://127.0.0.1/api/customer/ -d "{'username':'rajeevnith', 'frist_name': 'Rajeev', 'last_name':'Bahrdwaj'}"

我们如何配置Django记录器以将此请求正文发送出去?


你可能想看一下这个:http://stackoverflow.com/a/13940055/2028375 - Daniele Bernardini
它真的没有记录请求吗?我有一个非常相似的默认日志设置,我在我的日志中看到整个请求对象。 Django文档甚至指出使用额外参数记录请求对象:https://docs.djangoproject.com/ja/1.9/topics/logging/#django-request 这让我觉得要么你只是没有看到它,它确实存在,要么你在代码中某个地方覆盖了它的行为方式。 - Titus P
@TitusP 不,它并没有发送整个请求对象。它只发送 request.GET、request.POST、request.FILES、request.COOKIES 和 request.META,而在以 Content-Type: application/json 形式发布数据时,数据会出现在 request.body 中。 - r.bhardwaj
Django 版本? - Ella Sharakanski
@EllaShar 1.9.7 - r.bhardwaj
我对curl不是很熟悉,但我认为URL应该是最后一个参数。所以也许你根本没有发送任何POST数据? - Ella Sharakanski
2个回答

1
截至Django v3.1,可能最快的一种方法是将您的类添加到settings.py中。
DEFAULT_EXCEPTION_REPORTER = 'package.log.CustomExceptionReporter'

然后在 log.py 中:
class CustomExceptionReporter(ExceptionReporter):
    def get_traceback_data(self):
        data = super().get_traceback_data()
        
        #remove settings
        del data['settings']
        
        #add body if it exists
        if self.request is not None:
            if self.request.method == "POST":
                try:
                    data['request_body'] = request.body
                except:
                    data['request_body'] = None
                
            
        return data

0
我们使用像这样的管理员电子邮件处理程序,可处理任何类型的错误。希望它对你有用。
class MyAdminEmailHandler(AdminEmailHandler):

    def __init__(MyAdminEmailHandler, include_html=False, email_backend=None):
        super(MyAdminEmailHandler, self).__init__(self, include_html, email_backend)

    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{0}'.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

        try:
            mail.mail_admins(subject, message, fail_silently=True,
                             html_message=html_message,
                             connection=self.connection())
        except Exception as e:
            console_logger.warn("%s : %s" % (__name__, str(e)))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接