JSON 解码只能确认格式,不代表字段齐全;把第三方日志转换成本文中间格式时,应另外核对键名、单位和类型。本文从Node构建JSON清单的受控中间格式读取记录,统一使用毫秒和退出码。展示耗时走势时,可以让每个结果代表连续三次执行的平均。
先固定可回放的数据
前端构建包装器可在一次运行结束后,把各阶段结果整理为受控中间格式,交给离线看板回放。这里采用对象数组保存完整快照,故意留下两次同名测试,使失败尝试不会被后来的成功覆盖。验收先确认数组成员仍是独立事件,再检查耗时与退出状态没有被显示层改写。
importjson raw='[{"step":"build","ms":120,"code":0},{"step":"test","ms":40,"code":1},{"step":"test","ms":60,"code":0},{"step":"pack","ms":80,"code":2}]'恢复结构并统一字段
清单顶层是记录数组,每条记录包含步骤名、毫秒数和退出码。读取结构化 JSON 可以保留数值类型,不需要从彩色终端输出里猜测字段。
rows=json.loads(raw)ifany(r["ms"]<0forrinrows):raiseValueError()计算本篇的指标
每个完整窗口取连续三条记录的平均,结果对齐第三条及之后的位置。不足三条的输入输出空数组,避免用补零制造下降趋势。
times=[r["ms"]forrinrows]result=[sum(times[i-2:i+1])/3foriinrange(2,len(times))]对照独立期望值
期望数组检查窗口数量与两个具体平均值。验收中容易漏掉的错误是少算最后一个窗口,或切片包含了第四个元素;若改为流式实现,应与这个小样本版本逐项比较对齐位置。
want=[73.33333333333333,60.0]ifresult!=want:raiseValueError(result)print(result)四条有序样本恰好产生两个完整窗口,便于分别手算首个与末个结果。
这里不筛掉失败事件,因为筛选会改变相邻关系;不够三条时也不补零,避免让图表看起来出现不存在的下降。
移动平均可以平滑展示,却会引入窗口语义。
分析脚本本身只读数据,不能为了得到更好看的数字去改写失败状态或隐藏异常记录。