深入解析 OpenClaw如何通过 ws-log.ts 模块实现高效、可读、低开销的 WebSocket 日志系统
关键词:WebSocket 日志|耗时追踪|紧凑模式|结构化日志|终端友好|性能优先
在 OpenClaw 的多端架构中,WebSocket 是 Web UI 与后端通信的核心通道。每秒可能有数十条 ACP(Agent Communication Protocol)消息穿梭其间——包含用户输入、AI 响应、工具调用、审批请求等。
若直接打印原始 JSON,日志将迅速变成不可读的噪音海洋:
{"method":"chat.sendMessage","params":{"sessionKey":"web_abc","content":"重启服务"}}
{"method":"tool.call.request","params":{"runId":"r-xyz","tool":"bash_exec","args":{"cmd":"kubectl...}}}
为解决这一问题,OpenClaw 设计了 src/utils/ws-log.ts —— 一个智能、自适应、终端友好的 WebSocket 日志器。它不仅记录事件,更通过耗时追踪、动态过滤与视觉编码,让日志真正“可读可用”。
本文将详解其三大核心机制:
- 耗时追踪:自动计算请求-响应延迟
- 紧凑模式:仅慢查询/错误才详细记录
- 颜色与图标:✓ ✗ ← → 提升终端可读性
一、设计哲学:日志不是数据 dump,而是人机界面
ws-log.ts 遵循三条原则:
- 默认简洁:正常流量不刷屏
- 异常突出:错误/延迟自动高亮
- 上下文保留:关键信息一眼可见
少即是多,慢即是警。
二、机制一:耗时追踪 —— 自动计算请求-响应延迟
ACP 协议天然具备请求-响应对特性(如 tool.call.request → tool.call.result)。ws-log.ts 利用此特性自动追踪耗时。
实现:请求 ID 映射表
// ws-log.ts
const pendingRequests = new Map<string, { method: string; start: number }>();
export function logOutgoing(message: ACPMessage) {
if (message.id && isRequestMessage(message)) {
pendingRequests.set(message.id, {
method: message.method,
start: Date.now()
});
}
// ... 打印发出日志
}
export function logIncoming(message: ACPMessage) {
if (message.id && pendingRequests.has(message.id)) {
const req = pendingRequests.get(message.id)!;
const duration = Date.now() - req.start;
// 打印带耗时的响应日志
printLog('←', `${req.method} [${duration}ms]`, 'dim');
pendingRequests.delete(message.id);
}
// ... 其他消息处理
}
输出示例
→ tool.call.request (runId=r-abc)
← tool.call.result [2450ms] # 自动标注耗时
无需埋点,自动获得性能洞察。
三、机制二:紧凑模式 —— 慢查询才记录详情
为避免日志爆炸,ws-log.ts 默认启用 Compact Mode:
规则

阈值配置
const SLOW_THRESHOLD_MS = 1000; // >1s 视为慢
示例对比
紧凑模式(默认)
→ chat.sendMessage (web_abc)
→ tool.call.request (r-xyz)
← tool.call.result [2450ms] ✗ # 因超时被记录
详细模式(调试开启)
→ chat.sendMessage {"sessionKey":"web_abc","content":"重启"}
→ tool.call.request {"runId":"r-xyz","tool":"bash_exec",...}
← tool.call.result {"runId":"r-xyz","error":"Command failed",...}
只在需要时,才展示细节。
四、机制三:颜色与图标 —— 终端视觉编码
ws-log.ts 使用 ANSI 颜色与 Unicode 图标,大幅提升可扫描性:
视觉语义系统

实现(使用 chalk)
import chalk from 'chalk';
function printLog(
arrow: '→' | '←',
message: string,
status?: 'success' | 'error' | 'slow'
) {
const color = arrow === '→' ? 'blue' : 'green';
let icon = '';
if (status === 'success') icon = ' ✓';
if (status === 'error') icon = ' ✗';
if (status === 'slow') icon = chalk.yellow(' [SLOW]');
console.log(chalk[color](`${arrow} ${message}${icon}`));
}
实际输出(带颜色)
→ chat.sendMessage (web_abc)
→ tool.call.request (r-xyz)
← tool.call.result [2450ms] ✗ ← 红色 "✗" + 黄色 "[2450ms]"
一眼识别流向、状态与性能瓶颈。
五、结构化后备:JSON 日志用于机器分析
尽管终端日志高度可读,ws-log.ts 同时输出结构化 JSON 到文件,供 SIEM 或日志系统消费:
// ws-log.jsonl
{"direction":"out","method":"chat.sendMessage","timestamp":1710234567,"sessionId":"web_abc"}
{"direction":"in","method":"tool.call.result","duration":2450,"error":true,"runId":"r-xyz"}
- 终端:给人看(美观、简洁)
- 文件:给机器看(完整、结构化)
人机各取所需。
六、性能与资源控制
1. 零内存泄漏
pendingRequestsMap 定期清理超时请求(>30s)- 使用 WeakMap 替代(若适用)
2. 低 CPU 开销
- 日志格式化仅在
process.env.NODE_ENV !== 'production'时启用 - 生产环境默认关闭 WebSocket 日志(可选开启)
3. 可配置级别
# 仅错误
LOG_LEVEL=error npm start
# 详细模式
WS_LOG_VERBOSE=1 npm start
七、开发者体验:一键开启调试
在 Web UI 中点击“调试模式”,自动发送 ACP 指令:
{
"method": "system.setLogLevel",
"params": { "level": "verbose", "duration": 300 } // 5 分钟
}
后端动态调整 ws-log.ts 行为,无需重启。
调试随需启停,生产保持安静。
结语:可观测性是信任的桥梁
ws-log.ts 的存在,体现了 OpenClaw 对开发者的尊重:我们不仅构建系统,更构建理解系统的工具。通过将枯燥的协议流转化为富有语义的视觉叙事,它让每一次交互都可追溯、可理解、可优化。
在 AI 系统日益复杂的今天,良好的可观测性不是奢侈品,而是安全与效率的基石。
在下一篇中,我们将探讨 OpenClaw 的测试体系:如何对非确定性 AI 系统进行确定性验证。
下一篇预告:
第 20 篇:从零部署 OpenClaw —— 实战:接入 WhatsApp + 创建自定义 Skill
您的 AI 助手,从此由您定义。若感兴趣可以浏览本书其他章节内容:
第 1 篇:OpenClaw 是什么?—— 工业级 AI 智能体网关的定位与愿景
第 2 篇:三位一体架构详解 —— 网关层、协议层、智能体系如何协同工作
第 3 篇:ACP 协议设计哲学 —— 为什么 OpenClaw 选择自研 Agent Client Protocol
第 4 篇:启动与配置体系 —— openclaw.mjs、config.yaml 与环境变量管理
第 5 篇:run.ts 上篇 —— 模型调度、账号轮询与上下文守护机制
第 6 篇:run.ts 下篇 —— 故障转移、重试策略与结果封装
第 7 篇:记忆系统基石 —— memory-search.ts 中的 RAG 配置解析与合并逻辑
第 8 篇:向量检索实战 —— OpenClaw 如何实现混合搜索(向量 + 全文)
第 9 篇:长期记忆与会话同步 —— 如何让 AI “记住”跨天对话
第 10 篇:exec.ts 上篇 —— 安全执行 Shell 命令的三层隔离模型
第 11 篇:exec.ts 下篇 —— 用户审批、后台任务与权限提升控制
第 12 篇:process.ts —— AI 如何像开发者一样管理后台进程
第 13 篇:安全边界设计 —— OpenClaw 如何防范 AI 滥用系统权限
第 14 篇:server-channels.ts —— 渠道插件生命周期管理器
第 15 篇:WhatsApp 深度集成 —— session.ts 与 Baileys 的健壮连接管理
第 16 篇:消息流入中枢 —— monitor-inbox.ts 如何解析、去重与防抖
第 17 篇:聊天 RPC 接口 —— chat.ts 中的历史查询、发送与中止逻辑
第 18 篇:Skills System —— 为什么“文档即工具”是 OpenClaw 的扩展灵魂
第 19 篇:可观测性工程 —— ws-log.ts 如何让 WebSocket 日志可读可用
第 20 篇:从零部署 OpenClaw —— 实战:接入 WhatsApp + 创建自定义 Skill
浙公网安备 33010602011771号