feat(observability): OpenTelemetry 全链路追踪(Jaeger + NATS 跨总线传播)

新增 sundynix-shared/otelx:otelx.Init(ctx,服务名) 注册 W3C 传播器 + OTLP/HTTP
批量导出(默认 localhost:4318,docker 里的 Jaeger);OTEL_SDK_DISABLED=true 关导出。
Jaeger 不在线 / 导出器构建失败都不阻断启动(可观测性是增益而非依赖)。

- NATS 跨进程传播(无现成中间件):bus/trace.go 的 natsHeaderCarrier + inject/extract,
  PublishTask/CallTool 注入 traceparent,ConsumeTasks/ServeTool 抽出续上 → 链路跨总线连成一棵树。
- 埋点:gateway 挂 otelgin(HTTP server span,链路根);dispatcher task.execute →
  node.<kind>(每节点,nctx 下传使工具/LLM 挂到节点下)→ llm.stream/llm.generate;
  bus 自动出 tool.call(client)↔tool.serve(server) 成对跨服务 span。
- docker-compose 加 jaeger all-in-one(UI :16686,OTLP :4318)。
- 依赖修复:otlptracehttp 触发 genproto 单体(旧)vs 拆分模块 ambiguous import(milvus 拉旧版),
  pin genproto 至后拆分版(go.work 工作区全局生效)。
- production_readiness.md 1.1 更新为「已实现」。

验证:真实 input→retriever→agent 任务在 Jaeger 出 14 span / 3 服务的完整树,
跨 NATS(publish→consume)、跨服务(tool.call→tool.serve)均连通,
瓶颈 kb_search 692ms、llm 1597ms 一眼可见;四模块 build+vet+test 全绿。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Blizzard
2026-06-24 11:35:08 +08:00
parent 46ef3df221
commit a2d184b7ec
22 changed files with 675 additions and 67 deletions
+10 -3
View File
@@ -28,11 +28,18 @@
> **目标**:任何线上问题在 5 分钟内能定位到根因节点。
### 1.1 分布式链路追踪 (Tracing) — ⚠️ 缺失
### 1.1 分布式链路追踪 (Tracing) — ✅ 已实现
**现状**仅有 `X-Request-ID` 透传和 `log.Printf` 散落日志,无法追踪一次请求跨 Gateway → NATS → Dispatcher → MCP 工具的完整调用链。
**已落地**OpenTelemetry 全链路追踪一次任务从 Gateway → NATS → Dispatcher → MCP 工具的调用链在 Jaeger 里呈现为一棵 span 树
- 启动器 `sundynix-shared/otelx`:各服务 main 调 `otelx.Init(ctx, "服务名")`OTLP/HTTP 导出到 `OTEL_EXPORTER_OTLP_ENDPOINT`(默认 `localhost:4318`docker 里的 Jaeger);`OTEL_SDK_DISABLED=true` 整体关闭导出(仍保留传播器)。Jaeger UI: `http://localhost:16686`
- **HTTP 入口**gateway 挂 `otelgin` 中间件,每个请求一个 server span(链路根 + 提取上游 traceparent)。
- **NATS 跨进程传播**(关键):`sundynix-shared/bus``PublishTask`/`CallTool` 把 W3C traceparent 注入消息头,`ConsumeTasks`/`ServeTool` 抽出续上——这是链路能跨总线连成一棵树的核心。
- **Eino 图埋点**`task.execute` → 每个 `node.<kind>``tool.call`/`tool.serve`(跨服务成对)→ `llm.stream`/`llm.generate`,层级与 ExecEvent 对齐。
- 实测一次「input→retriever→agent」任务出 14 span / 3 服务,瓶颈(kb_search 692ms、llm 1597ms)一眼可见。
**需引入**
> 与既有 Prometheusmetrics+ sloglogs)合为可观测性三件套。下一步可补:slog 日志带 trace_id 互跳、mcp-py 接入、采样策略。
**实现细节(原规划,已照此落地)**
```
┌─────────────────────────────────────────────────────────────────┐