测试基础 Django 实时日志存储和接口日志返回

花菜 · 2023年09月19日 · 最后由 花菜 回复于 2023年09月20日 · 4003 次阅读

1、用户故事

在使用数据工厂时,只能看到配置的好的数据卡片;

但并不知道背后执行的逻辑是怎么样的,有时候执行的结果不符合预期时,

希望可以把当前数据卡片执行的日志返回,方便直接在前端就能排查问题。
image.png

2、设计和实现

2.1 日志持久化

2.1.1 定义保存 log 的模型

在某个 app 的 models 下面增加

# models.py
from django.db import models

class LogRecord(models.Model):
    class Meta:
        db_table = "t_log_record"
    request_id = models.CharField(max_length=100, null=True, db_index=True)
    level = models.CharField(max_length=20)
    message = models.TextField(db_index=True)    

2.2.2 自定义日志处理器

settings.py所在的目录,新建一个模块,比如log.py

# log.py

import logging
from xxx.models import LogRecord  # 引入上面定义的LogRecord模型

class DatabaseLogHandler(logging.Handler):
    def emit(self, record: logging.LogRecord) -> None:
        LogRecord.objects.create(
            request_id=record.request_id,
            level=record.levelname,
            message=self.format(record),
        )

2.2.3 配置 Django 的 logging 设置

注意,只是说明如何使用日志自定义 handle,不是完整的日志配置。

也缺少了上面的request_id字段,这个需要在 formatters 中配置。

使用request_id做链路追踪,参考:

https://blog.huacai.one/post/39

完整日志配置参考: https://github.com/lihuacai168/AnotherFasterRunner/pull/111/commits/2659df19192c41819813514aac5896d7550c1e5c

# settings.py
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'db': {
            'level': 'DEBUG',
            'class': 'your_app_name.handlers.DatabaseLogHandler',  # 指向你的自定义处理器
        },
    },
    'loggers': {
        'django': {
            'handlers': ['db'],
            'level': 'DEBUG',
            'propagate': True,
        },
    },
}


2.2 接口增加统一返回日志

image.png
通过中间件返回,具体参考链接

https://github.com/lihuacai168/django-ninja-demo/blob/92b4f4250e9bb9d42628355698a3e7912cffb04d/core/middleware.py#L27C19-L27C19

3、总结

  • 日志存储需要依赖统一 id,否则无法追踪
  • 目前写入日志是同步的,如果写入日志较大,db 会存在性能问题;可改用异步写入到 es
  • 如果日志直接返回前端,存在安全性问题,敏感信息不要打到日志
  • 可增加日志查询接口,实现直接在前端查看日志

image.png

公众号原文

共收到 5 条回复 时间 点赞

如果觉得文章对你有帮助,点赞收藏走一波。
你有更好的想法,欢迎留言一起讨论

第一种:

  1. 写一个日志的装饰器针对每个造数工具都给他加一个
  2. 数据库表里加一个 case_log 类似的字段存储每个工具的日志
  3. 前端用的 element 的话可以用现成的组件 Drawer 抽屉,把日志和一些请求信息赛里面,具体样式自己慢慢撸

第二种:
1.搭建调用链追踪 jaeger,觉得跑出的结果有问题自己看调用链去

最后说说造数平台,拿电商项目举例,写工具平台的不可能熟悉每个组的业务,不熟悉业务怎么写工具,还不如交易组一套服务,商品组一套服务,营销组一套服务,写几个 grpc 服务拉倒,最后用常用的 web 框架入 django fastapi 调用这些业务组的服务封装成 https 暴露出去。😂 这样大家参与感多点,只要把服务端的框架整出来,让他们往里面填轮子就行。😂 😂 😂

disable 回复

目前的实现其实包含了这两种。有规定写死的流程,也有支持配置的。
每个卡片的执行结果和 log 一起返回,跟你说的一样在 Drawer 上展示。
我们木有纯工具测试开发,都是业务测开,所以大家对自己负责的业务都是比较熟悉

花菜 回复

现实情况是各个组只是对自己模块熟悉,其他组的可能是指知道怎么玩相对熟悉而已。😂 目前我们这也是各个组出个人在自动化框架的基础上,简单的一个 flask 框架写了一推业务接口,很 low 就一个 app.py。然后呢,平台这边就是调用这些接口加上页面的编写(某种意义上来说俺就是个写页面的)😂 所以还不如整几个 grpc 服务,还能工程化一点。最后吐槽一句,除了页面还好看点,真难用。为了领导自己的 kpi,搞什么账号封禁,强推你只能上平台自己造数造数。本末倒置,其他部门的测试私底下也都有自己的脚本(本地跑跑也能满足自己的小需求),😂 也看出来对这东西的认可度了。。。😂 😂 😂有多少兄弟也是做的这些伪自动化,伪平台?现在行情不好,真后悔 21 年选择。。。浪费我时间

嗯嗯,大多数人都还是停留在吐槽的阶段。
工程化有一定的挑战难度,但可以尝试逐步去改善,好用的工具都是慢慢迭代出来的。
横空出世的,大概率都是 kpi 产物

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册