Shutdown Check

搜索文档

查找页面或章节

在终端里阅读结果,或把同样的数据导出为 JSON 和 JUnit。

shutdown-check 每次运行都会产出一个结果,包含结论、诊断码、消息、时间线、耗时,以及捕获到的服务输出。给人看选文本,给脚本用选 JSON,给 CI 报告用选 JUnit XML。

选择输出格式

格式命令选项输出位置适用场景
文本默认stdout本地调试和 CI 日志
JSON--jsonstdout脚本和结构化日志
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" 等。
detailstring—事件对应的具体值,例如 "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。