7.3 KiB
7.3 KiB
Forwarder Rule 2 Disable Postmortem (2026-08-06 实战)
完整事件链
8/5 17:04 之前
- rule 1 (实盘监控 → 交易信号群) enable=1
- rule 2 (链上监控 → 交易信号群) enable=1
- 一切正常,4 条 chat 4 麻吉/魏神信号入 signal_queue.db (#46-#49)
8/5 17:04 - 8/6 00:40 之间
- rule 2 被某处改成 enable=0(谁改的未确认)
- 期间 chat 4 传来 75+ 条信号(麻吉/狙击手/百分百胜率),全部不转发
- signal_queue.db 之后没新信号(等正确)
- chat 1 实盘监控(rule 1)一直正常 — 6 条消息正常转发
8/5 23:10 (不属于 chat 4 范围)
- chat 1 予与实盘传来 2 条加仓信号
- rule 1 转发成功(forwarder 日志显示)
- 但 signal_queue.db 没入库 — bug 2(未确诊)
8/6 00:31
- 麻吉 ETH 25x 加仓 → chat 4 收到 → rule 2 未启用 → 不转发
- 用户问"币圈跟单的信号怎么都没处理"
8/6 00:40 (排查)
docker logs telegram-forwarder | grep "未启用"→ 关键信号docker exec telegram-forwarder python3 -c "SELECT id, enable_rule FROM forward_rules"→ 看到 rule 2 enable=0- 根因定位:rule 2 被 disable
8/6 00:41 (修复)
UPDATE forward_rules SET enable_rule=1 WHERE id=2docker restart telegram-forwarder(内存刷新)- 链路恢复
8/6 00:50 (后续)
- 用户要"把链上监控的规则先删了,是不稳定的"
- 删除 rule 2 + 关联 keywords (孤儿)+ 关联 replace_rules
- forwarder log 显示 "0 个启用了总结功能的规则"
- 备份脚本
forwarder-rules-backup.sh自动 commit4771032
⚠️ 用户硬性纠正 (2026-08-06) — Mental Model 修复
用户问: "为什么禁用了链上监控,会影响到实盘监控群的状态"
agent 错误假设:可能有一个共享的资源或 queue 在两个 rule 之间,disable rule 2 会阻塞 rule 1
实际真相:
- rule 1 (实盘监控) 和 rule 2 (链上监控) 完全独立
- disable rule 2 绝对不影响 rule 1
- 8/5 23:10 那两条 chat 1 予与实盘加仓 确实成功转发了 (forwarder log 显示),但 signal_queue.db 没入 — 是 下游 process_signal 的 bug,不是 forwarder 的问题
- 用户认为"影响"是因为两段时间信号都断了:8/5 17:04 (rule 2 被 disable) + 8/5 23:10 (chat 1 转发但未入库)
SKILL.md 必须记的教训:
- 规则独立性: forwarder 多条 rule 之间没有隐式依赖,disable 一条不影响其他
- disable 影响范围: forwarder 收到源聊天消息 → 查所有 enabled rule → 匹配源聊天 → 转发。单一 rule 失效 = 单一源聊天失效
- 未来类似问题: 不要急着怀疑"全局 bug",先隔离到具体 chat + rule
信号链路 4 层诊断 (2026-08-06 完整验证)
[TG 源聊天] → [forwarder] → [forwarder 目标群] → [signal_queue.db] → [process_signal] → [OKX API]
Layer 1 Layer 2 Layer 3 Layer 4 Layer 5 Layer 6
每一层都可能断:
- Layer 1: TG 源头没消息 (上游未发布)
- Layer 2: forwarder 未收到 (telethon 鉴权 / 网络 / 容器挂)
- Layer 3: rule disabled (本节 case)
- Layer 4: signal_queue.db 写入失败 (process_signal 异常)
- Layer 5: process_signal 解析失败 (format 错)
- Layer 6: OKX 下单失败 (余额不足 / 币种不支持)
每层有独立诊断:
| Layer | 诊断命令 |
|---|---|
| 1 (TG 源) | forwarder 日志 message_listener 看到 找到源聊天: <chat_name> |
| 2 (forwarder→目标群) | 同上,关键看 处理转发规则 ID: <N> 或 规则 N 未启用 |
| 3 (target→queue) | signal_queue.db vs forwarder log 时间戳 |
| 4 (queue→process_signal) | signal_queue.db status 'done' / 'failed' |
| 5 (signal 解析) | process_signal.py exit code + 推送内容 |
| 6 (OKX) | OKX 持仓 + 余额 + advisor 返回 + execute 反查 |
修复时用的命令清单 (备查)
# 1. forwarder 规则诊断
docker exec telegram-forwarder python3 -c "
import sqlite3
conn = sqlite3.connect('/app/db/forward.db')
for r in conn.execute('SELECT id, source_chat_id, target_chat_id, enable_rule FROM forward_rules').fetchall():
print(r)
"
# 2. 批量 enable 0→1
docker exec telegram-forwarder python3 -c "
import sqlite3
conn = sqlite3.connect('/app/db/forward.db')
conn.execute('UPDATE forward_rules SET enable_rule=1 WHERE enable_rule=0')
conn.commit()
print(f'updated {conn.total_changes} rows')
"
# 3. 删 rule + 关联
docker exec telegram-forwarder python3 -c "
import sqlite3
conn = sqlite3.connect('/app/db/forward.db')
# 删 forward_rules
conn.execute('DELETE FROM keywords WHERE rule_id=:r', {'r': 2})
conn.execute('DELETE FROM replace_rules WHERE rule_id=:r', {'r': 2})
conn.execute('DELETE FROM forward_rules WHERE id=:r', {'r': 2})
conn.commit()
"
# 4. 重启 forwarder 刷新内存
docker restart telegram-forwarder
# 5. 自动备份 + commit
~/.hermes/scripts/forwarder-rules-backup.sh
跟其他 cron / skill 的关系
references/v4.5.39-tg-monitor-forwarder-table-bug-and-cron-disconnects.md— Layer 2 监听器 bug (历史)references/v4.5.40-gateway-inline-hook-and-cleanup-defense.md— Layer 4-5 inline hook 整合references/v4.5.41-signal-queue-done-but-no-order-execute.md— Layer 4-6 done 但未 executereferences/v4.5.42-insufficient-funds-explicit-notify.md— Layer 6 余额不足references/forwarder-rule-enable-killer.md— Layer 3 通用 killer (2026-08-06 主入口)- 本文 (本文件) — Layer 3 完整 postmortem + 4 层诊断框架
未来 session 提示
如果用户问"信号怎么又没跟了":
- 不要假设 上次/全局 bug
- 先 4 层诊断 (本文件表格)
- disable rule 只影响一条 rule,不传染 (用户硬纠正)
- 删 rule 比 disable rule 干净 — 用户偏好 (不稳定的 source 就删)
自动备份 local commit ≠ push
forwarder-rules-backup.sh 用 git push openclaw main try,失败时 commit 留本地。
⚠️ git.hi6k.com URL 没设 remote 权限 → push 失败 → commit 留本地。
修复方向 (本次没做):
- 在 TelegramForwarder/.git/config 加 openclaw remote with token
- 或用 SSH remote (git@git.hi6k.com:mike/TelegramForwarder.git)
- 或自己 fork 一个 GitHub repo,推上去
signal-queue-retry cron 行为
⚠️ signal-queue-retry (a82a3ab0d48d, 每 5 分钟) — 只读 queue 表处理 pending/failed。
如果 queue 表本身就是空的 (因为 forwarder Layer 3 没转发过来) → silently 输出空,没报错。
这一点是这次 8/6 排查最大的坑:
- 用户问"信号怎么没处理"
- signal-queue-retry 一直在跑,一直 silent OK
- 我之前误以为"没信号 = 正常"
- 实际: TG 源头有信号,forwarder 收到,rule disabled,目标群没收到,queue 永远空
以后: cron silent 不等于"正常",要 cross-check forwarder 最近日志看消息是否在 Layer 1-2 收到。
修复补丁确认 (2026-08-06)
- ✅ rule 2 enable=1 (临时恢复)
- ✅ rule 2 删除 (用户要求删除 + 链路稳定)
- ✅ forwarder-rules-backup.sh cron (7bda8bbfa4c9, 每天 03:00) 自动备份
- ✅ forwarder 重启
- ⚠️ push openclaw 失败 (git.hi6k.com 没权限) — commit 留本地
- ⚠️ push_to_qq daemon 状态未知 (没检查)
- ⚠️ signal-queue-retry cron silent 模式 (没主动告警) — 未来需加守护