Repository navigation
feat: 掉线、流量、到期与登录通知(Telegram / Webhook) - #10
Merged
Merged
Conversation
- 事件:节点离线/恢复(按节点开关,默认关,后台可批量打开)、本期流量
达到阈值与 100%、每天 9 点的到期汇总与自动续期、后台登录成功
- 渠道:Telegram 与 Webhook 可同时启用。每个渠道一个模板,占位符
{{title}} {{message}} {{node}} {{event}} {{site}} {{time}},后台实时预览;
Webhook 请求体保存时校验代入后是合法 JSON
- 防风暴:每轮巡检合并为一条;1 小时内有过超过宽限期掉线的节点,下一次
掉线满 30 分钟才报;一条最多列 20 台节点
- 离线从 hub 发现断开时计时,与 agent 上报间隔无关;已报离线的状态落库,
hub 重启不重发,恢复照常补发;未配置渠道时不标记
- 投递:单队列串行,仅对连接错误、5xx、429 重试;不跟随跳转,避免 POST
被改成 GET 以及凭证头被带到其它主机;错误信息去掉 URL
- bot token、Webhook URL 与请求头只写不回读
- schema 升到 4:node 表新增 notify、down_since
3 tasks done
标题行显示「已配置 / 未配置」,点击或回车展开。用原生 details,与节点 弹窗的「流量校正」一致。
agent 单元在换掉 DynamicUser= 时明写了这一项,hub 单元一直没有,两边的 提权约束因此不一致。hub 同样不创建 setuid/setgid 文件,加上它没有代价。
apply() 原先是 for await 串行,N 台节点就是 N 个首尾相接的往返;节点列表
又由 WebSocket 每 2 秒推一次全量,中间状态因此被逐帧渲染成一台一台打开。
改为 Promise.all。8 台节点、模拟 100 ms 往返下实测:8 个 PUT 的发出时刻由
40/121/234/351/465/667/679/789 ms 收敛到 53–58 ms,最后一个响应由 894 ms
提前到 247 ms。
未加批量端点:PUT /nodes/{id} 是节点弹窗每个字段共用的写入路径,再加一条
只写 notify 的路由会让同一列有两个写入口。节点上百时再议。
kofwj
added a commit
to kofwj/monitor
that referenced
this pull request
Sep 16, 2026
一个节点一个开关,关掉的完全不参与告警判断。上游 notify.rs 有这个能力而本地 alerts.rs 没有,代价是临时节点和还在调试的机器只能靠把整条规则关掉来消音 —— 那是把所有节点一起关掉。 存成 setting 表的 alert_muted_nodes(逗号分隔的节点 id),**不动 schema**, SCHEMA_VERSION 保持 4。加列会撞上上游 PR monitor-probe#10 的 node.notify(他们也是往 node 上加列),而按节点静音用一张 id 列表就够。存 id 不存名字:节点可以改名,跟着 名字走的静音会转移到接管了这个名字的节点上。 静音的节点不是「判为安静」,而是根本不判。这两件事的差别在解除静音的那一刻: 判为安静会写下 alert_state 那一行,而正是这一行让下一轮不播报 —— 于是静音 期间真的停机了,解除后也不会说。所以静音节点每轮把它的行删掉,解除后立刻 报告当前成立的情况。这也是规则被关掉时已有的做法(`forget_alerts`),只是 换成一个节点的粒度。 开关写在页面上即时生效,不放在「保存」按钮后面:一个要等别的按钮才动作的 开关,是一个会被留在错误位置的开关。 验证:cargo fmt --check / clippy --all-targets -D warnings / test 全过 (131 passed,新增 3 条:mute 列表的接受与拒绝、静音节点不记录且解除后立刻 播报、静音一个不影响其他节点);oxlint 0 warning;npm run build 通过。 另起真实进程走了一遍 面板 → API → 数据库:PUT 1,2 后 GET 读回 1,2, "web" / "1,,2" / "0" 均被 400 拒绝(中文提示),清空读回空串。
kofwj
added a commit
to kofwj/monitor
that referenced
this pull request
Sep 16, 2026
除 Telegram 之外再推一份到任意 HTTP 地址。设置键两个:`alert_webhook_url` 与 `alert_webhook_headers`(逐行 `Name: value`,覆盖 Gotify / n8n / Home Assistant 这类要 token 的目标)。请求体固定为 JSON,不做模板:`hub` 是站点名,`text` 是 整条消息,`lines` 是拆开的分组。模板是上游 PR monitor-probe#10 的做法,但存进去的 JSON 写错 只在发送时才炸;这里宁可少一个自由度,换「对面不必按换行猜哪半截是节点名」。 为此把渲染与投递拆开:`render` 出结构化的 `(heading, line)`,`compose` 按渠道 出 Telegram 的 HTML 或纯文本。顺带修掉 `render` 里一处算错的权重:分片之后新 消息会重新写一次标题,原来的推算没算进去,于是消息可能超过 `BUDGET` —— 而 Telegram 会拒收,hub 就会一直重试同一条。 投递语义变了,这是有意的:**任一渠道收下即视为已投递**,只有所有渠道都没收下 才留着下一轮重试。若按「全部成功才算」,一个配错的 webhook 会让已经发到 Telegram 的告警每 30 秒重发一次,把一次停机变成刷屏 —— 比第二个渠道漏收更糟。没收下的 渠道连名带错写进日志,那才是修它的地方。 同时修正 `db.rs` 中 `migrate_to_4` 的注释:它仍把 PR monitor-probe#10 写成 unmerged,而该 PR 已于 2026-09-16 合入上游。schema 版本号仍保持 4 不动 —— 本 fork 尚未合并上游, 两个 `migrate_to_4` 还没见面。 验证:138 个测试全绿(新增 6 个);另跑真实进程的端到端 —— 起 hub、登录、写设置、 点测试按钮,确认 mock 收到的请求头与 JSON 载荷;地址缺 scheme、请求头缺冒号都被 400 拒掉;地址指向死端口时 502 点名 Webhook 且错误里不带 URL(webhook 的凭据常在 query 上);日志里没有凭据。
CarlJia
referenced
this pull request
in CarlJia/monitor
Sep 16, 2026
独立评审(7 路本地 + codex 对抗尝试)后的修复。P0/P1 全部经独立校验器确认。 阻断项: - #1/#4 wasm 在运行时上下文里被同步调用,宿主函数里的嵌套 block_on 会 panic;release 档 panic=abort 直接终止进程,启用财务插件即崩。 call_hook/call_json_hook 补 block_in_place(与 run_one 同一形态), call_plugin_json 去掉多余的外层 block_on。新增 run_blocking:只在多线程 运行时上包一层,纯同步/单线程路径直接跑。 - #2 SSRF 预检只覆盖首个 URL,而共享 client 默认跟随重定向(含 https->http 降级),任一公网开放重定向即可绕过。新增 App::plugin_http (Policy::none()),插件出网与宿主隔离。 - #7 注册表读锁横跨插件执行,插件回头发事件重入同一把锁会死锁。 dispatch_ticks/call_json/dispatch_one 改为只在取快照时借锁。 迁移与数据边界: - #5 删列闸门按 plugin_id 限定(不再被第三方插件的 node: 前缀打开)。 - #15 四条 DROP COLUMN 收进一个事务,完成判据与待删清单同源。 - #16 Db::open 补 version > SCHEMA_VERSION 守卫(与 check_backup 一致)。 - #17 GATED_VERSION 用绝对常量,不再随 SCHEMA_VERSION 漂移。 - #6 删列前记一行非默认值行数,运维在日志里看得到这次丢了什么。 - #18/#23 plugin_data 配额统一按字节,检查与写入同一事务(BEGIN IMMEDIATE)。 - #20 无到期字段的插件事件按 payload 内容哈希(FNV-1a)定键,不再永久去重。 - #21/#22 SSRF 预检的 DNS 解析与请求超时都按剩余预算收缩。 - #24 data_list/nodes_query 用各自的上限,放不下报 -6 而不是静默截断。 契约与文档: - #13/#14 插件端点先判加载状态(400)再判能力声明(404);错误体统一纯文本。 - #8/#9/#29 README 的 nodes_query 字段、data_list 格式、tick 周期按实现改写。 - #26 表单控件按字段名推断的规则写进协议(#27 同步修掉清空价格存成 0)。 - #25 破坏性 ABI/API 变更按 SemVer 升到 2.0.0,README 补升级说明。 - #28 tg-notify 错误码表补 -9 对应的 19。 测试与 CI: - #10 删除空测试体;#11 nodes_query 测试播种节点并断言在线状态。 - #19 插件 crate 接进 CI(独立 crate,根 cargo test 覆盖不到)。 - #12 插件区分「宿主查询失败」与「确实没有节点」,清理拿不到存活集合拒删。 - #3 抽出 plugin_http_fetch,http_post/http_get 不再逐行重复。 验证:hub 166 passed;finance-stats 8;tg-notify 3;web-admin build+lint。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
liz963
added a commit
to liz963/monitor
that referenced
this pull request
Sep 16, 2026
通知实现整体改用 monitor-k 的版本:PushPlus 与 SMTP 为新增渠道,连同上游的 Telegram、Webhook 共四个,每个渠道一个开关、全部挂在总开关之下,只在该渠道最 小配置齐备时才调用;单渠道失败只记一条 warn,不影响其他渠道和主进程。上游那套 「队列 + 重试 + 模板 + 防风暴 + 每日摘要」的通知器(notes 通道、 deliver/watch/expiry_digest/renewed 与 /api/notify/test)整体移除,节点上下线 改由 spawn_node_watcher 按 120s 心跳窗口判定。 随之不再有「按节点开关」的通知语义:node.notify 与 node.down_since 两列保留在 schema 里、migrate_to_4 一字未动,好让已经 stamped 4 的库不必在新含义下重跑一 次;但 Rust 侧不再读写它们,Node/NodePatch 的字段与 set_down_since 一并删除。 顺带并入上游 monitor-probe#10 对 install-hub.sh 的加固:RestrictSUIDSGID=yes。 注:本提交里 auth.rs 暂时摘掉了登录通知的调用点,由随后的「密码账号与登录审计」 提交以 login_notice 的形式重新接回。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
新增通知功能,全部在 hub 侧完成,agent 与主题不需要升级,无新依赖。后台新增「通知」页。
事件
渠道与内容
{{title}}{{message}}{{node}}{{event}}{{site}}{{time}},后台实时预览;Webhook 请求体保存时校验代入后是合法 JSON防通知风暴
模拟一小时(真实巡检函数 + 虚拟时钟):
可靠性与安全
--interval无关(上报间隔 300 秒的 agent 重启几秒不会误报)node.down_since),hub 重启不重发、恢复照常补发;未配置任何渠道时不标记数据库
schema 升到 4:
node表新增notify、down_since,旧库启动时自动迁移。顺带
install-hub.sh的单元补上RestrictSUIDSGID=yes,与 agent 单元一致(#8 在换掉DynamicUser=时明写了这一项,DynamicUser=原本隐含它;hub 从未有过)。与通知无关,一行,搭这趟车。测试
cargo test(97 个)、cargo clippy --all-targets零警告、cargo fmt --checkweb-admin:npm run lint、npm test、npm run build--interval 300的 agent 断开 79 秒后才报(宽限期 1 分钟)systemd-analyze security --offline=true比对 hub 单元前后,差异只有RestrictSUIDSGID=