700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Django中间件实现操作日志记录

Django中间件实现操作日志记录

时间:2023-10-25 07:00:25

相关推荐

Django中间件实现操作日志记录

Django中间件实现操作日志

本文通过Django中间件的流程,实现操作日志记录的功能,模块化、拿来即用。

功能描述:通过中间件记录请求时间操作用户请求URL请求方法请求IP请求参数响应数据响应耗时等数据日志,而且可以自定义exclude_urls列表,访问列表中的url,不会保存操作日志。另外,通过设置的响应时间阈值(可配置化),将超过阈值的操作日志进行单独保存,便于分析。

说明:示例中是将数据记录在MySQL数据库中,如果你想写入log日志,只需将数据入库改为log格式写入即可(数据都放在self.data中,取用方便)。

创建中间件

在app下新建文件夹middlewares, 在文件夹下新建中间件文件LogMiddleware.py

在中间件文件中新建一个类, 继承MiddlewareMixin:

from django.utils.deprecation import MiddlewareMixinclass OpLogs(MiddlewareMixin):def process_request(self, request):pass

在settings中注册中间件:

# 自定义中间件MIDDLEWARE += ['app01.middlewares.LogMiddleware.OpLogs']

功能实现

LogModdleware.py中间件:

获取需要记录的参数,并计算请求耗时,将参数入库。

# -*- coding:utf-8 -*-"""@File : LogMiddleware.py@Author : Python@Date : /7/20 14:00"""import timeimport jsonfrom django.utils.deprecation import MiddlewareMixinfrom app.models import OpLogs, AccessTimeOutLogsclass OpLogs(MiddlewareMixin):__exclude_urls = ['index/'] # 定义不需要记录日志的url名单def __init__(self, *args):super(OpLog, self).__init__(*args)self.start_time = None# 开始时间self.end_time = None# 响应时间self.data = {}# dict数据def process_request(self, request):"""请求进入:param request: 请求对象:return:"""self.start_time = time.time() # 开始时间re_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) # 请求时间(北京)# 请求IPx_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')if x_forwarded_for:# 如果有代理,获取真实IPre_ip = x_forwarded_for.split(",")[0]else:re_ip = request.META.get('REMOTE_ADDR')# 请求方法re_method = request.method# 请求参数re_content = request.GET if re_method == 'GET' else request.POSTif re_content:# 筛选空参数re_content = json.dumps(re_content)else:re_content = Noneself.data.update({'re_time': re_time,# 请求时间're_url': request.path,# 请求url're_method': re_method,# 请求方法're_ip': re_ip,# 请求IP're_content': re_content, # 请求参数# 're_user': request.user.username # 操作人(需修改),网站登录用户're_user': 'AnonymousUser' # 匿名操作用户测试})def process_response(self, request, response):"""响应返回:param request: 请求对象:param response: 响应对象:return: response"""# 请求url在 exclude_urls中,直接return,不保存操作日志记录for url in self.__exclude_urls:if url in self.data.get('re_url'):return response# 获取响应数据字符串(多用于API, 返回JSON字符串)rp_content = response.content.decode()self.data['rp_content'] = rp_content# 耗时self.end_time = time.time() # 响应时间access_time = self.end_time - self.start_timeself.data['access_time'] = round(access_time * 1000) # 耗时毫秒/ms# 耗时大于3s的请求,单独记录 (可将时间阈值设置在settings中,实现可配置化)if self.data.get('access_time') > 3 * 1000:AccessTimeOutLogs.objects.create(**self.data) # 超时操作日志入库dbOpLogs.objects.create(**self.data) # 操作日志入库dbreturn response

app01.models 数据库模型:

from django.db import modelsclass OpLogs(models.Model):"""操作日志表"""id = models.AutoField(primary_key=True)re_time = models.CharField(max_length=32, verbose_name='请求时间')re_user = models.CharField(max_length=32, verbose_name='操作人')re_ip = models.CharField(max_length=32, verbose_name='请求IP')re_url = models.CharField(max_length=255, verbose_name='请求url')re_method = models.CharField(max_length=11, verbose_name='请求方法')re_content = models.TextField(null=True, verbose_name='请求参数')rp_content = models.TextField(null=True, verbose_name='响应参数')access_time = models.IntegerField(verbose_name='响应耗时/ms')class Meta:db_table = 'op_logs'class AccessTimeOutLogs(models.Model):"""超时操作日志表"""id = models.AutoField(primary_key=True)re_time = models.CharField(max_length=32, verbose_name='请求时间')re_user = models.CharField(max_length=32, verbose_name='操作人')re_ip = models.CharField(max_length=32, verbose_name='请求IP')re_url = models.CharField(max_length=255, verbose_name='请求url')re_method = models.CharField(max_length=11, verbose_name='请求方法')re_content = models.TextField(null=True, verbose_name='请求参数')rp_content = models.TextField(null=True, verbose_name='响应参数')access_time = models.IntegerField(verbose_name='响应耗时/ms')class Meta:db_table = 'access_timeout_logs'

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。