172 lines
7.3 KiB
Markdown
172 lines
7.3 KiB
Markdown
# 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=2`
|
|
- `docker restart telegram-forwarder` (内存刷新)
|
|
- 链路恢复
|
|
|
|
### 8/6 00:50 (后续)
|
|
- 用户要"把链上监控的规则先删了,是不稳定的"
|
|
- 删除 rule 2 + 关联 keywords (孤儿)+ 关联 replace_rules
|
|
- forwarder log 显示 "0 个启用了总结功能的规则"
|
|
- 备份脚本 `forwarder-rules-backup.sh` 自动 commit `4771032`
|
|
|
|
## ⚠️ 用户硬性纠正 (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 反查 |
|
|
|
|
## 修复时用的命令清单 (备查)
|
|
|
|
```bash
|
|
# 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 但未 execute**
|
|
- `references/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 提示
|
|
|
|
如果用户问"信号怎么又没跟了":
|
|
1. **不要假设** 上次/全局 bug
|
|
2. **先 4 层诊断** (本文件表格)
|
|
3. **disable rule 只影响一条 rule**,**不传染** (用户硬纠正)
|
|
4. **删 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 模式 (没主动告警) — 未来需加守护
|