Django 日志中间件全局捕获异常

该博客介绍了如何在Django项目中实现一个全局错误日志中间件,以便在发生异常时记录详细的错误信息。通过`process_exception`方法捕获异常,并使用logging模块将错误日志保存到文件。同时,展示了Django项目的日志配置,包括定义日志格式、处理方式和存储位置,确保信息的记录和调试便利。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

中间件

import json
import logging
import traceback

from django.http import HttpResponse
from django.utils.deprecation import MiddlewareMixin


class LogMiddle(MiddlewareMixin):
    """
    全局错误日志中间件
    """
    def process_exception(self, request, exception):
        print('发生异常', exception)
        logger_error = logging.getLogger('django')
        request_body = request.body
        request_url = request.get_raw_uri()
        request_method = request.method
        error_log = traceback.format_exc()
        error_msg = f"\nrequest_body: {request_body},\nrequest_url:{request_url}\nrequest_method:{request_method},\nexcept:{exception},\ndetailed_info:{error_log}"
        logger_error.error(error_msg)
        return HttpResponse(json.dumps(dict(code=500, data={}, msg="Some thing error")),
                            content_type="application/json")

settings MIDDLEWARE添加

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'journalmanage.middleware.LogMiddle'
]

settings logging配置

#所有的日志默认会存储到all-{}.log里

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
LOG_DIR = os.path.join(BASE_DIR, 'logs')  # LOG_DIR是存放日志的路径
if not os.path.exists(LOG_DIR): os.mkdir(LOG_DIR)  # 如果不存在这个logs文件夹,就自动创建一个
LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'formatters': {
        # 日志格式
        'standard': {
            'format': '[%(asctime)s] [%(filename)s:%(lineno)d] [%(module)s:%(funcName)s] '
                      '[%(levelname)s]- %(message)s'},
        'simple': {  # 简单格式
            'format': '%(levelname)s %(message)s'
        },
    },
    # 过滤
    'filters': {
    },
    # 定义具体处理日志的方式
    'handlers': {
        # 默认记录所有日志
        'default': {
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',#根据
            'filename': os.path.join(LOG_DIR, 'all-{}.log'.format(time.strftime('%Y-%m-%d'))),
            'maxBytes': 1024 * 1024 * 5,  # 文件大小
            'backupCount': 5,  # 备份数
            'formatter': 'standard',  # 输出格式
            'encoding': 'utf-8',  # 设置默认编码,否则打印出来汉字乱码
        },
        # 控制台输出
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'standard'
        },
    },
    # 配置用哪几种 handlers 来处理日志
    'loggers': {
        # 类型 为 django 处理所有类型的日志, 默认调用
        'django': {
            'handlers': ['default', 'console'],
            'level': 'INFO',
            'propagate': True
        },
        'django.request': {
            'handlers': ['default','console'],
            'level': 'INFO',
            'propagate': False  # 是否向上一级logger实例传递日志信息
        },
    }
}

