shutdown-check 每次运行都会产出一个结果,包含结论、诊断码、消息、时间线、耗时,以及捕获到的服务输出。给人看选文本,给脚本用选 JSON,给 CI 报告用选 JUnit XML。
选择输出格式
| 格式 | 命令选项 | 输出位置 | 适用场景 |
|---|---|---|---|
| 文本 | 默认 | stdout | 本地调试和 CI 日志 |
| JSON | --json | stdout | 脚本和结构化日志 |
| JUnit XML | --junit FILE | 文件 | CI 的测试报告界面 |
| 退出码 | 始终 | 进程 | 让调用方判定通过或失败 |
打印文本或 JSON 的同时,都可以写出 JUnit:
npx shutdown-check test --json --junit shutdown-result.xml阅读文本输出
通过时,结果包含结论和时间线:
PASS SC000: Graceful shutdown verified
Timeline:
+ 5 ms process launched — pid=67911
+ 113 ms service ready — HTTP 200
+ 113 ms work request sent — #1 GET /slow
+ 113 ms work request sent — #2 GET /slow
+ 114 ms work confirmed active — 2 response(s) sent headers; bodies still in progress
+ 114 ms signal sent — SIGTERM
+ 115 ms readiness withdrawn — HTTP 503
+ 115 ms new request rejected — HTTP 503
+ 2117 ms work request finished — #1 HTTP 200
+ 2117 ms work request finished — #2 HTTP 200
+ 2120 ms process exited — code=0, signal=none
+ 2121 ms shutdown verified — work completed and service exited before deadline+ 后面的数字是从运行开始算起的毫秒数。按顺序往下读,就能看到 SIGTERM 前后发生了什么。
失败时,最后一行是 check failed:
FAIL SC201: In-flight request was interrupted: aborted
Timeline:
+ 6 ms process launched — pid=73692
+ 112 ms service ready — HTTP 200
+ 113 ms work request sent — #1 GET /slow
+ 113 ms work confirmed active — 1 response(s) sent headers; bodies still in progress
+ 113 ms signal sent — SIGTERM
+ 116 ms process exited — code=null, signal=SIGTERM
+ 116 ms work request finished — #1 aborted
+ 116 ms check failed — SC201: In-flight request was interrupted: aborted打开对应诊断码的页面(这里是 SC201),查看原因和修复方法。
服务的 stdout 和 stderr
检查失败时,文本输出会附上服务每个非空输出流的最后 8 KiB:
Service stderr (last 8 KiB):
Error: database close timed out
Service stdout (last 8 KiB):
SIGTERM received
closing HTTP server输出流超过 8 KiB 时,较早的内容会丢弃。所以关闭日志要简洁,重要的状态要在靠近失败的地方打印。
服务输出是先捕获、后显示的,不会实时输出。它显示在结果之后,这样时间线依然清晰易读。
时间线事件
| 事件 | 含义 |
|---|---|
process launched | 配置的启动命令已启动 |
service ready | 就绪检查路由返回了预期状态码 |
work request sent | 发出了一个测试请求 |
work confirmed active | 所选的启动确认已通过 |
signal sent | 已发送第一次 SIGTERM |
signal repeated | 已发送可选的第二次 SIGTERM |
readiness withdrawn | 就绪检查路由不再报告就绪 |
new request rejected | 新请求返回了允许的状态码,或连接被拒绝 |
work request finished | 一个测试请求的响应已完成或失败 |
process exited | 启动的进程已停止 |
shutdown verified | 所有配置的检查都已通过 |
check failed | 运行以显示的诊断码结束 |
只有配置中对应的部分运行了,相应的事件才会出现。例如,只有启用了 shutdown.readinessWithdrawal,才会出现 readiness withdrawn。
JSON 输出
运行:
npx shutdown-check test --json命令会打印一个 JSON 对象。下面是一个精简过的通过示例:
{
"pass": true,
"code": "SC000",
"message": "Graceful shutdown verified",
"startedAt": "2026-09-23T10:00:00.000Z",
"durationMs": 2121,
"timeline": [
{ "ms": 5, "event": "process launched", "detail": "pid=67911" },
{ "ms": 114, "event": "signal sent", "detail": "SIGTERM" },
{
"ms": 2121,
"event": "shutdown verified",
"detail": "work completed and service exited before deadline"
}
],
"stdout": "",
"stderr": ""
}| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| pass* | boolean | — | 仅当结果为 SC000 时为 true。 |
| code* | string | — | 诊断码:通过时为 SC000,否则为第一个失败项的诊断码。 |
| message* | string | — | 用一句话说明发生了什么,并附上观察到的值。 |
| timeline* | TimelineEvent[] | — | 按顺序列出检查的每一步,并标出从检查开始算起的毫秒数。 |
| stdout* | string | — | 服务写入 stdout 的最后 8 KiB 内容。 |
| stderr* | string | — | 服务写入 stderr 的最后 8 KiB 内容。 |
timeline 数组中的每一项:
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| ms* | number | — | 从检查开始算起的毫秒数,已取整。 |
| event* | string | — | 发生了什么:"process launched"、"service ready"、"signal sent"、"work request finished"、"process exited" 等。 |
| detail | string | — | 事件对应的具体值,例如 "HTTP 503" 或 "code=0, signal=none"。 |
JSON 模式的退出码与文本模式相同。失败时仍然以 1 退出,所以 shell 步骤可能需要先保存 stdout,再根据退出码做处理。
JUnit 报告
运行:
npx shutdown-check test --junit reports/shutdown.xml父目录必须已经存在。shutdown-check 会写出一个测试套件,其中只有一个测试用例:
- 通过时没有 failure 元素。
- 关闭失败时,诊断码和消息作为 failure 写入。
- 时间线写入 system output。
- 如果捕获到了服务的 stdout 和 stderr,也会一并写入。
- 套件耗时取本次运行的耗时。
默认的套件名是 shutdown-check。使用 Node API 时,给 junitXml(result, name) 传第二个参数即可换一个名字。
CLI 会先写报告,再打印文本或 JSON,因此普通的检查失败仍会生成报告文件。出现环境或配置错误时不会生成报告,因为没有产生 CheckResult。
退出码
| 退出码 | 含义 |
|---|---|
| 0 | 通过 |
| 1 | 关闭检查失败 |
| 2 | 环境或配置错误 |
| 退出码 | 含义 | 可用的输出 |
|---|---|---|
0 | 配置的关闭约定已通过 | 文本/JSON,以及可选的 JUnit |
1 | 测试已运行,返回了表示失败的 SC 诊断码 | 文本/JSON,以及可选的 JUnit |
2 | 参数、环境或配置问题中止了运行 | stderr 上的错误;没有 JUnit 结果 |
只要退出码不为 0,CI 就应该判定失败。2 说明测试环境本身有问题;1 说明服务的行为需要排查。
在代码中使用结果
checkShutdown() 和 runCheck() 返回的 CheckResult 对象与 JSON 输出的相同。junitXml() 生成的 XML 也与 CLI 的一致。
import { checkShutdown, junitXml } from "shutdown-check";
const result = await checkShutdown(config);
const xml = junitXml(result, "orders-api shutdown");完整的自定义运行器见 Node API。