生成模型:Claude Opus 4.6 (anthropic/claude-opus-4-6) Token 消耗:输入 ~48k tokens,输出 ~6k tokens(本节)
日志系统是 OpenClaw 运行时的"黑匣子"——它记录 Gateway 的每一次请求、每一个通道的连接状态、每一次 Agent 调用的来龙去脉。OpenClaw 基于 tslog 库构建了一套双轨日志架构:文件日志(结构化 JSON)用于事后分析,控制台日志(彩色文本)用于实时监控。
34.1.1 日志框架:tslog(src/logger.ts)
衍生解释 — tslog
tslog 是一个 TypeScript 原生的日志库,特点是零依赖、类型安全、支持结构化日志。与 winston、pino 等流行日志库不同,tslog 的设计理念是"所见即所得"——日志对象的字段类型在编译期就已确定。OpenClaw 使用 tslog 的 hidden 模式(不输出 ANSI 格式),通过自定义 transport 将日志写入文件。
OpenClaw 定义了七个日志级别,按严重程度从高到低排列:
// src/logging/levels.ts
export const ALLOWED_LOG_LEVELS = [
"silent", // 不输出任何日志
"fatal", // 致命错误(进程将退出)
"error", // 错误
"warn", // 警告
"info", // 信息(默认级别)
"debug", // 调试(verbose 模式下启用)
"trace", // 追踪(最详细)
] as const;
tslog 内部使用数字表示级别:fatal=0, error=1, warn=2, info=3, debug=4, trace=5。silent 映射为 +∞,意味着没有任何日志能通过这个阈值。
getLogger() 是获取文件日志实例的统一入口,采用懒初始化 + 缓存模式:
日志文件采用按日滚动策略,文件名格式为 openclaw-YYYY-MM-DD.log:
每次创建新的 Logger 时,自动清理超过 24 小时的旧日志文件:
日志目录固定在 /tmp/openclaw(macOS 上 os.tmpdir() 可能返回用户随机路径,导致 Debug UI 的"打开日志"按钮失效)。
每条日志以 JSON 格式追加到文件:
日志行示例:
外部 Transport 扩展
日志系统支持注册外部 Transport,允许插件将日志转发到第三方服务:
Transport 回调中的异常被静默吞掉——日志永远不能阻塞主流程。
WhatsApp 库 Baileys 期望使用 pino 风格的日志接口。toPinoLikeLogger 将 tslog Logger 适配为 pino 接口:
34.1.2 日志分级与输出(src/logging/ 目录)
OpenClaw 的日志输出分为两条独立的轨道:
子系统日志(Subsystem Logger)
OpenClaw 的子系统日志是日志系统最精巧的部分——它为每个模块(如 discord、telegram、gateway/ws)创建独立的带前缀日志实例:
子系统名称支持层级结构("gateway/ws"、"agent/embedded"),child() 方法创建子日志实例。
控制台输出中,每个子系统使用不同的颜色以便区分:
Console Capture — 控制台劫持
enableConsoleCapture() 是 CLI 启动流程中的关键一步——它劫持 console.log/info/warn/error/debug/trace,将所有控制台输出同时写入文件日志:
特殊处理:
噪音抑制:非 verbose 模式下,"Closing session:"、"Opening session:" 等高频消息被静默
EPIPE 处理:管道断裂(EPIPE)错误被静默吞掉,而不是导致进程崩溃
RPC/JSON 模式:routeLogsToStderr() 将所有控制台输出重定向到 stderr,保持 stdout 干净(用于 --json 输出)
时间戳前缀:可配置自动添加时间戳前缀(排除已有时间戳和 JSON 内容)
日志系统内置了一套正则表达式驱动的敏感信息脱敏引擎:
脱敏策略:保留 Token 的前 6 位和后 4 位,中间用省略号替换:
PEM 私钥块保留首尾行,中间替换为 …redacted…。
脱敏有两种模式:"tools" 模式(默认)只处理工具输出中的敏感信息;"off" 模式则完全关闭脱敏。
34.1.3 WebSocket 日志(src/gateway/ws-log.ts)
Gateway 的 WebSocket 通信会产生大量日志——每次 RPC 调用、每条消息广播、每个连接事件都需要记录。ws-log.ts 提供了一套专门的 WebSocket 日志格式化工具。
formatForLog() 把任意值安全地转换为日志友好的字符串,长度限制在 240 字符以内,并自动脱敏:
WebSocket 消息里频繁出现的 UUID 会被缩写为 前8位…后4位 格式:
WebSocket 日志使用 "gateway/ws" 子系统标识,在控制台上显示为 [ws](gateway 前缀会被自动剥离)。
tslog 基础:OpenClaw 使用 tslog 作为日志框架,hidden 模式运行(不输出 ANSI),通过自定义 Transport 将 JSON 日志追加到文件
七级日志:silent → fatal → error → warn → info → debug → trace,默认级别 info,verbose 模式下控制台提升到 debug
双轨输出:文件轨道(JSON 格式、按日滚动、24h 自动清理)和控制台轨道(pretty/compact/json 三种样式、子系统颜色编码)
子系统日志:createSubsystemLogger("discord") 创建带前缀的日志实例,支持层级结构和子系统过滤,控制台颜色通过名称哈希分配
Console Capture:劫持全局 console.* 方法,同时写入文件日志,支持噪音抑制、EPIPE 容错和 stderr 重定向
敏感信息脱敏:正则表达式引擎自动识别 API Key、Token、密码等敏感字段,保留首尾字符并替换中间部分
WebSocket 日志:专用格式化工具限制输出长度、缩写 UUID、自动脱敏,使用 gateway/ws 子系统标识