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:
@@ -163,7 +163,7 @@ describe("ProbeStore", () => {
|
||||
durationMs: 150.5,
|
||||
failure: null,
|
||||
matched: true,
|
||||
statusDetail: "200 OK",
|
||||
observation: null,
|
||||
targetId: "test-http",
|
||||
timestamp: "2025-01-01T00:00:00.000Z",
|
||||
});
|
||||
@@ -172,7 +172,7 @@ describe("ProbeStore", () => {
|
||||
durationMs: 300,
|
||||
failure: null,
|
||||
matched: true,
|
||||
statusDetail: "200 OK",
|
||||
observation: null,
|
||||
targetId: "test-http",
|
||||
timestamp: "2025-01-01T00:00:30.000Z",
|
||||
});
|
||||
@@ -190,7 +190,7 @@ describe("ProbeStore", () => {
|
||||
durationMs: null,
|
||||
failure,
|
||||
matched: false,
|
||||
statusDetail: null,
|
||||
observation: null,
|
||||
targetId: "test-http",
|
||||
timestamp: "2025-01-01T00:01:00.000Z",
|
||||
});
|
||||
@@ -214,7 +214,7 @@ describe("ProbeStore", () => {
|
||||
durationMs: 100 + i,
|
||||
failure: null,
|
||||
matched: true,
|
||||
statusDetail: "200 OK",
|
||||
observation: null,
|
||||
targetId: "test-http",
|
||||
timestamp: `2025-01-01T01:${String(i).padStart(2, "0")}:00.000Z`,
|
||||
});
|
||||
@@ -302,7 +302,7 @@ describe("ProbeStore", () => {
|
||||
durationMs: 100 + index,
|
||||
failure: null,
|
||||
matched: index !== 1,
|
||||
statusDetail: "200 OK",
|
||||
observation: null,
|
||||
targetId: targetAId,
|
||||
timestamp,
|
||||
});
|
||||
@@ -311,7 +311,7 @@ describe("ProbeStore", () => {
|
||||
durationMs: 200,
|
||||
failure: null,
|
||||
matched: true,
|
||||
statusDetail: "200 OK",
|
||||
observation: null,
|
||||
targetId: targetBId,
|
||||
timestamp: "2025-01-01T00:03:00.000Z",
|
||||
});
|
||||
@@ -319,7 +319,7 @@ describe("ProbeStore", () => {
|
||||
durationMs: null,
|
||||
failure: { kind: "error", message: "fail", path: "request", phase: "request" },
|
||||
matched: false,
|
||||
statusDetail: null,
|
||||
observation: null,
|
||||
targetId: targetBId,
|
||||
timestamp: "2025-01-01T00:04:00.000Z",
|
||||
});
|
||||
@@ -373,7 +373,7 @@ describe("ProbeStore", () => {
|
||||
durationMs: 100,
|
||||
failure: null,
|
||||
matched: true,
|
||||
statusDetail: "200 OK",
|
||||
observation: null,
|
||||
targetId: t.id,
|
||||
timestamp: "2025-01-01T00:00:00.000Z",
|
||||
});
|
||||
@@ -381,7 +381,7 @@ describe("ProbeStore", () => {
|
||||
durationMs: null,
|
||||
failure: { kind: "error", message: "fail", path: "$", phase: "status" },
|
||||
matched: false,
|
||||
statusDetail: null,
|
||||
observation: null,
|
||||
targetId: t.id,
|
||||
timestamp: "2025-01-01T00:01:00.000Z",
|
||||
});
|
||||
@@ -493,7 +493,7 @@ describe("ProbeStore", () => {
|
||||
durationMs: 100,
|
||||
failure: null,
|
||||
matched,
|
||||
statusDetail: matched ? "200 OK" : "500 ERROR",
|
||||
observation: null,
|
||||
targetId,
|
||||
timestamp: `2025-01-01T00:0${index}:00.000Z`,
|
||||
});
|
||||
@@ -535,7 +535,7 @@ describe("ProbeStore", () => {
|
||||
durationMs: 100,
|
||||
failure: null,
|
||||
matched: false,
|
||||
statusDetail: null,
|
||||
observation: null,
|
||||
targetId: targetBId,
|
||||
timestamp: "2025-01-01T00:03:00.000Z",
|
||||
});
|
||||
@@ -543,7 +543,7 @@ describe("ProbeStore", () => {
|
||||
durationMs: 100,
|
||||
failure: null,
|
||||
matched: true,
|
||||
statusDetail: "200 OK",
|
||||
observation: null,
|
||||
targetId: targetAId,
|
||||
timestamp: "2025-01-01T00:02:00.000Z",
|
||||
});
|
||||
@@ -551,7 +551,7 @@ describe("ProbeStore", () => {
|
||||
durationMs: 100,
|
||||
failure: null,
|
||||
matched: false,
|
||||
statusDetail: null,
|
||||
observation: null,
|
||||
targetId: targetAId,
|
||||
timestamp: "2025-01-01T00:01:00.000Z",
|
||||
});
|
||||
@@ -574,7 +574,7 @@ describe("ProbeStore", () => {
|
||||
durationMs: 100,
|
||||
failure: null,
|
||||
matched: true,
|
||||
statusDetail: "200 OK",
|
||||
observation: null,
|
||||
targetId: t.id,
|
||||
timestamp: "2020-01-01T00:00:00.000Z",
|
||||
});
|
||||
@@ -582,7 +582,7 @@ describe("ProbeStore", () => {
|
||||
durationMs: 100,
|
||||
failure: null,
|
||||
matched: true,
|
||||
statusDetail: "200 OK",
|
||||
observation: null,
|
||||
targetId: t.id,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
@@ -605,7 +605,7 @@ describe("ProbeStore", () => {
|
||||
durationMs: 100,
|
||||
failure: null,
|
||||
matched: true,
|
||||
statusDetail: "200 OK",
|
||||
observation: null,
|
||||
targetId: t.id,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
@@ -626,7 +626,7 @@ describe("ProbeStore", () => {
|
||||
durationMs: 100,
|
||||
failure: null,
|
||||
matched: true,
|
||||
statusDetail: "200 OK",
|
||||
observation: null,
|
||||
targetId: t.id,
|
||||
timestamp: new Date(now - 3600000).toISOString(),
|
||||
});
|
||||
@@ -634,7 +634,7 @@ describe("ProbeStore", () => {
|
||||
durationMs: 200,
|
||||
failure: null,
|
||||
matched: true,
|
||||
statusDetail: "200 OK",
|
||||
observation: null,
|
||||
targetId: t.id,
|
||||
timestamp: new Date(now).toISOString(),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user