跳转到内容

04-运维 · 01 日志与监控

预计阅读:12 分钟 适用版本:公开稳定包 OpenClaw 2026.5.2;作者端已验证 2026.5.7 · 最后审核:2026-05-09 前置:04-运维/00-健康检查 目标:理清 OpenClaw 几十个日志文件的分类 / 读取顺序 / 轮转策略 / 告警接入


长期运行后,~/.openclaw/logs/ 很容易累积成数十个日志文件、数十 MB 到数百 MB。不分层管理会出现:

  1. 找不到该看哪个 —— 飞书不回复时,gateway.err.log 还是 daily-digest.launchd.err.log?
  2. 磁盘爆 —— 没 rotate 的日志一个月涨到几百 MB
  3. 告警失效 —— ERROR 淹在正常输出里,没人发现
  4. 信息不对称 —— 你看日志 A,agent 只能看到日志 B

按”谁在写 × 记什么”两个维度分:

层代表文件谁写看什么
Gateway 主日志gateway.log / gateway.err.logOpenClaw gatewayagent 对话 / 工具调用 / 错误
Launchd 任务日志*.launchd.log / *.launchd.err.log你配的 cron 脚本定时任务执行结果
维护脚本日志daily-maintenance.log / consolidation.log / backup.log运维脚本自己具体运维动作
告警日志alerts.log / alert-notify.log告警分发脚本发过哪些告警
审计日志audit.log / config-audit.jsonl配置变更钩子谁什么时候改了什么配置
失败报告failure-report-YYYYMMDD-HHMMSS.txt自愈脚本触发时详细事故快照

不要从 gateway.log 开始(文件大、噪声多)。按这个顺序:

第 1 步:alerts.log 或 alert-notify.log
→ 最近一次告警发生了什么?
第 2 步:对应组件的独立日志(如 daily-digest.err.log)
→ 那个告警的来源脚本里出了什么?
第 3 步:gateway.err.log(过滤时间段)
→ 同时间段 gateway 本身有没有异常?
第 4 步:audit.log
→ 那段时间有配置改动吗?

四步走完,90% 的故障能定位。


不轮转 = 系统自毁。作者的 rotate 策略:

