全局异常捕获与日志
目录
定义全局异常信息返回格式
- 调用内置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, 就提示文章质量低!!!
-
加入手写bug