如何在Django中为未处理异常保留自定义日志名称
解决Django未处理异常日志使用自定义Logger的方案
要让未处理异常使用你通过logging.getLogger(__name__)声明的模块级Logger,而非Django默认的django.request,可以通过自定义异常处理中间件实现:
步骤1:编写自定义异常日志中间件
创建中间件文件(如myapp/middleware.py),捕获未处理异常并定位到抛出异常的原始模块,再用对应模块的Logger记录日志:
import logging import sys from django.http import HttpResponseServerError class CustomExceptionLoggingMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): return self.get_response(request) def process_exception(self, request, exception): # 追踪异常栈,找到抛出异常的最内层模块 tb = sys.exc_info()[2] while tb.tb_next: tb = tb.tb_next frame = tb.tb_frame module_name = frame.f_globals['__name__'] # 获取对应模块的Logger实例 logger = logging.getLogger(module_name) # 记录异常,包含请求路径和完整栈信息 logger.error( f"未处理异常,请求路径: {request.path}", exc_info=sys.exc_info(), extra={'request': request} ) # 返回Django默认的500错误响应(可自定义) return HttpResponseServerError()
步骤2:替换默认异常中间件
在settings.py的MIDDLEWARE列表中,将Django默认的django.middleware.exception.ExceptionMiddleware替换为你的自定义中间件:
MIDDLEWARE = [ # 其他中间件保持不变 # 'django.middleware.exception.ExceptionMiddleware', 注释或删除这一行 'myapp.middleware.CustomExceptionLoggingMiddleware', # 后续中间件保持不变 ]
步骤3:配置Logging
确保你的模块级Logger有对应的处理器,同时禁用django.request的默认日志输出以避免重复记录:
LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'verbose': { 'format': '{levelname} {asctime} {module} {message}', 'style': '{', }, }, 'handlers': { 'console': { 'class': 'logging.StreamHandler', 'formatter': 'verbose', }, }, 'loggers': { # 配置你的应用模块Logger,示例为myapp 'myapp': { 'handlers': ['console'], 'level': 'DEBUG', 'propagate': False, }, # 禁用django.request的默认日志 'django.request': { 'handlers': [], 'level': 'CRITICAL', 'propagate': False, }, }, }
说明
- 该方案会自动定位到抛出异常的原始模块(如视图函数所在模块、工具类模块等),使用你预先声明的
__name__对应的Logger记录日志,保留完整的模块信息。 - 如果异常来自Django内部模块(如模板、ORM),也会使用对应Django模块的Logger记录,符合你的日志命名规则。
内容的提问来源于stack exchange,提问作者Jaime Escobar
相关产品推荐
相关产品推荐

