Appearance
功能规格说明:OpenTelemetry 集成
创建日期:2026-05-09
用户场景与测试 (必填)
用户故事:使用 OTLP 导出器的远程遥测(优先级:P1)
作为开发者,我希望将 Wave 遥测数据发送到 OTLP 收集器(例如 Jaeger、Grafana Tempo、Honeycomb),以便观察 agent 行为、调试性能问题和分析会话模式。
为什么是这个优先级:这是 OpenTelemetry 的主要用例——将结构化的 trace、metric 和 log 发送到外部后端进行分析。
独立测试:通过 OTEL_EXPORTER_OTLP_ENDPOINT 将 Wave 指向本地 Jaeger 或 Grafana 实例,运行会话,并验证 trace 出现在收集器的 UI 中。
验收场景:
- 假设
OTEL_TRACES_EXPORTER=otlp且OTEL_EXPORTER_OTLP_ENDPOINT设置为运行中的收集器,当用户发送消息且 agent 响应时,则收集器收到完整的 trace,包含交互 span、带 token 计数的 LLM 请求 span 和带持续时间的工具执行 span。 - 假设
OTEL_METRICS_EXPORTER=otlp且有收集器端点,当 agent 完成一轮时,则收集器收到定期的 metric 导出,包含 token 使用量、延迟直方图和错误计数器。 - 假设
OTEL_LOGS_EXPORTER=otlp且有收集器端点,当会话开始和结束时,则收集器收到session_start和session_end的结构化日志事件。
用户故事:JSONL 文件导出器(优先级:P2)
作为开发者,我希望遥测数据写入专用的 JSONL 文件(~/.wave/telemetry.jsonl),以便通过 tail 文件观察 span 和 metric,而无需外部收集器。
为什么是这个优先级:JSONL 匹配 Wave 现有的会话文件格式——每行是一个自包含的 JSON 记录,易于 tail -f、用 jq 解析或流式传输到下游工具。与 ~/.wave/logs/(文本日志,cli.log/desktop.log/vscode.log/jetbrains.log)和 ~/.wave/sessions/*.jsonl(会话数据)解耦。
独立测试:使用 OTEL_METRICS_EXPORTER=jsonl OTEL_TRACES_EXPORTER=jsonl 运行 Wave,与 agent 交互,并观察 ~/.wave/telemetry.jsonl 中的结构化 JSONL 记录。
验收场景:
- 假设 Wave 使用
OTEL_TRACES_EXPORTER=jsonl启动,当 agent 处理消息时,则~/.wave/telemetry.jsonl包含每个 span 一行 JSON(交互、LLM 请求、工具)。~/.wave/logs/cli.log不受影响。 - 假设 Wave 使用
OTEL_METRICS_EXPORTER=jsonl启动,当 agent 完成一轮时,则~/.wave/telemetry.jsonl包含 metric JSON 行。~/.wave/logs/cli.log不受影响。 - 假设有遥测 JSONL 文件,当通过
jq管道传输时,则每行独立解析为有效 JSON。
用户故事:通过事件日志的会话诊断(优先级:P2)
作为开发者,我希望关键会话生命周期事件(开始、结束、压缩、工具决策、错误)有结构化事件日志,以便无需解析原始 JSONL 文件即可重建会话期间发生的事情。
为什么是这个优先级:这提供了可搜索的结构化审计跟踪,补充原始消息历史。事件通过配置的 logs 导出器导出(OTLP 用于远程,jsonl 用于本地文件)。
独立测试:使用 OTEL_LOGS_EXPORTER=otlp 运行 Wave,完成包含多轮包括压缩和被拒绝工具调用的会话,并验证所有生命周期事件出现在收集器中。或使用 OTEL_LOGS_EXPORTER=jsonl 并 tail ~/.wave/telemetry.jsonl。
验收场景:
- 假设 OTEL 日志已启用,当会话开始时,则记录
session_start事件,包含 sessionId、model 和 workdir。 - 假设 OTEL 日志已启用,当 agent 自动压缩对话时,则记录
compaction事件,包含压缩前后的 token 计数。 - 假设 OTEL 日志已启用,当工具权限被拒绝时,则记录
tool_decision事件,包含工具名称和决策。 - 假设
OTEL_LOG_USER_PROMPTS=1,当用户发送消息时,则user_prompt事件包含实际提示文本。假设OTEL_LOG_USER_PROMPTS未设置,则排除提示文本。
边界情况
- 如果 OTLP 端点不可达会怎样? 遥测导出应优雅失败并记录警告;agent 会话必须正常继续而不阻塞。
- 如果 OTEL 已启用但未配置导出器会怎样? 不设置默认导出器。用户必须显式配置至少一个导出器。这避免在交互模式中意外的 stdout 污染。
- 并行工具执行期间会怎样? 每个工具调用必须使用 AsyncLocalStorage 在正确的父交互 span 下创建自己的子 span,以防止 span 上下文混合。
- 在 100+ 轮的长时间运行会话中会怎样? 超过 30 分钟的活动 span 必须被清理以防止内存泄漏。
- 如果遥测初始化失败会怎样? agent 必须在没有遥测的情况下正常启动;记录警告但不崩溃。