drf自定义全局异常及日志记录

封装全局异常的目的有两个

  • 统一后端出现异常时前端收到的响应信息
  • 记录日志【尤其是异常和错误日志】

封装drf全局异常

drf内置的全局异常,只能捕获一部分的异常,其他的异常将会直接交给django处理。我们封装全局异常的一部分原因就是捕获那些drf没有处理的异常。

drf异常处理使用的是内置的exception_handler方法,我们可以在此基础上捕获那些没有被处理的异常。

因为没有被drf处理的异常在exception_handler中直接返回None,因此可以通过该方法的返回值判断需要我们自己处理的异常。

注意:捕获异常时出现异常,是不会被处理的 😦

# utils/exceptions.py
from rest_framework.views import exception_handler

from .response import APIResponse		# 自定义Response
from .logger import log					# 自定义的日志记录使用方法


def common_exception_handler(exc, context):
    # 记录日志
    log.error('view是:%s ,错误是%s' % (context['view'].__class__.__name__, str(exc)))
    print(context['view'].__class__.__name__)
    
    # 接收内置exception_handler的异常处理结果
    ret = exception_handler(exc, context)

    if not ret:
        # 处理drf未处理的异常
        if isinstance(exc, KeyError):
            return APIResponse(code=0, msg='key error')

        return APIResponse(code=0, msg='error', result=str(exc))
    else:
        # drf已经处理的异常
        return APIResponse(code=0, msg='error', result=ret.data)

全局异常配置

# settings/dev.py 配置文件

REST_FRAMEWORK = {
    # 全局配置setting.py
    'EXCEPTION_HANDLER': 'Luffyapi.utils.exceptions.common_exception_handler',
}

日志配置

日志模块的使用参考:loggin模块

# settings/dev.py	配置文件

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': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',
            # 日志位置,日志文件名,日志保存目录必须手动创建,注:这里的文件路径要注意BASE_DIR代表的是小luffyapi
            'filename': os.path.join(os.path.dirname(BASE_DIR), "logs", "luffy.log"),
            # 日志文件的最大值,这里我们设置300M
            'maxBytes': 300 * 1024 * 1024,
            # 日志文件的数量,设置最大日志数量为10
            'backupCount': 100,
            # 日志格式:详细格式
            'formatter': 'verbose',
            # 文件内容编码
            'encoding': 'utf-8'
        },
    },
    # 日志对象
    'loggers': {
        'django': {		# 使用该日志
            'handlers': ['console', 'file'],
            'propagate': True, # 是否让日志信息继续冒泡给其他的日志处理系统
        },
    }
}

封装日志

# utils/logger.py

import logging
log = logging.getLogger('django')

使用日志

在封装的全局异常内使用日志

# from Luffyapi.utils.logger import log
log.error('view是:%s ,错误是%s' % (context['view'].__class__.__name__, str(exc)))
posted @ 2020-07-19 11:33  the3times  阅读(1150)  评论(0编辑  收藏  举报