Django自定義中間件實現(xiàn)全鏈路操作日志記錄
一、中間件
介紹
在 Django 中,中間件(Middleware)是一組輕量級、底層的插件系統(tǒng),用于全局地改變 Django 的輸入和輸出。中間件可以在請求被處理之前和響應返回之前執(zhí)行代碼,從而實現(xiàn)各種功能,例如跨域資源共享(CORS)、用戶認證、日志記錄等。
激活中間件
若要激活中間件,需要添加到settings.MIDDLEWARE
中
- 每個中間件組件由字符串表示:指向中間件工廠類的完整 Python 路徑。
- 需求注意中間件的添加順序。因為中間件有執(zhí)行順序,而且中間件之間可能有依賴關系。
- 中間件的全局執(zhí)行順序
- 請求階段:按
settings.MIDDLEWARE
中從上到下的順序執(zhí)行。 - 視圖處理:請求到達視圖函數(shù)。
- 響應階段:按
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", # 操作日志開關:如果數(shù)據(jù)庫磁盤IO性能一般,建議關閉 ]
生命周期
中間件生命周期
- 請求階段:
process_request(request)
:在視圖函數(shù)被調(diào)用之前執(zhí)行,用于處理請求。如果返回HttpResponse
對象,則后續(xù)的中間件和視圖不會被調(diào)用,直接返回響應。 - 視圖階段:
process_view(request, view_func, view_args, view_kwargs)
:在視圖函數(shù)被調(diào)用之前執(zhí)行,可以用于根據(jù)視圖函數(shù)的參數(shù)或請求信息進行額外處理。 - 響應階段:
process_response(request, response)
:在視圖函數(shù)返回響應后執(zhí)行,用于處理響應對象,可以修改響應內(nèi)容或響應頭。 - 異常階段:
process_exception(request, exception)
:當視圖函數(shù)拋出異常時執(zhí)行,用于處理異常并返回一個HttpResponse
對象。
內(nèi)置中間件示例
django.contrib.auth.middleware.AuthenticationMiddleware
:Django內(nèi)置的認證中間件,實現(xiàn)將user
屬性添加到每個傳入的HttpRequest
對象中,表示當前已登錄的用戶
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í)行相應的視圖。 - 如果它返回
HttpResponse
對象,Django 不會去影響調(diào)用相應的視圖;它會將響應中間件應用到HttpResponse
并返回結果。
- 如果它返回
基于類的中間件
基于類的自定義中間件格式
- 語句
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è)務狀態(tài)碼、HTTP狀態(tài)碼、響應數(shù)據(jù)、返回結果和執(zhí)行時間
- 第4步:
process_view()
中間件鉤子函數(shù)中,向字典log_data
記錄視圖名稱、Action名稱、資源ID
第5步:字典log_data
記錄的操作日志信息,通過Celery異步任務,寫入數(shù)據(jù)庫。實現(xiàn)操作日志記錄功能。
代碼運行效果:
參考資料
到此這篇關于Django自定義中間件實現(xiàn)全鏈路操作日志記錄的文章就介紹到這了,更多相關django自定義中間件全鏈路內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
利用Python的Flask框架來構建一個簡單的數(shù)字商品支付解決方案
這篇文章主要介紹了利用Python的Flask框架來構建一個簡單的數(shù)字商品支付解決方案,文中用極簡的代碼展示了一個flask框架下的支付模版,需要的朋友可以參考下2015-03-03PyTorch之torch.randn()如何創(chuàng)建正態(tài)分布隨機數(shù)
這篇文章主要介紹了PyTorch之torch.randn()如何創(chuàng)建正態(tài)分布隨機數(shù)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-02-02python?裝飾器(Decorators)原理說明及操作代碼
裝飾器(Decorators)是 Python 的一個重要部分,本文由淺入深給大家介紹了python?裝飾器Decorators原理,感興趣的朋友跟隨小編一起看看吧2021-12-12