OpenClaw 网关出问题先开哪个开关:日志级别、--verbose 与诊断导出包的分工
网关跑着跑着不对劲——回复变慢、某次工具调用选错了、或者半夜自己重启了一次。这时候第一反应通常是”把日志开大点”,于是加个 --verbose 重启,结果文件日志里该有的细节还是没有,白折腾一轮。
问题出在 OpenClaw 把可观测性拆成了三套互不干涉的东西:控制台输出、文件日志、以及诊断/稳定性记录器。它们各有各的开关,控制台的开关管不到文件,文件的开关也管不到诊断包。官方文档里这三块分散在 /gateway/logging 和 /gateway/diagnostics 两页,单看一页很容易把结论套错地方。
下面按”先分清、再调档、最后打包上报”的顺序过一遍。全部内容以官方文档写明的机制、配置项和命令为准,没写的不推测。
三套东西,三个开关
| 面 | 控制什么 | 开关 |
|---|---|---|
| 控制台输出 | 终端 / Debug UI 里看到的行 | logging.consoleLevel、logging.consoleStyle、--verbose |
| 文件日志 | 网关 logger 写出的 JSON lines | 仅 logging.level(还有 logging.file 指定路径) |
| 诊断与稳定性 | 无载荷的运行事件流、导出 zip | diagnostics.enabled(默认开启) |
记住一句话就够了:--verbose 只影响控制台详细程度和 WS 日志样式,它不会抬高文件日志级别。想在文件里拿到 verbose 那一档的细节,必须把 logging.level 调到 debug 或 trace。这是文档明确点名的一条,也是最容易踩的一条。
顺带一提,trace 档还会带上若干热路径的诊断计时汇总,比如插件工具工厂的准备耗时——如果你怀疑某个插件把启动拖慢了,这是文档指出的观察点。
文件日志写在哪、什么时候滚
默认的滚动日志文件在 /tmp/openclaw/ 下,一天一个文件,日期按网关宿主机的本地时区算。默认 profile 的文件名是 openclaw-YYYY-MM-DD.log,带名字的 profile 会把名字嵌进去,比如 openclaw-dev-YYYY-MM-DD.log。
有两种情况会让路径变掉,排查时找不到文件多半是撞上了它们:
- 那个目录不安全或不可写(属主不对、全局可写、是个符号链接),OpenClaw 会退到用户维度的
os.tmpdir()/openclaw-<uid>; - 在 Windows 上,它总是用上面这个 OS 临时目录兜底路径,不走
/tmp/openclaw/。
活动日志文件在达到 logging.maxFileBytes(默认 100 MB)时轮转,保留最多五份编号归档(.1 到 .5),然后继续往一个新的活动文件里写。所以捞历史时别只看当前那个文件,编号归档里可能才是事发现场。
路径和级别都在 ~/.openclaw/openclaw.json 里配:logging.file 和 logging.level。文件格式是每行一个 JSON 对象,适合直接丢给 jq 之类的工具过滤。
跟随查看用 CLI:
openclaw logs --follow
文档说明 Control UI 的 Logs 页也是通过网关的 logs.tail 拉同一个文件,两边看到的是一份数据。
另外,talk、实时语音和托管房间这几条代码路径也复用同一个文件 logger,写的是有界的生命周期记录,用于运维排查和 OTLP 日志导出;文档写明转写文本、音频载荷、turn id、call id、provider item id 都不会被抄进日志记录。
控制台那一侧怎么调
CLI 会捕获 console.log/info/warn/error/debug/trace,写进文件日志的同时仍然打到 stdout/stderr。控制台的详细程度单独调:
logging.consoleLevel,默认info;logging.consoleStyle,可选pretty或json。不设置时,TTY 下是pretty,否则走自动的compact样式。注意compact已经不是一个可以写进配置的值了,如果你的配置里还留着旧的compact,openclaw doctor --fix会把它映射成pretty。
控制台格式器是 TTY 感知的,每行带子系统前缀(如 [gateway]、[canvas]、[tailscale]),颜色按子系统名哈希稳定分配。是否上色看输出是不是 TTY 或环境是否像富终端(TERM/COLORTERM/TERM_PROGRAM),并且尊重 NO_COLOR 和 FORCE_COLOR。前缀会做缩短:先去掉开头的 gateway/、channels/ 或 providers/ 段,再最多保留最后两段,比如 channels/turn/execution 显示成 turn/execution;已知渠道子系统(telegram、whatsapp、slack 等)直接塌缩成渠道名。二维码这类 UX 输出走 logRaw(),不加前缀也不做格式化。
还有一条排查时有用的细节:WhatsApp 的消息体是打在 debug 级别的,不加 --verbose 看不到。
网关启动时会打一行解析后的默认 agent 模型和影响新会话的模式默认值,形如:
agent model: openai/gpt-5.6-sol (thinking=medium, fast=on)
其中 thinking 取自默认 agent、模型参数或全局 agent 默认值,没设置时显示 medium;fast 取自默认 agent 或模型的 fastMode 参数。怀疑”跑的模型跟我配的不一样”时,先翻这一行,比翻配置快。
WebSocket 协议日志的两档
网关的 WS 协议日志有两个模式:
- 普通模式(不加
--verbose):只打”有意思”的 RPC 结果——错误(ok=false)、慢调用(默认阈值>= 50ms)、解析错误; - verbose 模式:打全部 WS 请求/响应流量。
verbose 下的排版由 --ws-log 决定:
# 只打错误/慢调用
openclaw gateway
# 全部 WS 流量(请求响应配对)
openclaw gateway --verbose --ws-log compact
# 全部 WS 流量(完整 per-frame)
openclaw gateway --verbose --ws-log full
--ws-log auto 是默认值:普通模式走优化输出,verbose 模式用 compact。--compact 是 --ws-log compact 的别名。
排查”某个 RPC 偶发超时”这类问题,普通模式其实已经把慢调用挑出来了,不一定要一上来就全量抓。如果连网关都没起来,那是另一条路径,参见网关起不来时先查锁文件、端口和后台进程。
稳定性记录器:崩溃和卡顿的那条线
诊断默认是开的,网关会记录一条有界的、不含载荷的稳定性事件流,捕获的是运行事实而不是内容。
同一个心跳还会在事件循环或 CPU 看起来饱和时采样存活情况,发出 diagnostic.liveness.warning 事件,带上事件循环延迟、事件循环利用率、CPU 核占比、活跃/等待/排队会话数、当前的启动或运行阶段(已知时)、最近的阶段跨度,以及有界的工作标签。这些事件只有在有工作在等待或排队、或者活跃工作与持续的事件循环延迟重叠时,才升级成网关的 warn 级日志行,否则记在 debug。空闲时的存活采样仍然作为诊断事件记录,但不会单凭自己升级成告警——所以别看到日志里没 warn 就认定一切正常。
启动阶段会发 diagnostic.phase.completed 事件,带挂钟时间和 CPU 计时。嵌入式运行卡住时,如果最后一次桥接进度看起来已经是终态(比如一个原始 response item 或响应完成事件)但网关仍认为该运行是活跃的,诊断会标记 terminalProgressStale=true。
内存压力事件记录 RSS、堆、阈值和增长事实(rss_threshold、heap_threshold、rss_growth),文档写明它不做文件系统扫描,也不写 OOM 前快照。
看实时记录器和事后持久化的包:
openclaw gateway stability
openclaw gateway stability --type payload.large
openclaw gateway stability --json
# 致命退出、关停超时或重启启动失败之后,看最新持久化的那个包
openclaw gateway stability --bundle latest
# 直接把这个包打成诊断 zip
openclaw gateway stability --bundle latest --export
有事件时,持久化的包存在 ~/.openclaw/logs/stability/ 下。会话在重启后还在不在是另一套机制,见网关重启后会话还在不在。
要关掉稳定性记录器和诊断事件收集:
{
diagnostics: {
enabled: false,
},
}
关掉之后 bug 报告的细节会变少,但不影响正常的网关日志。
导出诊断包
OpenClaw 能在本地打一个 .zip,里面是脱敏后的网关状态、健康、日志、配置形状和近期无载荷的稳定性事件。
openclaw gateway diagnostics export
openclaw gateway diagnostics export --output openclaw-diagnostics.zip
openclaw gateway diagnostics export --json
参数表:
| 参数 | 默认值 | 作用 |
|---|---|---|
--output <path> | $OPENCLAW_STATE_DIR/logs/support/openclaw-diagnostics-<timestamp>-<pid>.zip | 写到指定 zip 路径或目录 |
--log-lines <count> | 5000 | 最多纳入多少行脱敏日志 |
--log-bytes <bytes> | 1000000 | 最多检查多少字节日志 |
--url <url> | 无 | 取 status/health 快照用的网关 WebSocket 地址 |
--token <token> | 无 | 取快照用的网关 token |
--password <password> | 无 | 取快照用的网关密码 |
--timeout <ms> | 3000 | status/health 快照超时 |
--no-stability-bundle | 关 | 跳过持久化稳定性包查找 |
--json | 关 | 打印机器可读的导出元数据 |
包里包含 summary.md(给支持看的可读概览)、diagnostics.json(配置、日志、状态、健康、稳定性数据的机器可读汇总)、manifest.json(导出元数据和文件清单)、脱敏后的配置形状与非机密配置项、脱敏日志摘要和近期已编辑的日志行、尽力而为的网关 status/health 快照,以及可用时的 stability/latest.json。
值得注意的是:网关不健康时这个导出仍然有用——status/health 请求失败的话,本地日志、配置形状和最新的稳定性包在可用时照样会被收集。健康检查本身的两套机制差别见health 与 heartbeat 两套健康检查的区别。
聊天里的 /diagnostics
owner 可以在任意会话里发 /diagnostics [note],让网关在本地导出一份可直接粘贴的支持报告。流程是:发 /diagnostics(可带一句简短备注,比如 /diagnostics bad tool choice)→ OpenClaw 发一段前言并要求一次显式的 exec 批准,批准后执行 openclaw gateway diagnostics export --json → 回复本地包路径、清单摘要、隐私说明和相关会话 id。
文档特意提醒:不要用 allow-all 规则来批准诊断。
群聊里 owner 同样能跑 /diagnostics,但导出结果、批准提示和 Codex 会话/线程明细会私发给 owner,群里只看到一条”诊断已私发”的简短通知。如果没有可用的私聊路径,这条命令会失败关闭,并要求 owner 去私聊里执行。
如果当前会话用的是原生 OpenAI Codex harness,同一次 exec 批准还会覆盖一次面向 OpenAI 的反馈上传,内容是 OpenClaw 已知的那些 Codex 线程。这次上传独立于本地那个网关 zip,且只发生在 Codex harness 会话上。批准提示会说明”批准同时也会发送 Codex 反馈”,但不列出具体的 Codex 会话或线程 id。批准之后,回复会列出渠道、OpenClaw 会话 id、Codex 线程 id,以及那些已发给 OpenAI 的线程对应的本地 resume 命令。拒绝或忽略批准,则导出、Codex 反馈上传和 id 列表三件事都不做。
包里保留什么、抹掉什么
官方文档把隐私模型写得很直白:
| 内容 | |
|---|---|
| 保留 | 子系统名、插件 id、provider id、渠道 id、已配置的模式、状态码、时长、字节数、队列状态、内存读数、脱敏后的日志元数据、已编辑的运维消息、配置形状、非机密特性设置 |
| 省略或编辑 | 聊天文本、prompt、指令、webhook body、工具输出、凭据、API key、token、cookie、机密值、原始请求/响应体、账号 id、消息 id、原始会话 id、主机名、本地用户名 |
当一条日志消息看起来像用户、聊天、prompt 或工具载荷文本时,导出只保留”有一条消息被省略了”这个事实加上它的字节数。
即便如此,文档仍建议在人工审阅之前把诊断包当作机密对待:载荷和凭据是按设计编辑掉的,但这个包依然汇总了本地网关日志和宿主机层面的运行状态。
脱敏是全局的,不只在导出时
敏感值脱敏始终启用,策略作用在控制台、文件日志、OTLP 日志记录和会话转写文本这几个出口上——也就是说,匹配到的机密值在 JSONL 行或消息写盘之前就被掩码了。
logging.redactPatterns 是一个正则字符串数组,会覆盖默认值。写法上可以用裸正则字符串(自动加 gi 标志),或者用 /pattern/flags 指定自定义标志。掩码规则是保留前 6 位加后 4 位(值长度 ≥ 18 字符时),更短的值直接变成 ***。默认规则覆盖常见的 key 赋值、CLI 参数、JSON 字段、bearer 头、PEM 块、主流厂商的 token 前缀,以及支付凭据字段名(卡号、CVC/CVV、共享支付 token、支付凭据)。
有几个安全边界是永远脱敏的,不受配置影响:Control UI 的工具调用事件、sessions_history 输出、诊断导出、provider 错误、exec 批准展示、网关 WebSocket 日志。logging.redactPatterns 是在这之上追加部署特有的模式。
什么时候这套东西不够用
几个边界值得先说清楚:
一是诊断包不是链路追踪。它是快照加有界事件流,回答”这个网关此刻和最近处于什么状态”。要把诊断持续流到采集器,文档指的是另一条独立通路——OpenTelemetry 导出,不在本文这两页文档的范围内。
二是关掉 diagnostics.enabled 之后再去回溯就晚了。稳定性事件是运行时记录的,事后开开关补不回来。低配设备上如果确实要省资源,得权衡这一点。
三是日志里没有内容。转写文本、工具输出、prompt 都不会进日志和导出包,所以”复现某次回答为什么这么答”这类问题,靠日志翻不出来,得走会话侧的手段。
四是配置项与 doctor 的关系。openclaw doctor --fix 会顺手把已废弃的 consoleStyle: compact 映射成 pretty,但文档没有把 doctor 描述成日志问题的通用修复器;体检输出怎么逐条对号入座,见doctor 体检输出怎么读。
实际排查时的顺序建议是:先看普通模式下网关自己挑出来的错误和慢调用,不够再把 logging.level 调到 debug(而不是加 --verbose),涉及卡顿和重启就去看 openclaw gateway stability,要交给别人看时才打 diagnostics export。把这四步分开,比一上来全量开日志有效得多。
延伸阅读
- 从头读起:OpenClaw 架构总览:网关、Agent、渠道、节点、插件五层各管什么,出问题该往哪查
- 本专题共 40 篇,完整分组目录见专题页
- OpenClaw 的 health 与 heartbeat 是两回事:一个查网关状态,一个按周期跑 Agent
- OpenClaw 网关重启后会话还在不在?哪些状态能自动恢复、哪些直接消失
本文依据 OpenClaw 官方仓库(github.com/openclaw/openclaw)docs/ 下的官方文档整理,核对日 2026-08-17。
我们没有安装或运行过 OpenClaw,因此不涉及界面外观、操作手感与实测耗时的任何描述;
文中的默认值、命令与配置项均为文档口径,不构成对实际运行结果的保证。
该项目迭代很快,请以仓库最新内容为准。接入即时通讯平台前,请自行确认所在平台的规则与合规要求。