Django记录操作日志

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

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

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

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

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

from django.utils.deprecation import MiddlewareMixin

class OpLogs(MiddlewareMixin):

def process_request(self, request):
    pass

1
2
3
4
5
6
在settings中注册中间件:

自定义中间件

MIDDLEWARE += [
‘app01.middlewares.LogMiddleware.OpLogs’
]
1
2
3
4
功能实现
LogModdleware.py中间件:
获取需要记录的参数,并计算请求耗时,将参数入库。

-- coding:utf-8 --

“”"
@File : LogMiddleware.py
@Author : Python
@Date : 2021/7/20 14:00
“”"
import time
import json

from django.utils.deprecation import MiddlewareMixin

from app.models import OpLogs, AccessTimeOutLogs

class 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())  # 请求时间(北京)

    # 请求IP
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        # 如果有代理,获取真实IP
        re_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.POST
    if re_content:
        # 筛选空参数
        re_content = json.dumps(re_content)
    else:
        re_content = None
        
    self.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_time
    self.data['access_time'] = round(access_time * 1000)  # 耗时毫秒/ms

    # 耗时大于3s的请求,单独记录 (可将时间阈值设置在settings中,实现可配置化)
    if self.data.get('access_time') > 3 * 1000:
        AccessTimeOutLogs.objects.create(**self.data)   # 超时操作日志入库db

    OpLogs.objects.create(**self.data)  # 操作日志入库db

    return response

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
app01.models 数据库模型:

from django.db import models

class 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'
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在 Django 中实时显示 adb logcat 日志,可以通过以下步骤进行操作: 1. 在 Django 项目的 settings.py 文件中添加以下代码,以启用子进程功能: ```python import subprocess from threading import Thread from time import sleep def run_logcat(): cmd = ['adb', 'logcat'] p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) for line in iter(p.stdout.readline, b''): yield line.decode() def logcat_generator(): for line in run_logcat(): yield line class LogcatThread(Thread): daemon = True def run(self): with open('logcat.log', 'w') as f: for line in logcat_generator(): f.write(line) ``` 2. 在 URLconf 中添加以下代码,以启动线程并按需访问生成的日志文件: ```python from django.urls import path from django.http import StreamingHttpResponse from . import views urlpatterns = [ path('', views.index), path('logcat/', views.logcat), ] def logcat_response(): def generate(): with open('logcat.log') as f: for line in f: yield line.encode() return StreamingHttpResponse(generate()) LogcatThread().start() ``` 3. 在 views.py 文件中添加以下视图处理程序: ```python from django.shortcuts import render def index(request): return render(request, 'index.html') def logcat(request): return logcat_response() ``` 4. 创建一个名为 index.html 的模板,其中包含一个触发器来请求日志: ```html {% extends 'base.html' %} {% block content %} <h1>ADB Logcat Viewer</h1> <p>You can view the logcat messages by clicking the following button:</p> <button onclick="reloadLogcat()">Refresh Logcat</button> <pre id="logcat"></pre> {% endblock %} {% block javascript %} <script type="text/javascript"> function reloadLogcat() { var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (this.readyState == 4 && this.status == 200) { document.getElementById("logcat").innerText = this.responseText; } }; xhr.open("GET", "/logcat/"); xhr.send(); } </script> {% endblock %} ``` 现在, 每次您访问网站并单击“刷新 Logcat”按钮时,您将获得最新的 adb logcat 日志

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值