本文是 OpenClaw教程 系列的可观测性实战篇,围绕日志规范、指标埋点与链路追踪给出可落地方案:统一 trace_id/request_id、结构化日志字段、核心指标清单与维度控制、span 设计与异步链路贯通,并提供从告警到定位的排障流程与常见坑位。
为什么在 OpenClaw 项目里先把“可观测性”做对
在实战项目中,可观测性(Observability)不是“上线后再补”的装修,而是从第一天就该设计进系统的基础能力。对 OpenClaw 这类可能包含网关、任务编排、模型/工具调用、异步队列、存储与多租户的系统来说,常见故障往往不是“服务挂了”,而是:
- 某一类请求变慢、但整体 QPS 不高
- 某个工具调用失败率升高、只影响部分用户
- 异步任务堆积、但接口仍然 200
- 模型响应波动、成本突然升高
要解决这些问题,必须把日志(Logs)、指标(Metrics)、链路追踪(Tracing)三件套统一起来,并且让它们之间能“互相跳转”:
- 从指标告警定位到具体的 trace
- 从 trace 反查到相关日志
- 从日志中的 request_id / trace_id 还原整条调用路径
本文将以“OpenClaw可观测性实战”为中心,给出可落地的规范与埋点方式,重点解决:日志怎么写才可检索、指标埋点埋什么、链路追踪怎么串起来。
一、统一基础:OpenClaw 的可观测性约定(强烈建议先落地)
在动手埋点之前,先把几个全局约定定下来,否则后面会出现“日志字段对不上、trace 串不起来、指标维度乱飞”的问题。
1.1 统一三类 ID:trace_id / span_id / request_id
- trace_id:一次端到端请求(或一次任务)的全链路唯一标识
- span_id:链路中的一个调用片段(如一次 DB 查询、一次工具调用)
- request_id:更偏业务侧的请求标识(如网关生成或前端传入),可与 trace_id 不同,但要能关联
建议:
- Web 请求进入(HTTP/gRPC)时若上游已有
traceparent(W3C 标准),则沿用 - 若没有,则在入口生成新的 trace
request_id可以用短 ID(例如 ULID/UUID 的短格式),用于日志快速肉眼定位
1.2 统一错误分类:error_type + error_code
不要只打 “failed”,建议最少两级:
error_type:例如validation_error/tool_timeout/model_rate_limit/db_errorerror_code:更细的稳定枚举,如TOOL_HTTP_504/MODEL_429/DB_CONN_RESET
这能让指标和告警更稳定,避免靠字符串模糊匹配。
1.3 统一“资源命名”:service.name / deployment.environment
建议在 OpenTelemetry 资源(Resource)层统一:
service.name:openclaw-api,openclaw-worker,openclaw-gatewaydeployment.environment:dev/staging/prodservice.version: Git SHA 或版本号
这些会直接影响指标、trace 在平台中的聚合方式。
二、日志规范:让日志可检索、可聚合、可回溯
日志的目标不是“记录发生过什么”,而是让你在 30 秒内回答:谁(用户/租户)在什么时候因为哪个组件的什么原因失败/变慢。
2.1 采用结构化日志(JSON),避免纯文本堆砌
推荐每条日志至少包含以下字段(可按你语言栈调整):
timestamp:ISO8601level:INFO/WARN/ERRORservice:服务名(或从 OTel Resource 注入)env:环境trace_id/span_idrequest_idtenant_id/user_id(有多租户/用户体系时强烈建议)operation:操作名(如agent.run,tool.call,workflow.execute)message:简短可读的信息duration_ms:耗时(适用于关键步骤)status:ok/errorerror_type/error_code/error_message
示例:一次工具调用的成功日志
operation:tool.calltool.name:web_searchtool.endpoint:https://...duration_ms: 243
示例:一次模型调用的失败日志
operation:model.generatemodel.provider:openaimodel.name:gpt-4.1-minierror_type:model_rate_limiterror_code:MODEL_429
2.2 日志分层:业务事件日志 vs 调试日志
建议至少两类:
1) 业务事件日志(Event Log):少而精、稳定字段、用于审计与排障
- 例如:任务开始/结束、工作流状态变化、工具调用结果摘要
2) 调试日志(Debug Log):只在开发或灰度时打开
- 例如:prompt/输入参数、长文本中间态
建议把 prompt/用户输入等敏感内容默认不落盘,如必须记录,需脱敏与权限隔离。
2.3 日志脱敏清单(OpenClaw 场景常见)
强烈建议在日志中禁止直接输出:
- API Key、Token、Cookie、Authorization
- 用户手机号/邮箱/身份证号
- 完整 Prompt(尤其包含用户隐私或企业数据)
- 原样工具返回(可能含敏感信息)
可采用策略:
- 对敏感字段打
*** - 对长文本只记录 hash(例如
prompt_hash)与长度(prompt_len) - 对工具返回只记录摘要(前 200 字)或结构化字段(
result_count、http_status)
2.4 让日志与 Trace 互相跳转:写入 trace_id
当链路追踪启用后,建议在日志输出时自动注入 trace_id/span_id。这样你在日志平台里搜到某条报错日志后,可以直接跳到对应的 trace,看上下游耗时与依赖。
落地建议:
- Web 框架中间件:从当前上下文读取 trace 信息,注入日志 MDC(Mapped Diagnostic Context)
- 异步任务:在入队消息中携带
traceparent或自定义trace_id字段,并在 worker 消费时恢复上下文
三、指标埋点:把“坏了/慢了/贵了”量化成可告警的信号
指标的关键不是越多越好,而是:能指导行动。在 OpenClaw 里,建议围绕四类信号建指标:
- 流量:多少请求/多少任务
- 延迟:哪里慢
- 错误:哪里失败、失败类型是什么
- 成本:模型 token、工具调用次数与费用
3.1 你应该优先落地的指标清单(建议从这 12 个开始)
A. 服务入口(API/Gateway)
1) http_server_requests_total{route,method,status} 计数器
2) http_server_request_duration_ms{route,method} 直方图
3) http_inflight_requests{route} 仪表盘(Gauge)
B. OpenClaw 核心业务(Agent/Workflow/Task)
4) openclaw_task_started_total{task_type}
5) openclaw_task_completed_total{task_type,status}
6) openclaw_task_duration_ms{task_type}
7) openclaw_workflow_step_duration_ms{workflow,step}
C. 工具调用(Tools)
8) openclaw_tool_calls_total{tool_name,status,http_status}
9) openclaw_tool_call_duration_ms{tool_name}
10) openclaw_tool_timeouts_total{tool_name}
D. 模型调用(LLM)
11) openclaw_model_requests_total{provider,model,status}
12) openclaw_model_tokens_total{provider,model,direction}(direction=prompt/completion)
这些指标能覆盖 80% 的问题定位:
- “整体慢”看入口延迟直方图
- “工具挂了”看 tool 的 status 与 timeout
- “成本暴涨”看 tokens_total
3.2 直方图怎么设计桶(bucket)才不浪费
延迟指标建议用直方图(Histogram),桶设置要符合真实分布。比如工具调用延迟常见在 50ms~5s:
- 50, 100, 200, 300, 500, 800, 1200, 2000, 3500, 5000, 8000
模型调用可能更慢:
- 200, 500, 800, 1200, 2000, 3500, 5000, 8000, 12000, 20000
原则:
- 桶不要太密,否则存储与计算成本高
- 以 SLO(比如 P95 < 2s)为中心,在阈值附近加密桶
3.3 指标维度(labels)控制:避免“维度爆炸”
常见反面案例:把 user_id、prompt、url 直接当 label,导致时序数量爆炸。
建议:
- label 仅使用低基数维度:
route、tool_name、model、status、error_type - 高基数信息(request_id、user_id、具体 URL)放日志或 trace attributes,不放指标 labels
3.4 可操作的告警建议(不依赖玄学阈值)
给出几条适合 OpenClaw 的告警规则方向:
- 入口错误率:
5xx / total在 5 分钟窗口 > 1% 且请求量 > N - 工具超时率:
openclaw_tool_timeouts_total5 分钟增量 > 阈值 - 模型 429:
openclaw_model_requests_total{error_type="model_rate_limit"}激增 - 任务堆积(若有队列):队列长度 Gauge 持续上升 + 消费速率下降
- 成本异常:tokens_total 的速率在 15 分钟内相比过去 24 小时同时间段上升 X 倍
这样告警触发后,你可以立刻用 trace 看是哪条链路在放大问题。
四、链路追踪实战:把一次“Agent 运行”拆成可解释的 spans
链路追踪的目标:把一次 OpenClaw 的端到端执行变成一棵树,让你看到:
- 总耗时花在哪里
- 哪个工具/模型调用是瓶颈
- 哪一步失败,错误从哪冒出来
- 重试、降级、缓存命中是否发生
4.1 span 设计:以“业务阶段”而不是“代码函数”命名
推荐 span 层级(示例):
HTTP POST /v1/agent/run(入口 span)auth.validateagent.plan(规划/路由)tool.call web_searchhttp.client GET https://...
model.generate gpt-4.1-minimemory.write(如有)response.render
命名建议:
- 使用动宾结构:
tool.call、model.generate、workflow.execute - 工具/模型名称放到 attributes:
tool.name、model.name,避免 span 名称过于碎片化
4.2 在 span 上挂 attributes:让 trace 可筛选、可聚合
OpenClaw 场景建议加的 attributes:
- 通用:
tenant_id、user_id、request_id - 工具:
tool.name、tool.type、http.status_code、retry.count、cache.hit - 模型:
model.provider、model.name、tokens.prompt、tokens.completion、temperature - 任务:
task_id、task_type、workflow.name、step.name
注意:
- attributes 不要塞超长文本(如完整 prompt),否则 trace 存储压力大
- 对于 prompt 可以记录:长度、hash、模板版本号
4.3 错误记录规范:用 span status + exception 事件
当失败发生时:
- 将 span 标记为错误(status=ERROR)
- 记录异常事件(exception type/message/stack)
- 额外打上稳定字段:
error_type、error_code
这样你既能通过错误率指标发现问题,也能在 trace 中看到具体失败点。
4.4 异步任务与队列:如何把 trace 传过去
OpenClaw 常会把“执行 Agent/Workflow”丢到队列或后台 worker。此时 trace 最容易断。
建议做法:
1) 生产者入队时:
- 在消息 headers 中写入
traceparent(W3C) - 或写入
trace_id+span_id(但优先 traceparent)
2) 消费者出队时:
- 从 headers 解析并恢复上下文
- 在此上下文中创建
queue.consume或task.executespan
3) 记录队列等待时间:
- 入队写
enqueued_at - 出队计算
queue_delay_ms - 作为 span attribute + 指标直方图
这样你能回答:“慢到底是执行慢,还是排队慢”。
五、把三件套串起来:一套可落地的排障路径
下面给出一个你在 OpenClaw 生产环境中可直接照抄的排障 SOP(标准作业流程)。
5.1 从告警开始:先看指标,再点进 trace
例:告警提示 openclaw_tool_call_duration_ms{tool_name=web_search} P95 从 300ms 升到 3s。
操作步骤:
1) 在指标面板确认:
- 变慢发生的时间段
- 是否伴随错误率升高(
openclaw_tool_calls_total{status="error"})
2) 用筛选条件找 trace:
tool.name=web_search且duration > 2s- 或
status=ERROR
3) 打开最慢的几条 trace:
- 看是 DNS/TLS/对端响应慢,还是重试导致
- 查看 attributes:
retry.count、http.status_code
4) 回到日志:
- 使用 trace_id 搜索相关日志
- 找到对端返回内容摘要、超时阈值、重试策略命中情况
5.2 常见问题与快速定位提示
- 模型调用耗时上升但无错误:优先看
model.provider是否切换、region是否变化、是否发生排队;检查 tokens 是否变多(prompt 变长会显著拉长延迟) - 工具错误率上升:按
http_status分组,区分 4xx(参数/权限)和 5xx(对端不稳);再看error_type是否集中在tool_timeout - 任务完成率下降但入口正常:看队列 delay 指标,可能是 worker 不足或消费卡住;trace 中会出现长时间 gap
六、在 OpenClaw 项目里落地的“最小闭环”清单(建议一周内完成)
如果你希望快速做出效果,不必一次性做全量,按以下顺序推进:
6.1 第 1 天:统一日志格式 + 注入 trace_id
- 所有服务切到结构化日志
- 日志里必须有
trace_id/request_id/operation/status/duration_ms - 先不追求完美字段,但要保证可检索
6.2 第 2~3 天:补齐入口指标 + 工具/模型核心指标
- HTTP 请求总量、延迟直方图、错误率
- 工具调用次数/耗时/超时
- 模型请求次数/失败类型/tokens
并把“维度爆炸”风险控制住:不要把 user_id 当 label。
6.3 第 4~5 天:链路追踪贯通 + 异步传递上下文
- 入口 trace 打通
- 工具 HTTP client、模型调用都生成子 span
- 队列/worker 上下文传递
- span 上至少挂:
tenant_id/user_id/tool.name/model.name/error_type
6.4 第 6~7 天:建立 3 个仪表盘 + 5 条告警
建议 3 个面板:
1) API 总览:QPS、P95、错误率
2) 工具健康:按 tool 维度的耗时、错误率、超时
3) 模型健康与成本:请求量、429、tokens 速率
建议 5 条告警:
- API 5xx 错误率
- P95 延迟
- 工具超时率
- 模型 429 激增
- tokens 速率异常
做到这里,你基本就拥有了“可发现、可定位、可解释、可追责”的最小闭环。
七、常见坑位清单(踩过一次就会珍惜规范)
1) 日志没有 trace_id:指标告警后只能“猜”,无法精确复盘
2) 指标 label 乱加:时序爆炸,监控成本飙升
3) span 命名随意:到处都是 functionA/functionB,业务人员看不懂
4) 把敏感信息打进日志/trace:合规风险极高
5) 只做日志不做指标:没有告警触发机制,问题只能靠用户反馈
6) 只做指标不做 trace:只能知道“慢了”,不知道“为什么慢”
结语:把可观测性当作 OpenClaw 的“产品能力”
在 OpenClaw 项目中,日志规范决定你能不能快速检索与还原现场;指标决定你能不能及时发现问题并触发告警;链路追踪决定你能不能把一次复杂的 Agent/Workflow 执行拆解成可解释的耗时与错误路径。
建议你从本文的“最小闭环”开始:先统一字段与 ID,再补关键指标与 spans,最终形成从告警到定位的自动化路径。这样无论是性能优化、稳定性治理,还是成本控制,你都会有可靠的数据依据,而不是凭感觉调参。
Prev:OpenClaw错误处理体系:异常分类、降级策略与失败重放