feat: 结构化 observation 替代 statusDetail,API 层动态构造 detail
- CheckResult: statusDetail -> observation (持久化) + detail (API 动态派生) - 存储: status_detail 列 -> observation TEXT (JSON) - CheckerDefinition: 新增 buildDetail(observation) 方法 - 各 checker 返回结构化 observation,API 层通过 registry 调用 buildDetail - HTTP: bodyPreview 在 status/header 失败时也提前采集 - UDP: observation 包含 durationMs,未响应归为 error failure - CMD: 超时/输出超限时保留已收集 observation - TCP: connectTimeMs 仅含连接建立耗时,不含 banner 等待 - 新增 buildDetail 单测和 mapCheckResult 覆盖测试 - 同步 openspec 主规范,归档 checker-observation 变更
This commit is contained in:
@@ -36,27 +36,27 @@
|
||||
- **THEN** `target` 展示摘要 SHALL 为 `<host>:<port>`,`config` JSON SHALL 包含 resolved 后的 host、port、readBanner、bannerReadTimeout 和 maxBannerBytes
|
||||
|
||||
### Requirement: tcp checker 执行
|
||||
系统 SHALL 按 tcp target 配置建立 TCP 连接,记录完整执行耗时,并在连接失败、超时或资源超限时产生结构化失败信息。
|
||||
系统 SHALL 按 tcp target 配置建立 TCP 连接,记录完整执行耗时和 TCP observation,并在连接失败、超时或资源超限时产生结构化失败信息。
|
||||
|
||||
#### Scenario: TCP 连接成功
|
||||
- **WHEN** tcp target 指向可连接的 TCP 服务,且未配置 expect 或 `expect.connected` 为 `true`
|
||||
- **THEN** 系统 SHALL 记录 `matched=true`、`durationMs` 和 `statusDetail`,并关闭 socket
|
||||
- **THEN** 系统 SHALL 记录 `matched=true`、`durationMs` 和包含 connected、connectTimeMs、banner 的 observation,并关闭 socket
|
||||
|
||||
#### Scenario: TCP 连接失败
|
||||
- **WHEN** tcp target 指向不可连接的 host/port,且未配置 expect 或 `expect.connected` 为 `true`
|
||||
- **THEN** 系统 SHALL 记录 `matched=false`,failure 的 kind 为 `error`,phase 为 `connect`,message 包含可读连接失败原因
|
||||
- **THEN** 系统 SHALL 记录 `matched=false`,observation SHALL 包含 connected=false 和错误信息,failure 的 kind 为 `error`,phase 为 `connect`,message 包含可读连接失败原因
|
||||
|
||||
#### Scenario: 期望端口不可达且连接失败
|
||||
- **WHEN** tcp target 配置 `expect.connected: false`,且 TCP 连接失败
|
||||
- **THEN** 系统 SHALL 记录 `matched=true`,statusDetail SHALL 展示实际连接失败原因摘要
|
||||
- **THEN** 系统 SHALL 记录 `matched=true`,observation SHALL 包含 connected=false 和实际连接失败原因,API detail SHALL 展示实际连接失败原因摘要
|
||||
|
||||
#### Scenario: 期望端口不可达但连接成功
|
||||
- **WHEN** tcp target 配置 `expect.connected: false`,但 TCP 连接成功
|
||||
- **THEN** 系统 SHALL 记录 `matched=false`,failure 的 kind 为 `mismatch`,phase 为 `connected`
|
||||
- **THEN** 系统 SHALL 记录 `matched=false`,observation SHALL 包含 connected=true,failure 的 kind 为 `mismatch`,phase 为 `connected`
|
||||
|
||||
#### Scenario: TCP 执行超时
|
||||
- **WHEN** 引擎注入的 `ctx.signal` 在 TCP 连接或 banner 读取过程中 abort
|
||||
- **THEN** 系统 SHALL best-effort 关闭 socket,记录 `matched=false`,failure 的 kind 为 `error`,phase 为 `connect` 或 `banner`,message 包含超时信息
|
||||
- **THEN** 系统 SHALL best-effort 关闭 socket,记录 `matched=false`,failure 的 kind 为 `error`,phase 为 `connect` 或 `banner`,message 包含超时信息,并在可收集时记录 observation
|
||||
|
||||
#### Scenario: duration 包含 banner 读取
|
||||
- **WHEN** tcp target 开启 `readBanner` 且服务端延迟发送 banner
|
||||
@@ -81,9 +81,9 @@
|
||||
- **WHEN** 服务端发送的 banner 数据超过 `maxBannerBytes`
|
||||
- **THEN** 系统 SHALL 停止读取并记录 `matched=false`、failure.kind=`error`、failure.phase=`banner` 的结构化错误
|
||||
|
||||
#### Scenario: banner statusDetail 截断展示
|
||||
#### Scenario: banner detail 截断展示
|
||||
- **WHEN** tcp target 成功读取到较长 banner
|
||||
- **THEN** `statusDetail` SHALL 展示截断后的 banner 摘要,避免 UI 和历史记录写入过长文本
|
||||
- **THEN** observation.banner SHALL 保存截断后的 banner 摘要,API detail SHALL 展示截断后的 banner 摘要,避免 UI 展示过长文本
|
||||
|
||||
### Requirement: tcp expect 校验
|
||||
系统 SHALL 支持 tcp 专属 expect,包括 `connected`、`banner` 和 `durationMs`,并按 connected、banner、durationMs 的阶段顺序快速失败。`connected` SHALL 保持布尔状态语义,未配置时默认 `true`。`banner` MUST 使用共享 `ContentRules` 数组,并仅在 `tcp.readBanner: true` 时允许配置。`durationMs` SHALL 使用共享 `ValueMatcher` 校验包含连接和 banner 读取在内的完整执行耗时。
|
||||
|
||||
Reference in New Issue
Block a user