起因
OpenClaw gateway 跑在 systemd / nohup 里。什么时候被重启过,我永远不知道。
更尴尬的是:有时候 gateway 已经在重启了,agent 那边卡住,我给飞书发消息没反应,我去翻日志才发现”哦,gateway 3 分钟前被 OOM 杀掉了”,已经重启完了。
折腾了几次之后我学乖了:不要去翻日志,要让 gateway 自己告诉我。重启的那一刻,飞书里直接冒一张卡。
它解决的问题
gateway-lifecycle 是个独立插件(不依赖任何其他 OpenClaw 插件),挂两个官方钩子:
gateway_start→ 启动时发 🟢 “网关已上线” 卡(含本次启动时间 + 上次启动时间)gateway_stop→ 关闭时发 🔴 “网关正在关闭” 卡(5 秒超时,最佳努力)
是的,就这点事,两个钩子、两张卡。
效果:
🔴 网关正在关闭
─────────────────────
关闭时间: 2026-06-07 12:19:54 UTC
OpenClaw gateway 收到关闭信号,准备退出。
进程退出期间 agent 不会处理新消息;下次启动时会再发"上线"通知。
─────────────────────
来自 gateway-lifecycle 插件
🟢 网关已上线
─────────────────────
本次启动: 2026-06-07 20:19:08 UTC
上次启动: 2026-06-07 20:01:43 UTC
─────────────────────
OpenClaw gateway 重新就绪,agent 可正常接收消息。
─────────────────────
来自 gateway-lifecycle 插件
重启那一刻,你飞书里立即可见。再也不用去翻 journalctl 或手 tail 几百行日志。
“独立” 是核心设计
我同时还在用 feishu-progress-card(推 agent 任务进度的插件),但这两个插件必须完全解耦。别人可能只想要”网关上/下线通知”,不想装任务进度;反之亦然。
所以 gateway-lifecycle:
- 不读
feishu-progress-card的 state 文件 - 自己维护路由表:
~/.openclaw/gateway-lifecycle.routes.json(30 分钟 TTL) - 自己注册
message_received钩子,把每个飞书会话的sessionKey → {conversationId, receiveIdType}记下来 - 启动 / 关闭时,只用自己路由表里的活跃会话作为收件人
装一个就工作。装两个也工作(各管各的)。互不打扰。
装它解决的实际痛点
🅰️ “agent 不理我了”排查时间——从翻日志降到 0 秒。飞书有没有”网关正在关闭”卡,一眼看到。
🅱️ 记录 gateway 稳定性——飞书聊天窗就是天然的时间线,重启历史一目了然。
🅲️ 开发期反复 pkill 重启不焦虑——每杀一次都有人告诉你”它已经回来”,不用去 tail journalctl 赌运气。
🅳️ 生产环境故障复盘——配合 systemd journal,能精确到秒知道”什么时候崩了、什么时候起”。
安装
openclaw plugins install ./gateway-lifecycle-0.1.0.tgz
openclaw.json:
{
"channels": {
"feishu": {
"appId": "cli_xxxxxxxxxxxxxxxx",
"appSecret": "***"
}
},
"plugins": {
"entries": {
"gateway-lifecycle": {
"enabled": true,
"hooks": { "allowConversationAccess": true }
}
}
}
}
重启 gateway 之后,先给 agent 发条消息(这一步让 message_received 钩子把你的 session 注册到路由表里),再重启一次 gateway。飞书里就该出现 🟢 网关已上线 卡。
⚠️ 装完第一次启动不会发卡(路由表是空的),重启第二次才会有。文档里有写。
一些设计取舍
“重启前” vs “重启后” 通知
我只做了”重启后”(gateway_start)和”关闭时”(gateway_stop)。“重启前”理论上能通过 systemd 的 ExecStopPre= 触发 HTTP 来做,但那要求你用 systemd,而我 OpenClaw 是 nohup 跑的,没有统一方案。所以 plugin 只能 hook 它能 hook 的时机,剩下的你别指望它。
“关闭” 卡能成功吗?
gateway_stop 钩子在 OpenClaw 真正退出之前触发,能跑几秒代码。我把发卡严格卡在 5 秒以内,超时 plugin 就静默退出,不阻塞 gateway 关闭。理论上你应该能看到 🔴 网关正在关闭,但如果断电或者 kill -9,那 plugin 也没辙:进程直接没了,钩子根本没机会跑。
“重启用什么信号”
OpenClaw 内部用 SIGTERM 触发 gateway_stop。SIGKILL(即 kill -9)不触发任何钩子,OS 直接杀进程,啥通知都收不到。所以别用 kill -9 重启 gateway,要用 pkill -TERM 才会看到那张”关闭”卡。