40 lines
1.2 KiB
Python
40 lines
1.2 KiB
Python
"""
|
|
调试中间件 — 捕获所有 500 错误并打印完整堆栈到日志
|
|
仅在测试阶段使用,上线前移除
|
|
"""
|
|
import logging
|
|
import traceback
|
|
|
|
logger = logging.getLogger('django')
|
|
|
|
|
|
class DebugExceptionMiddleware:
|
|
"""捕获所有未处理异常,打印完整堆栈到 gunicorn 日志"""
|
|
|
|
def __init__(self, get_response):
|
|
self.get_response = get_response
|
|
|
|
def __call__(self, request):
|
|
response = self.get_response(request)
|
|
if response.status_code == 500:
|
|
logger.error(
|
|
f"[500] {request.method} {request.path} "
|
|
f"user={getattr(request.user, 'UserName', 'anon')}"
|
|
)
|
|
return response
|
|
|
|
def process_exception(self, request, exception):
|
|
"""未处理异常 — 打印完整堆栈"""
|
|
tb = traceback.format_exc()
|
|
user_info = getattr(request.user, 'UserName', 'anon')
|
|
logger.error(
|
|
f"\n{'='*60}\n"
|
|
f"[EXCEPTION] {request.method} {request.path}\n"
|
|
f"User: {user_info}\n"
|
|
f"Type: {type(exception).__name__}: {exception}\n"
|
|
f"{'='*60}\n"
|
|
f"{tb}\n"
|
|
f"{'='*60}"
|
|
)
|
|
return None # 返回 None 让 Django 继续正常异常处理流程
|