Django实战:自定义中间件实现全链路操作日志记录
一、中间件
介绍
在 Django 中,中间件(Middleware)是一组轻量级、底层的插件系统,用于全局地改变 Django 的输入和输出。中间件可以在请求被处理之前和响应返回之前执行代码,从而实现各种功能,例如跨域资源共享(CORS)、用户认证、日志记录等。
激活中间件
若要激活中间件,需要添加到settings.MIDDLEWARE中
- 每个中间件组件由字符串表示:指向中间件工厂类的完整 Python 路径。
- 需求注意中间件的添加顺序。因为中间件有执行顺序,而且中间件之间可能有依赖关系。
- 中间件的全局执行顺序
- 请求阶段:按
settings.MIDDLEWARE中从上到下的顺序执行。 - 视图处理:请求到达视图函数。
- 响应阶段:按
settings.MIDDLEWARE中从下到上的顺序执行。
- 请求阶段:按
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", # 操作日志开关:如果数据库磁盘IO性能一般,建议关闭
]
生命周期
中间件生命周期
- 请求阶段:
process_request(request):在视图函数被调用之前执行,用于处理请求。如果返回HttpResponse对象,则后续的中间件和视图不会被调用,直接返回响应。 - 视图阶段:
process_view(request, view_func, view_args, view_kwargs):在视图函数被调用之前执行,可以用于根据视图函数的参数或请求信息进行额外处理。 - 响应阶段:
process_response(request, response):在视图函数返回响应后执行,用于处理响应对象,可以修改响应内容或响应头。 - 异常阶段:
process_exception(request, exception):当视图函数抛出异常时执行,用于处理异常并返回一个HttpResponse对象。
内置中间件示例
django.contrib.auth.middleware.AuthenticationMiddleware:Django内置的认证中间件,实现将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))
二、自定义中间件
中间件钩子函数
process_view()中间件钩子函数
- 语法:
process_view(request, view_func, view_args, view_kwargs) - 调用顺序:process_view() 只在 Django 调用视图前被调用。
- 返回
- 如果它返回
None,Django 将继续处理这个请求,执行任何其他的process_view(),然后执行相应的视图。 - 如果它返回
HttpResponse对象,Django 不会去影响调用相应的视图;它会将响应中间件应用到HttpResponse并返回结果。
- 如果它返回
基于类的中间件
基于类的自定义中间件格式
- 语句
response = self.get_response(request),将__call__()方法中的代码分为两部分
class SimpleMiddleware:
def __init__(self, get_response):
# 执行一次性配置和初始化工作
self.get_response = get_response
def __call__(self, request):
# 每个请求调用一次,在视图函数被调用之前执行
response = self.get_response(request)
# 每个请求调用一次,在视图函数被调用之后执行
return response
三、实战案例
操作日志功能
通过自定义中间件,实现Django操作日志记录功能
- 第1步:定义类
OperateLogMiddleware,方法__init__()中,添加exclude_urls排除不需要记录的URL的列表,和一个字典log_data用于临时存放日志信息。

- 第2步:在执行视图函数之前,向字典
log_data记录请求方法、请求路径、操作IP、浏览器Agent信息等

- 第3步:在执行视图函数之后,向字典
log_data记录用户ID、业务状态码、HTTP状态码、响应数据、返回结果和执行时间

- 第4步:
process_view()中间件钩子函数中,向字典log_data记录视图名称、Action名称、资源ID

