Loading

全局异常捕获与日志

定义全局异常信息返回格式

  • 调用内置exception_handler异常处理模块处理三大认证的异常.
  • 调用自定义Response对象ResponseDataFormat统一返回的数据格式.

定义全局异常信息返回格式

# 2. 定义全局异常信息返回格式
from rest_framework.views import exception_handler
from utils.response import ResponseDataFormat


def exception_response(exc, context):
    # 调用内置的异常处理模块, 接收返回值
    response = exception_handler(exc, context)
    # 判断返回的数据是否被内部的异常模块处理过(没有处理过返回None, 处理过返回的是一个response对象, 错误提示data属性中)
    if response:
        data = response.date.get('detail')
        code = 200
        msg = "访问成功"
    else:
        data = str(exc)
        code = 400
        msg = "访问失败"

    # 可以通过isinstance(exc, 错误类型) 对异常进行细分, 就不细分了, exc是一个错误类型的子对象
    return ResponseDataFormat(code=code, msg=msg, data=data)

在dev.py配置文件中配置全局使用的异常处理模块

# 配置全局使用的异常处理程序
REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'utils.exceptions.exception_response',
}

日志配置

  • 在dev.py中添加日志模块的配置字典(Django官网提供的)

    logs目录下会自动创建luffy.log 文件

    # 字典, 日志的配置信息
    LOGGING = {
        # 版本
        'version': 1,
        # 禁用现有的记录器
        'disable_existing_loggers': False,
        # 日志的格式(定义两个不同的格式)
        'formatters': {
            # 详细的版本
            'verbose': {
                'format': '%(levelname)s %(asctime)s %(module)s %(lineno)d %(message)s'
            },
            # 简单的版本
            'simple': {
                'format': '%(levelname)s %(module)s %(lineno)d %(message)s'
            },
        },
        # 过滤日志
        'filters': {
            'require_debug_true': {
                '()': 'django.utils.log.RequireDebugTrue',
            },
        },
        # 显示
        'handlers': {
            # 打印到终端的日志
            'console': {
                # 实际开发建议使用WARNING
                'level': 'DEBUG',  # 级别
                'filters': ['require_debug_true'],
                'class': 'logging.StreamHandler',
                'formatter': 'simple'  # 使用的格式
            },
            # 写入到文件
            'file': {
                # 实际开发建议使用ERROR
                'level': 'ERROR',  # 级别
                'class': 'logging.handlers.RotatingFileHandler',
                # 日志位置, 日志文件名, 日志保存目录必须手动创建, 注:BASE_DIR是项目名目录
                'filename': os.path.join(os.path.dirname(BASE_DIR), "logs", "luffy.log"),
                # 日志文件的最大值,这里我们设置300M
                'maxBytes': 300 * 1024 * 1024,
                # 日志文件的数量,设置最大日志数量为10
                'backupCount': 10,
                # 日志格式:详细格式
                'formatter': 'verbose',
                # 文件内容编码
                'encoding': 'utf-8'
            },
        },
        # 日志对象
        'loggers': {
            'django': {
                # 将日志打印到终端 并 写入到文件
                'handlers': ['console', 'file'],
                'propagate': True,  # 是否让日志信息继续冒泡给其他的日志处理系统
            },
        }
    }
    
  • 在utils.py 新建logger.py模块, 模块中生成日志对象, 方便以后的调用.

    # 导入logging模块
    import logging
    # 模块通过getLogger方法拿到配置文件中日志配置字段的loggers的django配置, 生成一个logging对象
    log = logging.getLogger('django')
    

在异常响应中记录日志

# 2. 定义全局异常信息返回格式
from rest_framework.views import exception_handler

from utils.response import ResponseDataFormat
from utils.logger import log


def exception_response(exc, context):
    # 调用内置的异常处理模块, 接收返回值
    ret = exception_handler(exc, context)
    print('=====')
    # 判断返回的数据是否被内部的异常模块处理过(没有处理过返回None, 处理过返回的是一个response对象, 错误提示data属性中)
    if ret:
        data = ret.date.get('detail')
        code = 200
        msg = "访问成功"
    else:
        data = str(exc)
        code = 400
        msg = "访问失败"

    # 组织日志格式
    # context["view"]拿到的当前的视图对象, 视图对象__class__ 拿到视图类类 视图类.__name__ 拿到视图类名称
    view = context["view"].__class__.__name__

    log_format = (f'当前视图: {view}, 报错信息: {data}.')
    # 记录日志
    log.error(log_format)

    # 可以通过isinstance(exc, 错误类型) 对异常进行细分, 就不细分了, exc是一个错误类型的子对象
    return ResponseDataFormat(code=code, msg=msg, data=data)

测试

  • 在项目名目录下的urls.py总路由文件中设置路由分发

    from django.urls import path, re_path, include
    
    urlpatterns = [
        # 路由分发到user app
        re_path('home/', include('home.urls'))
    ]
    
  • 在home目录下新建urls.py 子路由文件

    from django.urls import re_path
    # 导入视图类
    from home import views
    
    urlpatterns = [
        # 1. 异常&日志测试路由
        re_path('exception_log/', views.ExceptionLog.as_view())
    ]
    
  • 在apps目录下的views.py 视图层中写测试的视图类

    # 1. 异常&日志测试
    from rest_framework.views import APIView
    from utils.exceptions import ResponseDataFormat
    
    
    class ExceptionLog(APIView):
        def get(self, request):
            # print(xxx)  # 这里加bug
            return ResponseDataFormat(data='异常&日志测试!')
    
  • 启动程序正常访问

    * 4. 启动程序正常访问 (三大认证与视图类中现在是没有任何错误的)
         127.0.0.1:8000/home/exception_log/
         # csnd你牛逼在前上面这个链接加了http, 就提示文章质量低!!!
    

    image

    image

  • 加入手写bug

    image

    image

posted @ 2022-12-01 23:52  爱learn  阅读(77)  评论(0编辑  收藏  举报