文件rotate 策略脚本
gateway.log按大小(10MB)切,保留 5 份logs-rotate.py
gateway.err.log按大小(5MB)切,保留 10 份logs-rotate.py
*.launchd.log按天切,保留 14 天rotate-logs.sh
audit.log / config-audit.jsonl按周切,永久保留归档rotate-weekly-audit.py
#!/bin/bash
# rotate-logs.sh —— 按天切割
LOG_DIR="$HOME/.openclaw/logs"
DATE=$(date '+%Y%m%d')
for f in "$LOG_DIR"/*.launchd.log; do
[ -f "$f" ] || continue
size=$(stat -f %z "$f")
if [ "$size" -gt 1048576 ]; then # > 1MB 才切
mv "$f" "$LOG_DIR/archive/$(basename "$f").$DATE"
touch "$f" # 新文件
fi
done
# 删 14 天前的归档
find "$LOG_DIR/archive/" -mtime +14 -delete

作者用 launchd 每天凌晨 3 点跑一次。

  1. redirect-to-same-file truncate:grep 'pattern' file.log > file.log 会先 truncate,grep 读空。正确:

    Terminal window
    grep 'pattern' file.log > file.tmp && mv file.tmp file.log
  2. rotate 时进程还在写:直接 mv 的话 gateway 的 fd 还指向老文件。正确做法是重启 gateway 或用 copytruncate 风格:

    Terminal window
    cp gateway.log gateway.log.archive
    : > gateway.log # truncate 原文件(fd 仍有效)
  3. audit 日志不能 rotate:这些是合规证据。作者策略是 audit 只归档(移到 archive/ + 打 tar.gz),不删除。


监控:从”看日志”升级到”日志推过来”

Section titled “监控:从”看日志”升级到”日志推过来””

被动看日志在生产系统里行不通。让日志主动告警的两种思路:

每 N 分钟扫描关键日志,匹配告警规则 → 发飞书。

Terminal window
# 伪代码:每 5 分钟
tail -1000 ~/.openclaw/logs/gateway.err.log \
| grep -E 'ERROR|FATAL|OutOfMemory|invalid signature' \
| while read line; do
# 写入 alerts.log
echo "[$(date)] $line" >> ~/.openclaw/logs/alerts.log
# 发飞书卡片
bash ~/.openclaw/scripts/send-alert-card.sh "$line"
done

关键:规则要保守。早期容易把”正常 WARN”也告警,噪声大到没人看。宁愿漏报也不要骚扰警告。

思路 2:事件驱动(更好但更复杂)

Section titled “思路 2:事件驱动(更好但更复杂)”

不扫日志,而是在脚本里主动写告警:

# daily-digest.py 里
try:
result = check_gateway_health()
except Exception as e:
write_alert(level='ERROR', source='daily-digest', msg=str(e))
raise

write_alert 统一写 alerts.log + 触发飞书推送。

好处:源头可控、level 精确。 代价:每个脚本都要集成 write_alert 库。


参考 04-运维/00-健康检查 的三档色:

级别通道示例
🔴 CRITICAL飞书 + 系统通知(osascript)+ 可能的短信Gateway 离线 > 10 分钟、credentials 权限被改
🟡 WARN飞书(淡色卡片)fragments 400+、磁盘 > 5GB
🟢 INFO写 alerts.log 不推送正常心跳、daily-digest 生成完成

不要给自己发绿色通知。记录即可,积累起来用于”这周系统没有异常”的周审报告。


现象:一个故障瞬间触发 50 条告警(每 5 分钟一次 × N 小时)。

抑制策略:

  1. 去重窗口:同一种告警 1 小时内最多发 1 次飞书
  2. 聚合:连续 N 条同类告警 → 升级成”该问题持续中 2 小时”
  3. 收口:问题恢复后发一条”已恢复”,关闭该事件

作者的 alert-notify.log 就记录了每次告警的 dedup key + 发送次数,防止风暴。


audit.log 和 config-audit.jsonl 记录:

  • 谁(哪个 agent)什么时候改了什么配置
  • credentials 的读取记录(不是内容,是”被读了几次”)
  • 派发操作的完整链(main → planner → minsu)

为什么重要:

  • 出事故时能倒查”到底哪一步改坏的”
  • 多 agent 系统里很容易搞不清”谁动了这个文件”
  • 合规 / 安全审计需要

不能删。rotate 只归档,保留 6 个月以上。

config-audit.jsonl 每行一条结构化事件:

{"ts":"2026-04-17T09:30:12+08:00","agent":"main","action":"config.write","target":"openclaw.json","diff_summary":"added feishu.enabled=false"}
{"ts":"2026-04-17T09:30:15+08:00","agent":"main","action":"gateway.restart","trigger":"config.change"}

用 jq 查很方便:

Terminal window
jq 'select(.agent == "main" and .ts > "2026-04-17T00:00:00")' config-audit.jsonl

日志 ≠ 记忆:

日志记忆
系统写的,agent 不直接读agent 主动写,agent 主动读
事件流水,不解释有摘要、有结论、有情感
rotate 会丢理论上永久(除非明确 forget)

什么时候从日志提炼到记忆:

  • 某个故障重复出现 → 把排障路径写进 memory/YYYY-MM-DD-<故障名>.md
  • 某个运维决策有争议 → 写入 shared/MEMORY.md
  • 发现了新的监控指标 → 更新 shared/AGENTS.md 的健康检查章节

这一步作者用 reflector agent 定期自动做。


不要让 ~/.openclaw/logs/ 世界可读:

Terminal window
chmod 700 ~/.openclaw/logs
# 单个敏感文件
chmod 600 ~/.openclaw/logs/audit.log
chmod 600 ~/.openclaw/logs/config-audit.jsonl

为什么:某些日志会意外包含 appId / open_id / 部分响应内容,权限收严是底线。


监控仪表盘(如果你想做得更讲究)

Section titled “监控仪表盘(如果你想做得更讲究)”

可选:把关键指标推到外部(你的设备 / 家里的 NAS / 云)。

方式复杂度适用
daily-digest 卡片低大多数个人用户
自己写 HTML dashboard,定时生成中想看趋势图
Grafana / Prometheus高生产级 / 多机器

作者目前就用 daily-digest 卡片 + 每月手动看一次 audit log 趋势。足够。


检查项怎么验
日志分层ls ~/.openclaw/logs/ | wc -l 应 > 20,各类都有
rotate 正常ls ~/.openclaw/logs/archive/ 应有归档文件
告警路由人为制造一条 ERROR,应在 5 分钟内收到飞书告警
审计日志格式jq '.' config-audit.jsonl | head 应不报错
告警去重连续制造同类 ERROR 3 次,应只收 1 条告警
权限收严ls -l ~/.openclaw/logs/audit.log 应是 -rw-------


本章准确性保证 日志清单、rotate 脚本名、告警分级都基于作者 ~/.openclaw/logs/ 与 ~/.openclaw/scripts/ 的真实文件抽象而来;具体日志数量会随安装包版本、启用的 agent 和定时任务变化。审计日志 JSONL 格式是作者在用的真实结构。


导航:← 健康检查 · 📖 目录 · → 升级流程