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") }