我不再用面板看服务:把状态压成两个 JSON

我装过一次面板。它把我关心的东西压缩成一个绿色圆点:服务在跑,就是绿的;至于它在响应什么、慢在哪里,一概不显示。可它不告诉我端口绑在哪、证书从哪来、日志写到哪;真出故障,我还是得 SSH 上去一条条看。后来我把这套东西拆了,换成一个每分钟跑一次的采集脚本,和两个 JSON 文件。

面板的问题不是不好看

面板的问题不是不好看,是它替你决定了什么算「正常」。进程在、端口通,并不等于服务可用:证书过期、上游 502、磁盘写满,绿点都还是绿的。我要的不是一个判断,是判断背后的原始事实。

两个 JSON 里放什么

采集脚本每分钟跑一次,输出两份文件。第一份是服务状态:每个服务一条,记录 HTTP 状态码和耗时。第二份是系统指标:CPU、内存、磁盘、负载、运行时长,全部从 /proc 里读,不额外装 agent。

文件内容谁在读
服务状态每个服务的状态码与毫秒数首页卡片、告警脚本
系统指标CPU、内存、磁盘、负载、运行时长首页、我自己的脚本

探测用一个 curl 进程带并发,而不是每个服务起一个:

curl -sS -I --max-redirs 0 -m 6 --parallel \
  -w '%{url_effective} %{http_code} %{time_total}\n' \
  -o /dev/null <每个服务的地址>

判定规则只有一句:能连上、且状态码小于 500,就算活着。303、401、403 都说明服务在响应——它可能只是把我重定向到登录页,那也算进程还在。5xx、超时、连不上,才算挂。不跟随重定向是故意的:跟着跳到登录页,等于拿别人的页面证明自己的服务活着。

七个服务合成一次进程启动,CPU 占用大概只有逐个探测的三分之一。这类细节在面板里看不见,但在这台小机器上,一个每分钟都要跑的东西值得省。

为什么是静态页面

页面本身是一个静态 HTML,只负责读两个 JSON、把字段填进模板。没有后端,没有数据库。好处有三条:页面挂了不影响任何服务;换一台服务器、换一个静态托管都能跑;出问题时可以直接 curl 那两个 JSON,看到的就是页面看到的东西。

我甚至不介意它有几分钟的延迟。状态页的用途是「知道现在大概什么情况」,不是秒级监控;真要看秒级,还是得看日志和 systemctl status。

采集脚本要能手动跑

采集脚本必须能手动跑一次,输出和定时器跑出来的完全一样。否则出问题时,我分不清是服务坏了,还是采集本身坏了。定时器只负责按点叫醒它,判断逻辑只有一份。

数字只出现一次

做这个页面时我给自己定了一条:同一个数字只出现一次,图表不重复叙述同一件事。CPU 已经在指标区写了百分比,就不要在旁边再画一个只表达同一个百分比的环形图。少一个图形,少一次解释,也少一次「图和数据对不上」的怀疑。

另外三条:

  • 页面不判断,只展示:判断留给读的人;
  • 每个数字带时间戳:checked_at 是这份 JSON 的,不是页面的;
  • 采集失败要显眼:文件不再更新,比数字难看重要得多。

加一个新服务,要改的地方也就三处:

  1. 在采集脚本的清单里加一行名字和地址;
  2. 确认它绑的是回环,探测走本机;
  3. 首页加一张卡片,读同一个 JSON 里的 key。

一个能跑命令的面板,比一张漂亮的图有用;一份能被 curl 到的 JSON,比一个只有面板能读的数据库有用。

现在我的状态页很朴素:几行字、几个数字、一个时间戳。它不解释,也不安慰人。但它和我 SSH 上去看到的是同一批事实,这一点比绿点重要。