a2d184b7ec
新增 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>
42 lines
1.3 KiB
Go
42 lines
1.3 KiB
Go
package bus
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/nats-io/nats.go"
|
|
"go.opentelemetry.io/otel"
|
|
"go.opentelemetry.io/otel/trace"
|
|
)
|
|
|
|
// natsHeaderCarrier 让 OTel 传播器能读写 NATS 消息头(W3C traceparent 等),
|
|
// 从而把链路上下文跨 NATS 总线带到下游服务——这是分布式追踪能连成一棵树的关键。
|
|
type natsHeaderCarrier nats.Header
|
|
|
|
func (c natsHeaderCarrier) Get(key string) string { return nats.Header(c).Get(key) }
|
|
func (c natsHeaderCarrier) Set(key, value string) { nats.Header(c).Set(key, value) }
|
|
func (c natsHeaderCarrier) Keys() []string {
|
|
out := make([]string, 0, len(c))
|
|
for k := range c {
|
|
out = append(out, k)
|
|
}
|
|
return out
|
|
}
|
|
|
|
// injectTrace 把 ctx 里的链路上下文写进 NATS 消息头(发布前调用)。
|
|
func injectTrace(ctx context.Context, h nats.Header) {
|
|
otel.GetTextMapPropagator().Inject(ctx, natsHeaderCarrier(h))
|
|
}
|
|
|
|
// extractTrace 从 NATS 消息头还原上游链路上下文,挂到 ctx 上(消费时调用)。
|
|
func extractTrace(ctx context.Context, h nats.Header) context.Context {
|
|
if h == nil {
|
|
return ctx
|
|
}
|
|
return otel.GetTextMapPropagator().Extract(ctx, natsHeaderCarrier(h))
|
|
}
|
|
|
|
// tracer 是 bus 自身的 span 发射器(与业务同 scope,方便 Jaeger 归组)。
|
|
func tracer() trace.Tracer {
|
|
return otel.Tracer("github.com/sundynix/sundynix-agentix")
|
|
}
|