<think>我们正在讨论Django中间件。根据引用[1],Django中间件是处理Django请求和响应的框架级别的钩子。它是一个轻量、低级别的插件系统,用于全局改变Django的输入或输出。每个中间件组件负责处理特定的功能,例如会话管理、CSRF保护等。中间件的工作原理(引用[2])是:在Django中,每个请求和响应都会通过中间件栈。中间件按照在MIDDLEWARE设置中定义的顺序执行。对于请求,中间件按照从上到下的顺序执行,而对于响应,则按照从下到上的顺序执行。中间件的类型(引用[3])主要分为两类:处理请求的中间件(如process_request)和处理响应的中间件(如process_response)。此外,还有process_view、process_exception和process_template_response等方法。使用方法(引用[3])是:首先创建一个中间件类,然后实现需要的方法(如process_request或process_response),最后在settings.py的MIDDLEWARE设置中注册这个中间件。注意中间件的顺序很重要。下面我们详细展开:1.**中间件的作用**:-全局修改请求:例如,在请求到达视图之前,我们可以对请求进行预处理(如添加属性、检查权限等)。-全局修改响应:在视图处理完请求后,我们可以对响应进行后处理(如添加HTTP头、修改响应内容等)。-其他功能:如引用[4]提到的,中间件还可以用于性能优化(缓存计算结果)、安全控制(如引用[5]提到的黑名单过滤)等。2.**中间件的原理**:-当一个HTTP请求到达Django时,首先会经过中间件栈(按MIDDLEWARE列表顺序)的process_request方法。-然后,Django会解析URL找到对应的视图函数。在调用视图函数之前,会经过中间件的process_view方法(按顺序)。-如果视图函数抛出异常,则会触发中间件的process_exception方法(按倒序)。-最后,在返回响应时,会经过中间件的process_response方法(按倒序)。3.**自定义中间件的使用方法**:-创建中间件类:在某个app下创建middleware.py文件,然后定义一个类,例如:```pythonclassSimpleMiddleware:def__init__(self,get_response):self.get_response=get_responsedef__call__(self,request):#在视图调用之前的代码(按中间件顺序执行)response=self.get_response(request)#调用下一个中间件或视图#在视图调用之后的代码(按中间件逆序执行)returnresponse```或者使用更细粒度的方法(如process_request,process_response等)。-注册中间件:在settings.py的MIDDLEWARE列表中添加自定义中间件的路径,例如:`'myapp.middleware.SimpleMiddleware'`。4.**注意事项**(引用[3]和引用[4]):-中间件的顺序非常重要,因为它决定了执行的顺序。-在process_view中修改参数时要小心,避免污染原始视图参数(建议使用深拷贝)。-中间件可以中断请求,直接返回响应(例如在process_request中返回HttpResponse,那么后续中间件和视图将不会执行)。举例说明:一个记录请求耗时的中间件```pythonimporttimeclassTimingMiddleware:def__init__(self,get_response):self.get_response=get_responsedef__call__(self,request):start_time=time.time()response=self.get_response(request)duration=time.time()-start_timeprint(f"Requestto{request.path}took{duration:.2f}seconds.")#可以添加响应头response['X-Request-Duration']=str(duration)returnresponse```在settings.py中注册:```pythonMIDDLEWARE=[#...其他中间件'myapp.middleware.TimingMiddleware',]```这个中间件会在每个请求处理完成后记录耗时,并在响应头中添加`X-Request-Duration`。总结:Django中间件是一个强大的工具,可以在请求/响应的全局层面进行干预,实现诸如日志记录、权限验证、性能优化等功能。§§相关问题§§1.Django中间件的执行顺序是怎样的?2.如何在中间件中处理异常?3.中间件和装饰器有什么区别?4.如何测试Django中间件?5.中间件中哪些方法必须实现?</think>### Django 中间件详解 #### 一、中间件的作用 中间件Django 处理请求/响应流程的核心组件,主要功能包括: 1. **全局请求处理**:在视图执行前拦截请求(如身份验证、CSRF 保护)[^1][^5] 2. **全局响应处理**:在视图执行后修改响应(如添加 HTTP 头、压缩内容) 3. **异常处理**:统一捕获视图抛出的异常[^3] 4. **性能优化**:缓存计算结果、请求耗时统计等[^4] 5. **安全控制**:IP 黑名单过滤、XSS 防护等[^5] #### 二、工作原理 中间件按 `settings.py` 中定义的顺序组成处理链: ```python # settings.py 配置示例 MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', # 安全防护 'django.contrib.sessions.middleware.SessionMiddleware', # 会话管理 'django.middleware.common.CommonMiddleware', # URL标准化 'django.middleware.csrf.CsrfViewMiddleware', # CSRF防护 'myapp.middleware.CustomMiddleware', # 自定义中间件 ] ``` **处理流程**: 1. 请求进入时按**从上到下**顺序执行 `process_request()` 方法 2. 执行视图前按顺序执行 `process_view()` 方法[^4] 3. 视图处理请求 4. 响应返回时按**从下到上**顺序执行 `process_response()` 方法 5. 异常发生时按**倒序**执行 `process_exception()` 方法[^3] #### 三、自定义中间件开发 1. **创建中间件类**(在 app 的 middleware.py 中): ```python # myapp/middleware.py import time from copy import deepcopy class PerformanceMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): # 请求处理前 start_time = time.time() # 调用下一个中间件/视图 response = self.get_response(request) # 响应处理后 duration = time.time() - start_time response.headers['X-Response-Time'] = f'{duration:.2f}s' return response def process_view(self, request, view_func, view_args, view_kwargs): # 深拷贝避免污染原始参数[^4] safe_kwargs = deepcopy(view_kwargs) # 可在此预处理视图参数 return None ``` 2. **注册中间件**: ```python # settings.py MIDDLEWARE = [ ... 'myapp.middleware.PerformanceMiddleware', ] ``` #### 四、关键方法说明 | 方法 | 执行时机 | 返回值作用 | |---------------------|----------------------------|------------------------------| | `process_request` | 请求到达路由前 | 返回 None 继续,返回响应则中断 | | `process_view` | 路由解析后,视图执行前[^4] | 同上 | | `process_response` | 视图返回响应后 | 必须返回响应对象 | | `process_exception` | 视图抛出异常时 | 返回 None 继续,响应则处理异常 | #### 五、最佳实践 1. **顺序敏感**:安全中间件应放在顶部,响应处理中间件放底部[^3] 2. **避免副作用**:在 `process_view` 中修改参数需用深拷贝[^4] 3. **性能优化**:在中间件缓存重复计算结果[^4] ```python class CacheMiddleware: def process_view(self, request, view_func, *args): cache_key = f"view_data:{request.path}" if cached := cache.get(cache_key): return cached # 直接返回缓存响应 return None ``` 4. **异常处理**:统一错误日志记录 ```python class ErrorLoggingMiddleware: def process_exception(self, request, exception): logger.error(f"{request.path} error: {str(exception)}") return None # 交由下一个中间件处理 ``` #### 六、典型应用场景 1. **安全控制**:CSRF 验证、IP 黑名单[^5] 2. **会话管理**:自动绑定用户会话[^2] 3. **性能监控**:请求耗时统计(如上示例) 4. **A/B 测试**:根据请求特征路由到不同视图 5. **内容处理**:响应压缩、移动端适配 > 中间件本质是 Django 的插件系统,通过介入请求/响应生命周期实现横切关注点(cross-cutting concerns),避免在视图函数中重复相同逻辑[^1][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值