Skip to content

99.给用户添加操作日志

大家好~我是米洛
我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的教程,希望大家多多支持。
欢迎关注我的公众号米洛的测开日记,获取最新文章教程!

回顾

上一节我们完成了后置条件功能。这样整个用例的生命周期,除了跟yapi(或其他接口文档工具)关联以外,用例的逻辑基本上算是告一段落了。

这一篇我们打算将目光放在用户上,接着我们需要做的是以下几件事,也不是说全部做这些,只是还需要做的有这些。

  • 完成操作日志功能
  • 完成用户管理功能
  • 完成个人设置页面
  • 完成工作台功能

那这节我们就先完成操作日志相关的功能。

思考

操作日志这玩意,和传统意义的日志要分开。我们要说的操作日志是更可读的日志,比如:

2021-12-19 22:15:00 米洛 发表文章: 今天排位又坑了别人

我们需要的是何时何人做了何事,主要是3个要素。

  • 时间
  • 人物
  • 事件

对于详细的日志我们暂时不需要记录那么清楚(可能只需要到case的程度)。注意到,这里是暂时。

后续如果我们想知道case的具体改动,又或者说我们想订阅某个服务下的case,不论增删改,我们都想知道,那我们就得加上这些数据。

这功能说白了,就是个小型监视器。

至于思路的话,我们用个装饰器,在方法执行前把操作记录塞到db即可,暂时先不用太复杂。

设计表

我们把表分为以下几个字段, 新建app/models/operation_log.py

from datetime import datetime

from sqlalchemy import Column, INT, DATETIME, String, SMALLINT, TEXT

from app.models import Base


class PityOperationLog(Base):
    """
    用户操作记录表
    """
    __tablename__ = 'pity_operation_log'

    id = Column(INT, primary_key=True)
    # 操作人
    user_id = Column(INT, index=True)

    # 操作时间
    operate_time = Column(DATETIME)

    # 操作title
    title = Column(String(64), nullable=False)

    # 操作描述
    description = Column(TEXT, comment="操作描述")

    # tag
    tag = Column(String(24), comment="操作tag")

    # mode
    mode = Column(SMALLINT, comment="操作类型")

    # key
    key = Column(INT, nullable=True, comment="关键id,可能是目录id,case_id或者其他id")

    def __init__(self, user_id, mode, title, tag, description, key=None):
        self.user_id = user_id
        self.tag = tag
        self.mode = mode
        self.title = title
        self.key = key
        self.description = description
        self.operate_time = datetime.now()
  • user_id: 操作人
  • operate_time: 操作时间
  • title: 操作标题
  • description: 改动细节
  • tag: 操作标签
  • mode: 操作模式
  • key: 操作关键id

这个key属于预留字段,是为了给case操作记录做的预留。如果某某某改动了某个case的前置条件,其实我们操作记录是只有前置条件的改动。所以遇到这种情况,我们就需要设置key为用例id,这样当我想查询用例改动的时候,就可以查到这条记录了。

当然,这暂时只是我的一个设想。

改造PityBase

还记得之前我们设计的pity基类吗?里面包含了create_at等基本字段,在今天,我们还得额外给它加一些东西:

这边添加了4个字段,但注意这些都不是数据表的真实字段,只是我们用来获取操作日志需要的4个字段

  • fields

默认展示的字段,举个例子,一个用户有姓名年龄等字段,我们要展示哪些字段的改动呢?

明显id,创建时间这些我们是不需要的。

所以这个字段就用来规定我们对变更的展示.

  • tag

之前说了,表对应的tag,举个例子,在pity里面可以是测试用例测试计划等。以后如果我们想看所有测试计划的改动,就可以根据tag来筛选。

  • alias

我们的操作记录,试想一下,如果用这样的方式:

[数据库配置] 乌迪尔 编辑了 数据库: 本地数据库

name: ~~老的redis~~ -> 新的redis

database: ~~user~~ -> pity_user

看上去是没啥毛病,但是对用户来说不友好啊!如果我们能把数据库的name换成名称,database换成数据库名会不会更好些?

这就是别名的目的。

  • __show__

这个变量是用来展示 乌迪尔 修改了 xxxx,因为有时候我们可能修改了XXX项目XXX项目角色:

乌迪尔添加了项目 abc -> 用户 李大嘴 -> 角色 管理员

这里展示字段需要3个,分别是项目,用户和角色。这里根据__fields__联动,取前面N个字段。

新增PityRelationField类

因为我们的字段名可能是xxx_id,需要关联到别的字段,要不就是枚举类,比如type是0代表用例,1代表sql,所以我们要建立0->1以及xxx_id到表字段的映射关系。

这么说可能很抽象,我们举个具体的例子:

Redis表有个env字段,他来自Environment表的id,所以我们需要把env换成Environment的name字段(比如fat),这样我们就能很好地识别出变动的数据。

init_relation则是建立此等关系,待会我们会说明。

修改配置文件config.py

设置这些变量是为了能够很好地获取对应的值,不然我把__fields__写为__field__就出大问题了。

修改crud/__init__.py

上面是动态导入包(建数据表用的),下面则是设置映射关系

以Redis为例,可以看到Redis.env映射到了Environment.id,第二个字段则是替换成Environment.name。

其他细节

具体的细节很多,很难一步一步写清楚,大家可以查看crud/__init__.py里的insert_log方法。

整体思路就是根据预设的字段,存放对应的字段改动,字段有别名则替换字段的别名,比如name->姓名,有其他表的数据则替换为其他表的数据。

具体效果

本节内容比较多,感兴趣的朋友可以催更或者自己查看代码。感觉用文字的方式很难讲清楚。

参考链接: 美团分享的文章https://juejin.cn/post/7009116644031070244

对应git commit改动:

https://github.com/wuranxu/pity/commit/bf374ac4851ec24e1386b351549c15ebe26772df

其他实现

如果简单记录的话,不用这么复杂,写出xxx修改了xxx即可。那个可以用装饰器完成。有兴趣的朋友可以自己实现。


本文由于篇幅问题,就讲到这里了,我去补注释去了~下一节我们把今天写的字段数据展示在个人动态页面中。