項目目錄結(jié)構(gòu)
---study_drf
? ? ? ? ---study_drf
? ? ? ? ? ? ? ? ---settings.py
? ? ? ? ---utils
? ? ? ? ? ? ? ? ---log.py
? ? ? ? ? ? ? ? ---exception.py
項目依賴
Django==3.2 django-cors-headers==3.5.0 djangorestframework==3.12.2 djangorestframework-jwt==1.11.0 mysqlclient==2.1.1 pinyin==0.4.0 #拼音處理 PyJWT==1.7.1 fpdf==1.7.2 #生成pdf文件 APScheduler==3.10.1 #輕量級定時任務(wù) redis==4.6.0 #操作redis數(shù)據(jù)庫的
要使用drf的Response做為響應(yīng)對象,需要先注冊app
settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',#使用rest_framework的Response需要注冊
]
一、utils/log.py
1、setting.py配置日志
#######--配置日志,
#1、配置日志要保存的文件夾,創(chuàng)建文件夾
import time
BASE_LOG_DIR = os.path.join(BASE_DIR, 'logs')
ERROR_PATH_DIR = os.path.join(BASE_LOG_DIR,'error')
if not os.path.exists(ERROR_PATH_DIR):
#如果logs/error/不存在,遞歸創(chuàng)建目錄
os.makedirs(ERROR_PATH_DIR)
ALL_PATH_DIR = os.path.join(BASE_LOG_DIR,'all')
if not os.path.exists(ALL_PATH_DIR):
#如果logs/all/目錄不存在,就遞歸創(chuàng)建(如果logs目錄不存在,也會創(chuàng)建)
os.makedirs(ALL_PATH_DIR)
#2、相關(guān)的日志配置
LOGGING = {
'version': 1,
'disable_existing_loggers': False, # 設(shè)置已存在的logger不失效
'filters': {
},
'formatters': {
'standard': {
'format': '[%(asctime)s][%(levelname)s][%(filename)s:%(lineno)d:%(funcName)s]:%(message)s',
'datefmt': '%Y-%m-%d %H:%M:%S'
},
'simple': {
'format': '[%(asctime)s][%(levelname)s]:%(message)s',
'datefmt': '%Y-%m-%d %H:%M:%S'
}
},
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'file': { #按照文件大小分割日志,將所有的日志信息都保存在這里
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
'filename': os.path.join(BASE_LOG_DIR,'all', 'debug.log'),
'maxBytes': 1024 * 1024 * 50, # 日志大小50M
'backupCount': 5,
'formatter': 'standard',
'encoding': 'utf-8',
},
#os.path.join(BASE_LOG_DIR,'error',f"{time.strftime('%Y-%m-%d')}.log")
'time_file':{#按照時間分割日志,每周一新增一個日志文件,存error等級以上的日志
'level': 'INFO',#日志的等級
'class': 'logging.handlers.TimedRotatingFileHandler',
'filename':os.path.join(BASE_LOG_DIR,'error',f"{time.strftime('%Y-%m-%d')}.log") ,#日志的文件名
'when': 'D', #時間單位,S,M,H,D,'W0'(星期1),'W6'(星期天)
'interval': 1,
'backupCount': 5, #備份數(shù)量
'formatter': 'standard', #使用的日志格式
'encoding': 'utf-8',
}
},
'loggers': {
#INFO以上日志,打印在console,也寫到以文件大小分割的日志中
'django': {
'handlers': ['console','file'],#handlers中存在的配置
'level': 'INFO',
'propagate': True
},
#error以上的日志寫到按時間分割的日志文件中,同時打印在控制臺
'django.request': {
'handlers': ['time_file'],#handlers中存在的配置
'level': 'ERROR',
'propagate': True
},
},
}
2、utils/log.py,拿到配置的日志處理對象,實現(xiàn)手動記錄日志
#手動寫日志
import logging
info_logger = logging.getLogger('django') #根據(jù)loggers配置handlers,將日志寫到指定的地方
error_logger = logging.getLogger('django.request') #根據(jù)loggers配置handlers,將日志寫到指定的地方
if __name__ == '__main__':
#簡單的使用例子,使用這個方法記錄日志,可以記錄詳細(xì)的日志信息(在視圖中使用)
error_logger.exception(f'{__file__}/Test_log,method=post,error,django.request')
二、utils/exception.py
1.1、重寫自己的drf全局異常模塊文章來源:http://www.zghlxwxcb.cn/news/detail-523498.html
from rest_framework.views import exception_handler
from rest_framework.response import Response
from rest_framework import status
from utils.log import error_logger #寫日志
#配置drf的全局異常處理,需要在settings中配置
def _exception_handler(exc,context):
#exc是報錯的異常對象,context是哪個模塊的函數(shù)出現(xiàn)報錯
response = exception_handler(exc,context)
# print(exc.detail.get('error'),exc.detail.get('code'))
# print(exc,'異常對象')
# print(context,'報錯函數(shù)')
# print(response,'返回對象')
#response有兩個結(jié)果:一個是None(系統(tǒng)處理),一個django處理后(但格式不符合要求)
if not response:
#當(dāng)然可以在這里進行精細(xì)的捕獲
#將錯誤信息寫到日志文件中,使用這個方法,可以把更多信息記錄起來(不要使用error方法,記錄的信息不詳細(xì))
error_logger.exception(exc)
return Response(data={'error':'系統(tǒng)內(nèi)部錯誤,請稍后再重試','code':500},
status=status.HTTP_500_INTERNAL_SERVER_ERROR)
else:
#djang處理的
if type(response.data) == dict:
detail = response.data.get('detail')
elif type(response.data) == list:
#特殊情況處理
detail = response.data
if len(detail) <=1:
return Response(data={'error':detail[0], 'code': 400},
status=response.status_code)
else:
return Response(data={'error': detail, 'code': 416},
status=response.status_code)
else:
detail = response.data
if detail:
if '未找到。' == detail:
detail = '查詢不到該數(shù)據(jù)信息'
if '無效頁面。' == detail:
detail = '該頁面的數(shù)據(jù)查詢不到,請確定要查詢的頁面數(shù)據(jù)是否存在'
return Response(data={'error':detail,'code':400},status=response.status_code)
else:
#我在寫認(rèn)證時,raise AuthenticationFailed({'code': 410, 'msg': msg,'type':'報錯'})
#拿到這里拋出異常的信息和code
return Response(data={'error':exc.detail.get('error'),'code':exc.detail.get('code')},status=response.status_code)
1.2、settings.py 在配置文件中使用全局異常處理文章來源地址http://www.zghlxwxcb.cn/news/detail-523498.html
#### drf的配置,全局配置
REST_FRAMEWORK = {
#2、配置全局異常處理
'EXCEPTION_HANDLER': 'utils.exception._exception_handler',
}
到了這里,關(guān)于DRF:配置全局異常處理和日志結(jié)合的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!