拦截 Django 500 错误进行日志记录,而不创建/提供自定义 500.html

Mik*_*ans 3 python django http-status-code-500

为了记录触发服务器错误 500 的“某些依赖性,某处很深”的错误,并且在生产实例上的控制台日志中没有堆栈跟踪DEBUG=False,我实现了标准自定义 500 处理程序,该处理程序解决了相当多的 Stackoverflow 关于打印堆栈的问题跟踪 500 错误建议:

import sys
import traceback

def server_error_500_handler(request):
    type, value, tb = sys.exc_info()
    print('\n----intercepted 500 error stack trace----')
    print(value)
    print(type)
    print(traceback.format_exception(type, value, tb))
    print('----\n')
Run Code Online (Sandbox Code Playgroud)

然而,这些也都以 结尾render(request, '500.html'),而我不想提供自定义的 500 页面,而是希望代码“返回”(如果有这样的事情)只提供 Django 本身已经做的任何事情。有什么方法可以让它做到这一点吗?或者,是否有某种方法可以侦听 500 事件而不劫持 500 错误返回代码路径?

Abd*_*kat 5

不要制作自定义 500 处理程序,而是制作您自己的自定义中间件process_exception并在其中实现一个方法:

import traceback


class Log500ErrorsMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        return response
    
    def process_exception(self, request, exception):
        print('\n----intercepted 500 error stack trace----')
        print(exception)
        print(type(exception))
        tb = exception.__traceback__
        print(traceback.format_exception(type(exception), exception, tb))
        print('----\n')
        return None # Let other middlewares do further processing
Run Code Online (Sandbox Code Playgroud)

然后将其添加到MIDDLEWARE设置中,一直到最后,因为中间件在响应/异常阶段按自下而上的顺序运行,所以如果你把它放在最后,它总是会运行(某些中间件可以决定短路否则返回响应,因此后面有任何内容可能会阻止它运行)。

MIDDLEWARE = [
    ...
    'path.to.Log500ErrorsMiddleware',
]
Run Code Online (Sandbox Code Playgroud)