Django自定義中間件實現(xiàn)全鏈路操作日志記錄
一、中間件
介紹
在 Django 中,中間件(Middleware)是一組輕量級、底層的插件系統(tǒng),用于全局地改變 Django 的輸入和輸出。中間件可以在請求被處理之前和響應(yīng)返回之前執(zhí)行代碼,從而實現(xiàn)各種功能,例如跨域資源共享(CORS)、用戶認(rèn)證、日志記錄等。
激活中間件
若要激活中間件,需要添加到settings.MIDDLEWARE中
- 每個中間件組件由字符串表示:指向中間件工廠類的完整 Python 路徑。
- 需求注意中間件的添加順序。因為中間件有執(zhí)行順序,而且中間件之間可能有依賴關(guān)系。
- 中間件的全局執(zhí)行順序
- 請求階段:按
settings.MIDDLEWARE中從上到下的順序執(zhí)行。 - 視圖處理:請求到達(dá)視圖函數(shù)。
- 響應(yīng)階段:按
settings.MIDDLEWARE中從下到上的順序執(zhí)行。
- 請求階段:按
MIDDLEWARE = [
"corsheaders.middleware.CorsMiddleware", # CORS跨域支持
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.locale.LocaleMiddleware", # I18N多語言支持,注意放置順序
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
# "myapp_system.operate_log.services.OperateLogMiddleware", # 操作日志開關(guān):如果數(shù)據(jù)庫磁盤IO性能一般,建議關(guān)閉
]生命周期
中間件生命周期
- 請求階段:
process_request(request):在視圖函數(shù)被調(diào)用之前執(zhí)行,用于處理請求。如果返回HttpResponse對象,則后續(xù)的中間件和視圖不會被調(diào)用,直接返回響應(yīng)。 - 視圖階段:
process_view(request, view_func, view_args, view_kwargs):在視圖函數(shù)被調(diào)用之前執(zhí)行,可以用于根據(jù)視圖函數(shù)的參數(shù)或請求信息進(jìn)行額外處理。 - 響應(yīng)階段:
process_response(request, response):在視圖函數(shù)返回響應(yīng)后執(zhí)行,用于處理響應(yīng)對象,可以修改響應(yīng)內(nèi)容或響應(yīng)頭。 - 異常階段:
process_exception(request, exception):當(dāng)視圖函數(shù)拋出異常時執(zhí)行,用于處理異常并返回一個HttpResponse對象。
內(nèi)置中間件示例
django.contrib.auth.middleware.AuthenticationMiddleware:Django內(nèi)置的認(rèn)證中間件,實現(xiàn)將user屬性添加到每個傳入的HttpRequest對象中,表示當(dāng)前已登錄的用戶
class AuthenticationMiddleware(MiddlewareMixin):
def process_request(self, request):
if not hasattr(request, "session"):
raise ImproperlyConfigured(
"The Django authentication middleware requires session "
"middleware to be installed. Edit your MIDDLEWARE setting to "
"insert "
"'django.contrib.sessions.middleware.SessionMiddleware' before "
"'django.contrib.auth.middleware.AuthenticationMiddleware'."
)
request.user = SimpleLazyObject(lambda: get_user(request))二、自定義中間件
中間件鉤子函數(shù)
process_view()中間件鉤子函數(shù)
- 語法:
process_view(request, view_func, view_args, view_kwargs) - 調(diào)用順序:process_view() 只在 Django 調(diào)用視圖前被調(diào)用。
- 返回
- 如果它返回
None,Django 將繼續(xù)處理這個請求,執(zhí)行任何其他的process_view(),然后執(zhí)行相應(yīng)的視圖。 - 如果它返回
HttpResponse對象,Django 不會去影響調(diào)用相應(yīng)的視圖;它會將響應(yīng)中間件應(yīng)用到HttpResponse并返回結(jié)果。
- 如果它返回
基于類的中間件
基于類的自定義中間件格式
- 語句
response = self.get_response(request),將__call__()方法中的代碼分為兩部分
class SimpleMiddleware:
def __init__(self, get_response):
# 執(zhí)行一次性配置和初始化工作
self.get_response = get_response
def __call__(self, request):
# 每個請求調(diào)用一次,在視圖函數(shù)被調(diào)用之前執(zhí)行
response = self.get_response(request)
# 每個請求調(diào)用一次,在視圖函數(shù)被調(diào)用之后執(zhí)行
return response三、實戰(zhàn)案例
操作日志功能
通過自定義中間件,實現(xiàn)Django操作日志記錄功能
- 第1步:定義類
OperateLogMiddleware,方法__init__()中,添加exclude_urls排除不需要記錄的URL的列表,和一個字典log_data用于臨時存放日志信息。

- 第2步:在執(zhí)行視圖函數(shù)之前,向字典
log_data記錄請求方法、請求路徑、操作IP、瀏覽器Agent信息等

- 第3步:在執(zhí)行視圖函數(shù)之后,向字典
log_data記錄用戶ID、業(yè)務(wù)狀態(tài)碼、HTTP狀態(tài)碼、響應(yīng)數(shù)據(jù)、返回結(jié)果和執(zhí)行時間

- 第4步:
process_view()中間件鉤子函數(shù)中,向字典log_data記錄視圖名稱、Action名稱、資源ID

第5步:字典log_data記錄的操作日志信息,通過Celery異步任務(wù),寫入數(shù)據(jù)庫。實現(xiàn)操作日志記錄功能。
代碼運行效果:

參考資料
到此這篇關(guān)于Django自定義中間件實現(xiàn)全鏈路操作日志記錄的文章就介紹到這了,更多相關(guān)django自定義中間件全鏈路內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
用python實現(xiàn)簡單EXCEL數(shù)據(jù)統(tǒng)計的實例
下面小編就為大家?guī)硪黄胮ython實現(xiàn)簡單EXCEL數(shù)據(jù)統(tǒng)計的實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-01-01
Windows平臺Python連接sqlite3數(shù)據(jù)庫的方法分析
這篇文章主要介紹了Windows平臺Python連接sqlite3數(shù)據(jù)庫的方法,結(jié)合實例形式分析了Windows平臺安裝SQLite數(shù)據(jù)庫及創(chuàng)建、連接數(shù)據(jù)庫的實現(xiàn)方法與相關(guān)注意事項,需要的朋友可以參考下2017-07-07

