docs(memory): Uptime Kuma 接入 Bark 告警并通过端到端验证
This commit is contained in:
parent
bcfc932061
commit
b58f09a924
@ -1,5 +1,6 @@
|
||||
# 2026-09-13
|
||||
|
||||
2026-09-13 | CHG | Uptime Kuma 接入 Bark 告警:新增通知渠道「Bark 手机推送」(type 必须写 `Bark` 首字母大写,端点用容器网关 `http://172.17.0.1:8081/<key>`),已关联全部 9 个监控;用临时监控触发真实 DOWN 完成端到端验证(Bark 日志实测收到并返 200)后清理
|
||||
2026-09-13 | DEP | 安装用户级技能 `design-taste-frontend`(taste-skill v2,源 github.com/Leonxlnx/taste-skill,上游路径 skills/taste-skill/SKILL.md);安装前完成安全审计(P2 安全,纯 Markdown 无脚本);description 追加中文触发词;来源与审计记录见 `~/.workbuddy/skills/design-taste-frontend/SOURCE.md`
|
||||
2026-09-13 | FIX | 本机 git 走系统代理(HTTP_PROXY=127.0.0.1:58412)导致 github clone 失败(Empty reply / CONNECT 502)→ 清空代理 env 后用 `curl --noproxy "*"` 拉 codeload tarball 再解压可正常下载;另 Bash 工具在本机不可用(shim 报 dirname: command not found),需改用 PowerShell
|
||||
2026-09-13 | CHG | Uptime Kuma 第一批监控上线:9 个站点 HTTP 监控(60/120/300s 三档 + 证书到期通知),因官方 API 不支持创建监控,采用「直写 SQLite monitor 表 + 重启容器」批量添加
|
||||
|
||||
@ -67,5 +67,12 @@
|
||||
| file / read / tool / sub2api | 120s | 2 | 2000 |
|
||||
| code / status | 300s | 2 | 3000 |
|
||||
- **`service.xpcool.com` 单独放宽为 `["200-399","404"]`**:该后端是纯 POST 接口(遵循本项目"接口全 POST"规范),任何 GET 都 404;返回 404 说明 nginx + GoFrame 存活,**后端进程真挂时 nginx 返回 502,仍会判 DOWN**。
|
||||
- **通知渠道(Bark,2026-09-13 勘查结论)**:Kuma 2.5.3 **原生支持 Bark**(`/app/server/notification-providers/bark.js`),对应 `notification` 表(字段 `id/name/active/user_id/is_default/config`,`config` 为 JSON 字符串;截至 09-13 该表为空 = 尚未配通知)。Bark 服务端 = 容器 `bark`(`finab/bark-server`,`0.0.0.0:8081`),另经 `service.xpcool.com/bark/` 反代(末尾斜杠会剥掉 `/bark/` 前缀);当前 server-monitor.sh 用的 key 在 `/etc/server-monitor.conf` 的 `BARK_URL`。**注意**:Kuma 容器访问 Bark 建议用宿主机地址(容器内 `127.0.0.1` 不是宿主机),即 `http://172.17.0.1:8081/<key>`(或把 kuma 加入 `xpcool-net` 后用容器名 `bark`)。
|
||||
- **待办**:「证书到期提前几天通知」需在面板设置里确认。
|
||||
- **通知渠道 = Bark(2026-09-13 已配置并验证)**:Kuma 2.5.3 原生支持 Bark(`/app/server/notification-providers/bark.js`)。`notification` 表:`id/name/active/user_id/is_default/config`,**`config` 是整条通知对象的 JSON 字符串(含 `type`),Kuma 用 `providerList[notification.type]` 派发,靠 `item.name` 索引**。
|
||||
- **最大的坑:`type` 必须写 `Bark`(首字母大写)**,不是 `bark`。前端 `NotificationDialog.vue:257` 就是 `Bark: "Bark"`;写成小写则查不到 provider,**静默不发通知**。
|
||||
- 当前配置:`id=1 / name='Bark 手机推送' / is_default=1`,`config` = `{"type":"Bark","barkEndpoint":"http://172.17.0.1:8081/sm5WnyANWx89GgLtFnRXhk","barkGroup":"Uptime-Kuma","apiVersion":"v1"}`。
|
||||
- **端点必须用容器网关 `172.17.0.1:8081`**:kuma 在默认 `bridge` 网络(网关 172.17.0.1),容器内的 `127.0.0.1` 不是宿主机;Bark 容器端口发布在宿主机 `0.0.0.0:8081`,故走网关可达(实测 200)。
|
||||
- `apiVersion:"v1"` → 走 GET `{endpoint}/{title}/{body}?icon=…&group=…&sound=…`(bark-server 支持);不填也默认 v1。Bark key 就是 `/etc/server-monitor.conf` 里 `BARK_URL` 那个(`sm5WnyANWx89GgLtFnRXhk`),手机端就是 `https://service.xpcool.com/bark/<key>/`。
|
||||
- 挂到监控:`monitor_notification(monitor_id, notification_id)`;**等价于 UI 的 `applyExisting`**。已为 9 个监控全部关联(共 9 行)。
|
||||
- 脚本:`.workbuddy/tmp/kuma-bark-setup.sh`(幂等写入)、`.workbuddy/tmp/kuma-bark-verify.sh`(端到端验证 + 自清理);改库前必备份 `/tmp/kuma.db.backup.<时间戳>`。
|
||||
- **端到端验证方法(推荐复用)**:临时插一个指向 `http://127.0.0.1:9/` 的监控(`interval=20/retry_interval=20/maxretries=0`)→ 重启容器 → 十几秒即 DOWN 并推送 → 查 `docker logs bark` 确认真的收到 GET 推送(200)→ 删掉临时监控与其 heartbeat 再重启。全程不清真站点,可靠性最高。
|
||||
- 全部 9 个监控 `expiry_notification=1`(证书到期通知已开),当前均 UP。
|
||||
|
||||
37
.workbuddy/tmp/kuma-bark-inspect.sh
Normal file
37
.workbuddy/tmp/kuma-bark-inspect.sh
Normal file
@ -0,0 +1,37 @@
|
||||
#!/bin/bash
|
||||
# 1) 确认 Bark key 可用(发一条真实测试推送) 2) 取 Kuma Bark 通知配置字段 3) 查容器网络(决定用哪个地址访问 Bark)
|
||||
# 2026-09-13
|
||||
|
||||
KEY="sm5WnyANWx89GgLtFnRXhk"
|
||||
|
||||
echo "=== 1. Bark 服务自检 ==="
|
||||
curl -s -o /dev/null -m 10 -w "healthz=%{http_code}\n" http://127.0.0.1:8081/healthz
|
||||
|
||||
echo ""
|
||||
echo "=== 2. 发送真实测试推送(宿主机 → Bark) ==="
|
||||
curl -s -m 20 -o /tmp/bark-test.json -w "http=%{http_code}\n" \
|
||||
"http://127.0.0.1:8081/$KEY/Kuma%20Test/ai-verify-20260913"
|
||||
echo "--- resp ---"
|
||||
cat /tmp/bark-test.json 2>/dev/null
|
||||
echo ""
|
||||
|
||||
echo ""
|
||||
echo "=== 3. Kuma 容器网络 ==="
|
||||
sudo docker inspect uptime-kuma --format '{{json .NetworkSettings.Networks}}'
|
||||
echo ""
|
||||
echo "--- 容器内能否访问宿主机 Bark (172.17.0.1) ---"
|
||||
sudo docker exec uptime-kuma sh -c "curl -s -o /dev/null -m 8 -w 'code=%{http_code}\n' http://172.17.0.1:8081/healthz" 2>&1 || echo "container curl 不可用"
|
||||
|
||||
echo ""
|
||||
echo "=== 4. Bark 通知 provider 源码(取字段名) ==="
|
||||
sudo docker exec uptime-kuma cat /app/server/notification-providers/bark.js 2>&1 | head -60
|
||||
|
||||
echo ""
|
||||
echo "=== 5. Kuma 表结构 ==="
|
||||
sudo docker exec uptime-kuma sqlite3 /app/data/kuma.db "PRAGMA table_info(notification);" 2>&1
|
||||
echo "--- monitor_notification ---"
|
||||
sudo docker exec uptime-kuma sqlite3 /app/data/kuma.db "PRAGMA table_info(monitor_notification);" 2>&1
|
||||
echo "--- 现有通知 ---"
|
||||
sudo docker exec uptime-kuma sqlite3 /app/data/kuma.db "SELECT id,name,active,user_id,is_default FROM notification;" 2>&1
|
||||
echo "--- 现有监控 ---"
|
||||
sudo docker exec uptime-kuma sqlite3 /app/data/kuma.db "SELECT id,name FROM monitor ORDER BY id;" 2>&1
|
||||
58
.workbuddy/tmp/kuma-bark-setup.sh
Normal file
58
.workbuddy/tmp/kuma-bark-setup.sh
Normal file
@ -0,0 +1,58 @@
|
||||
#!/bin/bash
|
||||
# 为 Uptime Kuma 配置 Bark 通知渠道,并挂到全部监控(2026-09-13)
|
||||
# 幂等:重复执行不会产生重复行
|
||||
set -e
|
||||
|
||||
DB=/app/data/kuma.db
|
||||
KEY="sm5WnyANWx89GgLtFnRXhk"
|
||||
KCONF="/data/uptime-kuma/kuma.db"
|
||||
TS=$(date +%Y%m%d%H%M%S)
|
||||
|
||||
echo "=== 0. 备份数据库 ==="
|
||||
sudo cp "$KCONF" "/tmp/kuma.db.backup.$TS"
|
||||
ls -l "/tmp/kuma.db.backup.$TS"
|
||||
|
||||
echo ""
|
||||
echo "=== 1. 用 Kuma 的 URL 格式在容器内实测一次(含 icon/group/sound 参数) ==="
|
||||
sudo docker exec uptime-kuma sh -c "curl -s -o /dev/null -m 15 -w 'kuma_style_url=%{http_code}\n' 'http://172.17.0.1:8081/$KEY/UptimeKuma%20Monitor%20Down/test-from-kuma-container?icon=https%3A%2F%2Fgithub.com%2Flouislam%2Fuptime-kuma%2Fraw%2Fmaster%2Fpublic%2Ficon.png&group=Uptime-Kuma&sound=telegraph'"
|
||||
|
||||
echo ""
|
||||
echo "=== 2. 写入 Bark 通知(若不存在) ==="
|
||||
NAME='Bark 手机推送'
|
||||
CONFIG='{"type":"Bark","name":"Bark 手机推送","barkEndpoint":"http://172.17.0.1:8081/sm5WnyANWx89GgLtFnRXhk","barkGroup":"Uptime-Kuma","apiVersion":"v1","isDefault":true,"active":true,"applyExisting":false}'
|
||||
|
||||
EXIST=$(sudo docker exec uptime-kuma sqlite3 "$DB" "SELECT COUNT(*) FROM notification WHERE name='$NAME';")
|
||||
if [ "$EXIST" = "0" ]; then
|
||||
sudo docker exec uptime-kuma sqlite3 "$DB" "INSERT INTO notification (name, active, user_id, is_default, config) VALUES ('$NAME', 1, 1, 1, '$CONFIG');"
|
||||
echo "已新增通知渠道"
|
||||
else
|
||||
sudo docker exec uptime-kuma sqlite3 "$DB" "UPDATE notification SET active=1, is_default=1, config='$CONFIG' WHERE name='$NAME';"
|
||||
echo "已更新既有通知渠道"
|
||||
fi
|
||||
|
||||
echo "--- JSON 合法性校验 ---"
|
||||
sudo docker exec uptime-kuma sqlite3 "$DB" "SELECT id, json_valid(config) AS json_ok, json_extract(config,'\$.type') AS type, json_extract(config,'\$.barkEndpoint') AS endpoint FROM notification;"
|
||||
|
||||
NID=$(sudo docker exec uptime-kuma sqlite3 "$DB" "SELECT id FROM notification WHERE name='$NAME' LIMIT 1;")
|
||||
echo "notification_id=$NID"
|
||||
|
||||
echo ""
|
||||
echo "=== 3. 挂到全部监控(幂等) ==="
|
||||
sudo docker exec uptime-kuma sqlite3 "$DB" "INSERT INTO monitor_notification (monitor_id, notification_id) SELECT m.id, $NID FROM monitor m WHERE NOT EXISTS (SELECT 1 FROM monitor_notification mn WHERE mn.monitor_id = m.id AND mn.notification_id = $NID);"
|
||||
echo "--- 关联结果 ---"
|
||||
sudo docker exec uptime-kuma sqlite3 "$DB" "SELECT mn.monitor_id, m.name, mn.notification_id FROM monitor_notification mn JOIN monitor m ON m.id = mn.monitor_id ORDER BY mn.monitor_id;"
|
||||
|
||||
echo ""
|
||||
echo "=== 4. 重启容器加载配置 ==="
|
||||
sudo docker restart uptime-kuma > /dev/null
|
||||
sleep 15
|
||||
sudo docker ps --filter name=uptime-kuma --format '{{.Names}} | {{.Status}}'
|
||||
curl -s -o /dev/null -m 10 -w "panel_http=%{http_code}\n" http://127.0.0.1:3001/
|
||||
|
||||
echo ""
|
||||
echo "=== 5. 复核 ==="
|
||||
sudo docker exec uptime-kuma sqlite3 "$DB" "SELECT id,name,active,is_default FROM notification;"
|
||||
sudo docker exec uptime-kuma sqlite3 "$DB" "SELECT COUNT(*) AS linked FROM monitor_notification;"
|
||||
echo "=== 容器日志尾部(看有无通知相关报错) ==="
|
||||
sudo docker logs --tail 20 uptime-kuma 2>&1 | grep -i -E "error|notification|bark" || echo "(无相关日志)"
|
||||
echo "DONE"
|
||||
12
.workbuddy/tmp/kuma-bark-src.sh
Normal file
12
.workbuddy/tmp/kuma-bark-src.sh
Normal file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
# 查看 Kuma Bark 通知的完整实现与 config 结构要求
|
||||
echo "=== bark.js 全文 ==="
|
||||
sudo docker exec uptime-kuma cat /app/server/notification-providers/bark.js 2>&1
|
||||
|
||||
echo ""
|
||||
echo "=== notification-provider.js 的 postNotification ==="
|
||||
sudo docker exec uptime-kuma sed -n '1,80p' /app/server/notification-providers/notification-provider.js 2>&1
|
||||
|
||||
echo ""
|
||||
echo "=== notification.js 里 config / type 的解析 ==="
|
||||
sudo docker exec uptime-kuma grep -n "JSON.parse\|notification.type\|config" /app/server/notification.js 2>&1 | head -30
|
||||
69
.workbuddy/tmp/kuma-bark-verify.sh
Normal file
69
.workbuddy/tmp/kuma-bark-verify.sh
Normal file
@ -0,0 +1,69 @@
|
||||
#!/bin/bash
|
||||
# 端到端验证 Bark 告警:临时加一个必然失败的监控 → 触发 DOWN → 看推送是否送达 → 清理
|
||||
# 2026-09-13
|
||||
|
||||
DB=/app/data/kuma.db
|
||||
Q() { sudo docker exec uptime-kuma sqlite3 "$DB" "$1"; }
|
||||
KCONF=/data/uptime-kuma/kuma.db
|
||||
TS=$(date +%Y%m%d%H%M%S)
|
||||
|
||||
sudo cp "$KCONF" "/tmp/kuma.db.backup.$TS"
|
||||
|
||||
echo "=== 1. 新增临时监控(指向必然连不上的端口) ==="
|
||||
Q "INSERT INTO monitor (name, active, user_id, type, url, interval, retry_interval, maxretries, weight, accepted_statuscodes_json, description) VALUES ('自检 · 临时(验证后自动删除)', 1, 1, 'http', 'http://127.0.0.1:9/', 20, 20, 0, 9999, '[\"200-399\"]', 'Bark 通道端到端验证');"
|
||||
|
||||
TMPID=$(Q "SELECT id FROM monitor WHERE name='自检 · 临时(验证后自动删除)' LIMIT 1;")
|
||||
NID=$(Q "SELECT id FROM notification WHERE name='Bark 手机推送' LIMIT 1;")
|
||||
echo "temp_monitor_id=$TMPID notification_id=$NID"
|
||||
|
||||
Q "INSERT INTO monitor_notification (monitor_id, notification_id) VALUES ($TMPID, $NID);"
|
||||
|
||||
echo ""
|
||||
echo "=== 2. 重启 Kuma 让它加载临时监控并开始探测 ==="
|
||||
sudo docker restart uptime-kuma > /dev/null
|
||||
sleep 20
|
||||
sudo docker ps --filter name=uptime-kuma --format '{{.Names}} | {{.Status}}'
|
||||
|
||||
echo ""
|
||||
echo "=== 3. 等待探测与告警推送(约 60 秒) ==="
|
||||
for i in 1 2 3 4 5 6; do
|
||||
sleep 15
|
||||
ST=$(Q "SELECT status FROM heartbeat WHERE monitor_id=$TMPID ORDER BY id DESC LIMIT 1;" 2>/dev/null)
|
||||
echo " [${i}] 第 $((i*15))s:heartbeat status=${ST:-无}"
|
||||
if [ "$ST" = "0" ]; then break; fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "=== 4. 该临时监控的心跳记录(0=DOWN) ==="
|
||||
Q "SELECT id, status, msg, time FROM heartbeat WHERE monitor_id=$TMPID ORDER BY id DESC LIMIT 5;"
|
||||
|
||||
echo ""
|
||||
echo "=== 5. 通知发送历史 ==="
|
||||
Q "SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '%notification%';"
|
||||
Q "SELECT * FROM notification_sent_history ORDER BY id DESC LIMIT 5;" 2>/dev/null || echo "(无该表或为空)"
|
||||
|
||||
echo ""
|
||||
echo "=== 6. Bark 服务端日志(能看到实际收到的推送) ==="
|
||||
sudo docker logs --tail 25 bark 2>&1 | tail -25
|
||||
|
||||
echo ""
|
||||
echo "=== 7. Kuma 日志中的通知相关行 ==="
|
||||
sudo docker logs --tail 60 uptime-kuma 2>&1 | grep -i -E "bark|notification|error" | tail -15 || echo "(无)"
|
||||
|
||||
echo ""
|
||||
echo "=== 8. 清理临时监控 ==="
|
||||
Q "DELETE FROM heartbeat WHERE monitor_id=$TMPID;"
|
||||
Q "DELETE FROM monitor_notification WHERE monitor_id=$TMPID;"
|
||||
Q "DELETE FROM monitor WHERE id=$TMPID;"
|
||||
echo "--- 清理后剩余监控 ---"
|
||||
Q "SELECT id, name FROM monitor ORDER BY id;"
|
||||
echo "--- 清理后关联数(应为 9) ---"
|
||||
Q "SELECT COUNT(*) FROM monitor_notification;"
|
||||
|
||||
echo ""
|
||||
echo "=== 9. 重启并复核 ==="
|
||||
sudo docker restart uptime-kuma > /dev/null
|
||||
sleep 15
|
||||
sudo docker ps --filter name=uptime-kuma --format '{{.Names}} | {{.Status}}'
|
||||
curl -s -o /dev/null -m 10 -w "panel_http=%{http_code}\n" http://127.0.0.1:3001/
|
||||
echo "DONE"
|
||||
19
.workbuddy/tmp/kuma-final-check.sh
Normal file
19
.workbuddy/tmp/kuma-final-check.sh
Normal file
@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
# 复核:Bark 通知 + 各监控的证书到期通知开关
|
||||
DB=/app/data/kuma.db
|
||||
Q() { sudo docker exec uptime-kuma sqlite3 "$DB" "$1"; }
|
||||
|
||||
echo "=== 通知渠道 ==="
|
||||
Q "SELECT id, name, active, is_default, json_extract(config,'\$.type') AS type, json_extract(config,'\$.barkEndpoint') AS endpoint, json_extract(config,'\$.barkGroup') AS grp FROM notification;"
|
||||
|
||||
echo ""
|
||||
echo "=== 监控 × 证书到期通知开关 ==="
|
||||
Q "SELECT id, name, expiry_notification, interval, maxretries FROM monitor ORDER BY id;"
|
||||
|
||||
echo ""
|
||||
echo "=== 关联数 ==="
|
||||
Q "SELECT COUNT(*) FROM monitor_notification;"
|
||||
|
||||
echo ""
|
||||
echo "=== 当前各监控状态(最近一条心跳) ==="
|
||||
Q "SELECT m.id, m.name, h.status, h.time FROM monitor m LEFT JOIN heartbeat h ON h.id = (SELECT id FROM heartbeat WHERE monitor_id = m.id ORDER BY id DESC LIMIT 1) ORDER BY m.id;"
|
||||
7
.workbuddy/tmp/kuma-type.sh
Normal file
7
.workbuddy/tmp/kuma-type.sh
Normal file
@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
# 确认 providerList 的 key 命名(notification.type 该填什么)
|
||||
echo "=== providerList 构造 ==="
|
||||
sudo docker exec uptime-kuma grep -n -B3 -A12 "providerList" /app/server/notification.js 2>&1 | head -50
|
||||
echo ""
|
||||
echo "=== providers 列表引入 ==="
|
||||
sudo docker exec uptime-kuma grep -n -A40 "require(\"./notification-providers" /app/server/notification.js 2>&1 | head -50
|
||||
16
.workbuddy/tmp/kuma-type2.sh
Normal file
16
.workbuddy/tmp/kuma-type2.sh
Normal file
@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
# 确认前端提交的 notification.type 到底是 "bark" 还是 "Bark"
|
||||
echo "=== NotificationDialog 中 type 的来源 ==="
|
||||
sudo docker exec uptime-kuma ls /app/src/components/notifications/ 2>&1 | head -30
|
||||
echo ""
|
||||
echo "=== 搜 bark 类型常量 ==="
|
||||
sudo docker exec uptime-kuma grep -rn -i "bark" /app/src/components/NotificationDialog.vue /app/src/components/notifications/Bark.vue 2>&1 | head -20
|
||||
echo ""
|
||||
echo "=== 搜 type 列表定义(notification type 下拉) ==="
|
||||
sudo docker exec uptime-kuma grep -rn -i "\"bark\"\|'bark'\|value=\"bark\"" /app/src 2>&1 | head -20
|
||||
echo ""
|
||||
echo "=== 看 init() 里 providerList 赋值的完整上下文(是否 toLowerCase) ==="
|
||||
sudo docker exec uptime-kuma sed -n '220,245p' /app/server/notification.js 2>&1
|
||||
echo ""
|
||||
echo "=== 新增/保存通知时是否校验 type ==="
|
||||
sudo docker exec uptime-kuma sed -n '275,300p' /app/server/notification.js 2>&1
|
||||
Loading…
Reference in New Issue
Block a user