第5步:字典log_data记录的操作日志信息,通过Celery异步任务,写入数据库。实现操作日志记录功能。
参考:完整代码地址
参考资料
您正在阅读的是《Django从入门到实战》专栏!关注不迷路~
Django实战:自定义中间件实现全链路操作日志记录的更多相关文章
- 微软企业库5.0 学习之路——第九步、使用PolicyInjection模块进行AOP—PART4——建立自定义Call Handler实现用户操作日志记录
在前面的Part3中, 我介绍Policy Injection模块中内置的Call Handler的使用方法,今天则继续介绍Call Handler——Custom Call Handler,通过建立 ...
- 基于SqlSugar的开发框架循序渐进介绍(8)-- 在基类函数封装实现用户操作日志记录
在我们对数据进行重要修改调整的时候,往往需要跟踪记录好用户操作日志.一般来说,如对重要表记录的插入.修改.删除都需要记录下来,由于用户操作日志会带来一定的额外消耗,因此我们通过配置的方式来决定记录那些 ...
- Winform开发框架之权限管理系统改进的经验总结(4)-一行代码实现表操作日志记录
在前面介绍了几篇关于我的权限系统改进的一些经验总结,本篇继续这一系列主体,介绍如何一行代码实现重要表的操作日志记录.我们知道,在很多业务系统里面,数据是很敏感的,特别对于一些增加.修改.删除等关键的操 ...
- JS实战 · 复选框全选操作
思路: 1.获取被选中checkbox,通过checked属性的状态完成: 2.获取被选中的checkbox的value值: 3.求所有value的和sum: 4.定义span区域存储和sum: ...
- Dubbo 全链路追踪日志的实现
微服务架构的项目,一次请求可能会调用多个微服务,这样就会产生多个微服务的请求日志,当我们想要查看整个请求链路的日志时,就会变得困难,所幸的是我们有一些集中日志收集工具,比如很热门的ELK,我们需要把这 ...
- [编码实践]SpringBoot实战:利用Spring AOP实现操作日志审计管理
设计原则和思路: 元注解方式结合AOP,灵活记录操作日志 能够记录详细错误日志为运营以及审计提供支持 日志记录尽可能减少性能影响 操作描述参数支持动态获取,其他参数自动记录. 1.定义日志记录元注解, ...
- springmvc+log4j操作日志记录,详细配置
没有接触过的,先了解一下:log4j教程 部分内容来:log4j教程 感谢! 需要导入包: log包:log4j-12.17.jar 第一步:web.xml配置 <!-- log4j配置,文件路 ...
- Spring Boot分布式系统实践【基础模块构建3.3】注解轻松实现操作日志记录
日志注解 前言 spring切面的编程,spring中事物处理.日志记录常常与pointcut相结合 * * Pointcut 是指那些方法需要被执行"AOP",是由"P ...
- springAOP实现操作日志记录,并记录请求参数与编辑前后字段的具体改变
本文为博主原创,未经允许不得转载: 在项目开发已经完成多半的情况下,需要开发进行操作日志功能的开发,由于操作的重要性,需要记录下操作前的参数和请求时的参数, 在网上找了很多,没找到可行的方法.由于操作 ...
- .Net Core中间件和过滤器实现错误日志记录
1.中间件的概念 ASP.NET Core的处理流程是一个管道,中间件是组装到应用程序管道中用来处理请求和响应的组件. 每个中间件可以: 选择是否将请求传递给管道中的下一个组件. 可以在调用管道中的下 ...
随机推荐
- ORA-28001:口令已经失效
Oracle用户口令默认的有效期导致的一个异常,留爪. Oralce11G下,创建的用户及口令,也就是用户密码默认会有个180天的过期时间, 如果超过180天用户口令未做修改,则该用户口令失效,也就是 ...
- SynchronousQueue底层实现原理剖
一.SynchronousQueue底层实现原理剖 SynchronousQueue(同步移交队列),队列长度为0.作用就是一个线程往队列放数据的时候,必须等待另一个线程从队列中取走数据.同样,从队列 ...
- 🎀idea import配置
简介 本文记录idea中import相关配置:自动导入依赖.自动删除无用依赖.避免自动导入*包 自动导入依赖 在编辑代码时,当只有一个具有匹配名称的可导入声明时,会自动添加导入 File -> ...
- 为什么 MySQL 选择使用 B+ 树作为索引结构?
为什么 MySQL 选择使用 B+ 树作为索引结构? MySQL 选择 B+ 树作为其索引结构的主要原因是它具有以下几个优势,这些优势使得 B+ 树非常适合用于数据库系统中的索引实现. 1. 高效的范 ...
- Win10远程桌面连接功能
Win10远程桌面连接功能 Win10系统自带的远程桌面连接需要满足以下三个条件 开启远程桌面连接 设置一个连接密码 知道自己的IP地址 下面教你如开开启远程设置 第一步:在桌面我的电脑图片上单机属性 ...
- 备份一个迭代查找TreeViewItem的辅助函数
private TreeViewItem FindTreeItem(TreeViewItem item, Func<TreeViewItem, bool> compare) { if (i ...
- 题解:AT_arc173_a [ARC173A] Neq Number
简单二分. 思路 数位 dp 预处理和判断. init 预处理出 dp 数组,与 windy 数大致相同. 二分答案,如果 111 至 midmidmid 的 Neq 数数量大于等于 kkk,rt=m ...
- Result、ConfigAwait、ValueTask
Result.ConfigAwait.ValueTask 参照: C# Async/Await: ConfigAwait, ValueTask是个啥?对提高性能有用么?_哔哩哔哩_bilibili 理 ...
- Windows系统常用端口详解
7,9,13,17,19 这是几个简单的TCP/IP服务,在windows中被Simple TCP/IP Services管理. 7 : Echo 服务:将接收到的数据原样返回. 9 : Discar ...
- FunProxy - 使用 Rust 构建跨平台全链路测试抓包代理工具
作者:vivo 互联网大前端团队- Song Jiachao 在软件开发过程中,软件测试对于保障软件质量和用户满意度起着关键作用.为最大程度上提升软件品质,我们积极开展全链路测试实践,打造了用Rust ...