Skip to content

Session 资产管理、标注与测试报告导出:构建可复现的质量凭据 ​

在正规的研发测试流程中,性能测试最忌讳的是"口说无凭"或"单次截图"。Perfowl 把单次测试执行组织为一个本地 Session 资产目录,采用 append-only 写入 + SHA-256 摘要校验,支持测试过程中的即时打点标注(Note),并支持导出 JSONL 与 CSV 数据。

术语澄清

当前实现是 append-only(只追加)+ 哈希校验:篡改会在下次读取/回放时因哈希不匹配而被检测到(fail-closed 拒绝),但这不是密码学签名意义上的"不可篡改"——没有对文件做数字签名,理论上仍可能被同时篡改内容和重新计算哈希。准确表述见 Session 完整性与回放确定性。


1. Session 资产包结构解析 ​

每次点击「开始测试」并「停止」后,Perfowl 会在本地生成一个自包含的独立 Session 目录。以下是当前实现的真实文件结构(以代码为准,不是历史示意):

text
<产品 Session 目录>/
├── session-plan.json           # 用户实际目标与选项(仅私有本地)
├── manifest.json               # 产品状态、sampleCount、耐久封存摘要,不是Raw清单
├── metrics.csv                 # 产品样本宽表(数值及质量/作用域/单位)
├── events/events-000001.jsonl   # 规范化产品事件
├── raw/collector-000001.jsonl   # Sidecar产品wire,不是Core来源原始流
├── core-seal.json              # Core封存摘要与消费序号
├── product-seal.json           # 产品耐久状态
├── collector-core/
│   ├── manifest.json           # Core Raw清单与rawSHA256
│   ├── raw-events.jsonl        # 系统来源原始流
│   ├── metrics-derived.jsonl   # 原始来源派生值(quality/scope/unit)
│   ├── report-final.json       # 最终统计与覆盖(含会话帧统计)
│   ├── report-seal.json        # 报告/相关文件与消费边界
│   └── frame-events-live.jsonl # 独立逐帧来源记录
└── screenshots/                # 仅启用截图持久化时的附件;预览本身不等于已保存

上述为2026-10-04当前产品外层与Core内层的区分;CoreProfile分块仅相应采集/存储条件下存在,不是每个Session必有。Raw连续序号、哈希、Core报告与产品耐久边界须分别复核。SQLite在writer-seal.v1中的登记摘要是逻辑检查点,不得直接与其页文件的字节SHA相比较;这不改成密码学防篡改承诺。


2. 测试过程中的实时打点标注 (Note) ​

在复杂的性能压测中,测试人员通常需要执行多个连续动作(如:“00:15 进入直播间”、“00:45 连续刷礼物”、“01:30 退出房间”)。

Perfowl 提供了即时标注功能:

  • 实时快捷打点:测试进行中,在工作台输入标注说明并回车,系统会立即在当前时间点插入一条 eventType=note 的事件。
  • 时间轴自动绑定:标注文字与同窗的采样时间戳严格锚定。在后续回放或查看报表时,标注点将以醒目旗帜直接呈现在指标曲线上,研发可直接跳跃到对应业务操作瞬间进行归因。
  • 按追加顺序记录:标注按真实发生时序 append-only 写入同一个事件流,不提供"编辑历史标注文字"的入口;这是 append-only 设计的自然结果,不是密码学意义上防止篡改(参见本页顶部术语澄清)。

3. 多格式导出规程与跨平台消费 ​

由 SessionExporter(MacApp/Sources/PerfowlCore/SessionExporter.swift)从同一份 review.timeline 生成,保证 CSV 与 JSONL 不会出现不同的时钟锚点或窗口坐标。

3.1 结构化 CSV 导出 (适用于数据分析与报表交付) ​

  • 宽表格式,不是长表:每个时间点(playback point)独立成一行,列是固定的字段集合(ordinal、elapsed_seconds、point_quality、event_type、source_id 以及各指标的具体字段,如 cpu_percent、frame_time_ms、physical_footprint_bytes、network_send_bytes_per_second 等数十个预定义列),不是"每行一个 metric_name + value 键值对"的长表结构。
  • 首行携带元数据:第一行输出 record_type=export_meta 等 Session 级元数据(时钟来源、锚点、时间轴质量、算法版本),从第二行起才是逐点事件数据。
  • 格式规范:数值采用 ASCII 浮点数(%.6f),缺失值显式留空(不补 0 破坏平均值),字段按 RFC 4180 风格转义逗号/引号/换行。

3.2 标准 JSONL 导出 (适用于 CI/CD 质量看板入库) ​

  • 逐行事件流:首行输出 SessionExportMetadata(recordType=export_meta,含 exportVersion、timelineAlgorithmVersion、clockSource、timelineQuality 等字段),后续每行对应一条 NormalizedPerformanceEvent(recordType=event)。
  • 截图字段:截图仅记录相对文件路径(relativePath)、采集质量(quality)与错误原因(error),当前不包含逐张截图的哈希/校验码字段;不把图像二进制塞进文本导出,保持数据流轻量。

4. 相关指南深入阅读 ​

4. 非启动全字段导出修订 · 2026-10-04 ​

当前review导出session-export.v3保留v2原61列顺序,在末尾追加13个能量/电池/热字段和三项Display值(共77列);时间线算法仍session-timeline.v1。原Session的stored metrics.csv不改写,新会话在旧列后追加13值及完整qualities/metricScopes/metricUnits JSON。batteryTemperatureRaw保留来源原单位,不与摄氏温度列混用。会话14项Frame summary仍在Core最终报告,不伪装逐秒原生值;GPU counter仍为源原生向量,缺schema为null。

合法0仍输出0.000000,nil/非有限值为空;消费者必须结合质量/单位/作用域区分candidate、source-sentinel、warmup、external-power-connected与missing。JSONL中缺新增键的旧会话仍兼容解码,不回填旧文件。修复字段遗漏不代表来源稳定或物理准确,更不代表54项100%已验收。合同、测试与未关门项。

2026-10-04 · 消费封存与端到端覆盖不能混同 ​

durable/completed与Raw→Metric→Report SHA/终序一致,只证明已消费并落盘的记录链闭合;不证明设备所有事件已取得、没有上游未解析积压或每项在当前时间窗有效。G3五轮每轮139行和181自身参考均完整封存,但帧源设备时轴远短于主机140s,全54项可信门仍未通过。设备时轴、主机交付时轴、实际窗口、各quality和独立reference必须分列;有值不自动calibrated。完整54项合同与增量。

Perfowl · Performance Observer