Uptime Kuma Agent自动批量配监控服务:内部 Socket.IO API 四脚本工具箱,与它踩过的所有坑
发布:2026-10-23 | 实测窗口:2026-10-18(Uptime Kuma 2.5.6 容器源码逐条核验)
结论先行:Uptime Kuma 没有管理型 REST API,Settings → API Keys 生成的密钥只服务/metrics——想批量加监控、配 SMTP 告警、开公开状态页,唯一路径是内部 Socket.IO API。本工具箱用四个零安装脚本把这条路径固化成"管道即用":幂等可重跑、凭据只走 stdin(不打印、不落盘)、在容器内跑(复用自带 socket.io-client,本机一个包都不用装)。
GitHub 仓库:【待补充:仓库地址】(首发 commit 后回填)
一、为什么会有这个工具箱
Uptime Kuma 是最流行的自托管监控面板之一,但当你想"程序化地管理它"时会撞上一堵墙:
- 没有管理型 REST API。Internal-API Wiki 自己声明:内部 Socket.IO API 非官方支持、大版本升级可能破坏性变更。
- API Key 是个陷阱。Settings → API Keys 生成的
uk2_...密钥只服务于/metrics(Prometheus 抓取),拿它去跑管理操作一律失败(Prometheus API Keys Wiki 为出处)。网上不少教程把这两件事混为一谈,照做会白折腾半天。 - UI 批量操作靠手点。几十个监控、SMTP 通知挂全量、状态页分组——点到手酸,且不可复现。
所以答案只剩一个:账号密码登录 + 内部 Socket.IO API。本工具箱把 2026-10-18 两套生产实例的实操抽离泛化成四个脚本,所有踩坑都固化进了代码与文档。
⚠️ 与文档冲突时以容器源码实测为准——本工具箱全部事件与载荷形状在
louislam/uptime-kuma:2.5.6源码逐条核验过。
二、四脚本清单(stdin 协议一句话版)
| 脚本 | 干什么 | stdin 组成 |
|---|---|---|
uptime-kuma-add-monitors.js |
批量加 HTTP 监控(幂等:按名称/URL 查重) | 1 用户名 / 2 密码 / 3 行起到 EOF:监控清单 JSON(可多行 pretty) |
uptime-kuma-email-notify.js |
SMTP 告警:先测后存 + applyExisting 全量挂载 |
1 用户名 / 2 密码 / 3 单行邮件载荷 JSON / 4(可选)旧通知名 |
uptime-kuma-status-page.js |
公开状态页 upsert(分组动态收录全部监控) | 1 用户名 / 2 密码 / 3 行起到 EOF:状态页配置 JSON |
drop-notification.js |
删指定通知 + 全监控关联验收 | 1 用户名 / 2 密码;通知 id 走命令行参数 |
共同设计:
- 零安装:
docker cp脚本进容器/app/下执行,node 从脚本目录向上找到容器自带的socket.io-client——本机不需要 npm install 任何东西。 - 幂等:监控按名称/URL 查重,通知与状态页 upsert——重复执行不产生副本。
- 自适配:全新未初始化实例自动
setup创建账号后继续。 - 凭据纪律:用户名/密码/SMTP 授权码只经 stdin 进入进程内存,脚本不打印、不写盘;输出里邮箱打码(
maskEmail)、密码永不回显。
三、五个踩坑(每个都是真实事故/实测换来的)
坑 1:notificationList 必须在 login 之前订阅 ⚠️ 最贵的一个
服务端在 login ack 的处理过程中就推送 notificationList。如果 login 成功后再 socket.on("notificationList"),会读到 0 条 → 旧通知名匹配失效 → 新建出第二个通知 → 同一故障发两封邮件(生产真实事故)。修复就一行:订阅写在 emit("login") 之前。
// ⚠️ 必须在 login 之前订阅(2026-10-18 生产实测踩坑):
let notifList = null;
socket.on("notificationList", (list) => { notifList = list; });
await loginWithSetup(socket, username, password); // 订阅在前,登录在后
drop-notification.js 的 monitorList 订阅同理。
坑 2:API Key 配不了监控(见 §一第 2 条)
uk2_... 只服务 /metrics。管理操作一律账号密码登录——这不是脚本的限制,是 Uptime Kuma 的设计边界。
坑 3:测试信的 Liquid 变量是 dummy 值
testNotification 发出的测试信里,{{ name }} 是 "Monitor Name not available"、{{ status }} 是 ⚠️ Test、heartbeatJSON 是 null。直接用真实告警模板会得到一个错乱的测试主题。样例载荷里的这个分支是刻意的:
{% if name == "Monitor Name not available" %}{{ msg }}{% else %}{{ status }} - {{ name }}{% endif %}
测试信与真实告警的主题都正确。配套纪律:邮件载荷必须是单行 JSON(email 脚本只读 stdin 第 3 行;PowerShell 用 ConvertTo-Json -Compress,bash 用 jq -c)——别把样例"美化"成多行。
坑 4:载荷字段类型差一个字符就崩
add的载荷必须含accepted_statuscodes数组,否则服务端处理器直接抛错;saveStatusPage的config.domainNameList必须是数组(空数组也行,字符串必崩);- 分组形状固定
{name, monitorList:[{id}]}。
监控默认值与前端 EditMonitor.vue 实发口径对齐:60s 间隔 / 200-299 判活 / maxretries 0——对着前端开发者工具抄一遍口径,比猜文档准。
坑 5:脚本放错目录 → Cannot find module 'socket.io-client'
node 从脚本所在目录逐级向上找 node_modules。正式用法是 docker cp 到容器 /app/ 下;放 /tmp 临时调试必须加 -e NODE_PATH=/app/node_modules。另外容器冷启动后数秒内首次登录可能慢于 15s 应答窗口——复跑即可,不是 bug。
四、部署与使用流程(推荐路径)
整条链路的推荐形态是 “本地 Docker 验证 → 服务器部署 → 本地自动批量添加”:
① 本地 Docker 起一个 Uptime Kuma 测试实例
↓ 按仓库 README 用假凭据/测试凭据跑通四脚本全流程
② 验收 OK(监控首跳 UP / 测试信收件 / 状态页免登录可开)
↓ 用户在服务器上部署正式 Uptime Kuma
③ 拿到账号密码(注意:只能是账号密码,API Key 走不通,见坑 2)
↓
④ 本地直接自动批量添加要追踪的服务(远程执行模式,免 SSH)
远程执行模式——本机容器当执行器,一条环境变量指向目标实例:
"$u`n$pw`n$cfgJson" | docker exec -i -e UPTIME_KUMA_URL=http://<目标IP>:<端口> `
<本机执行容器> node /app/uptime-kuma-add-monitors.js
最短上手(本地容器):
# 0) 四个脚本进容器
for f in scripts/*.js; do docker cp "$f" <容器名>:/app/; done
# 1) 凭据文件(裸两行:第1行用户名、第2行密码;用后即删)
printf '%s\n%s\n' '<用户名>' '<密码>' > creds.txt
# 2) 批量加监控
{ cat creds.txt; cat examples/targets.sample.json; } | \
docker exec -i <容器名> node /app/uptime-kuma-add-monitors.js
# 3) 用完删凭据
shred -u creds.txt 2>/dev/null || rm -f creds.txt
验收清单:监控列表出现全部目标且首跳 UP / 收件箱有测试信 / 状态页 URL 无痕窗口可开。
五、安全设计(代码层保证,不是靠自觉)
| 保证 | 实现 |
|---|---|
| 凭据不落盘 | 四脚本零 writeFile;凭据只经 stdin → 进程内存 → socket 发往你自己指定的 UPTIME_KUMA_URL(默认 localhost:3001) |
| 零外呼 | 全仓库唯一的 fetch 是状态页公开验收接口(拉自己刚建的 /api/status-page/<slug>);零 telemetry、零第三方域名 |
| 不回显 | password 只出现在 login/setup 发送处,无一处进 console.log;邮箱输出 maskEmail 打码 |
| 仓库不收凭据 | .gitignore 挡 creds.txt / key.txt / *.key / *.pem / *.log;所有 example 均为占位符形态 |
| AI 协作红线 | 仓库内置 AGENTS.md:冒烟只许假凭据、commit 信息不得含真实地址账号邮箱、发现疑似问题先问不自行改码 |
请勿把凭据文件内容粘贴给 AI 或贴进聊天——工具箱所有 sample 都是占位符,没有例外。
六、给 AI Agent 用的仓库(顺带一提)
本仓库自带 AGENTS.md,AI 编码代理打开仓库即自动获得:stdin 协议表、五条红线(login 前订阅、单行载荷、Liquid if 分支、数组口径、先问再改)、验证口径(node --check 四脚本 + 假凭据冒烟)。也就是说——把仓库丢给任何一个支持 AGENTS.md 的 agent,它就能正确地替你跑这四条管道,而不会"好心"把该保留的坑修掉。
七、事件速查表(2.5.6 源码核验,排障用)
| 事件 | 要点 |
|---|---|
login / needSetup / setup |
认证;全新实例自动 setup(密码太弱报 passwordTooWeak) |
getMonitorList → monitorList 事件 |
列表靠事件推送,ack 只回 {ok} |
add |
载荷须含 accepted_statuscodes 数组,否则处理器抛错 |
addNotification(payload, id, cb) |
id=null 新建 / 有 id 更新;applyExisting:true 挂全量 |
notificationList 事件 |
⚠️ login ack 处理中就推送——必须 login 前订阅,否则读 0 → 双通知双邮件 |
getStatusPage / addStatusPage / saveStatusPage |
分组 {name, monitorList:[{id}]};config.domainNameList 必须是数组 |
排障 Top 5:
| 症状 | 原因 / 处置 |
|---|---|
登录失败:用户名或密码错误 |
凭据文件须裸两行(有标签行会错位);或密码错 |
监控清单 JSON 解析失败 |
第 3 行起不是合法 JSON / creds 混入多余行 |
测试邮件发送失败:Invalid login... |
SMTP 授权码(非登录密码)错/过期 → 服务商后台重新生成 |
| 测试信里 name 显示 dummy 值 | 正常——renderTemplate 测试态兜底,用样例 if 分支规避 |
Cannot find module 'socket.io-client' |
脚本不在容器 /app 下 → 重新 docker cp;临时位置加 -e NODE_PATH=/app/node_modules |
八、脱敏声明
- 全文无真实服务器地址、账号、密码、SMTP 授权码、收件邮箱;示例一律
<目标IP>:<端口>、<用户名>占位符形态。 - 工具箱仓库内所有 example 均为占位符;
.gitignore挡凭据类文件。 - 本工具箱生成链路零外部请求(唯一 fetch 为自建状态页公开接口);文中外部链接仅为 Uptime Kuma 官方 wiki 出处。
- 叙事中的"生产事故""实测"仅保留日期与现象,不含可定位到具体环境的设备/网段/规模信息。
附:仓库与出处
- GitHub 仓库:https://github.com/firstsaofan/uptime-kuma-toolkit
- Internal-API Wiki · Prometheus API Keys Wiki · uptime-kuma-api 文档
- Uptime Kuma:https://github.com/louislam/uptime-kuma (本包按 2.5.6 核验)