Go语言分布式追踪:OpenTelemetry实战
Go语言分布式追踪:OpenTelemetry实战
1. OpenTelemetry概述
OpenTelemetry(OTel)是CNCF的可观测性框架,提供了一套统一的追踪、指标、日志收集标准。本文重点介绍分布式追踪的实现。
2. 追踪客户端实现
package otel import ( "context" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/exporters/jaeger" "go.opentelemetry.io/otel/sdk/trace" ) type Tracer struct { tracer *trace.Tracer } func NewTracer(serviceName, endpoint string) (*Tracer, error) { exporter, err := jaeger.NewRawExporter( jaeger.WithCollectorEndpoint(endpoint), ) if err != nil { return nil, err } tp := trace.NewTracerProvider( trace.WithBatcher(exporter), trace.WithResource( resource.NewWithAttributes( semconv.ServiceNameKey.String(serviceName), ), ), ) otel.SetTracerProvider(tp) return &Tracer{ tracer: otel.Tracer(serviceName), }, nil } func (t *Tracer) StartSpan(ctx context.Context, name string, attrs ...attribute.KeyValue) (context.Context, *trace.Span) { return t.tracer.Start(ctx, name, trace.WithAttributes(attrs...)) } func (t *Tracer) AddEvent(ctx context.Context, name string, attrs ...attribute.KeyValue) { span := trace.SpanFromContext(ctx) span.AddEvent(name, trace.WithAttributes(attrs...)) }3. gRPC拦截器集成
func (s *Server) StreamInterceptor() grpc.ServerStreamInterceptor { return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { ctx, span := tracer.StartSpan(ss.Context(), info.FullMethod) defer span.End() return handler(srv, serverStream{ss, ctx}) } } type serverStream struct { grpc.ServerStream ctx context.Context } func (s *serverStream) Context() context.Context { return s.ctx }4. HTTP中间件集成
func Middleware(tracer *Tracer) gin.HandlerFunc { return func(c *gin.Context) { ctx, span := tracer.StartSpan( c.Request.Context(), c.FullPath(), attribute.String("http.method", c.Request.Method), ) defer span.End() c.Request = c.Request.WithContext(ctx) c.Next() span.SetAttributes( attribute.Int("http.status", c.Writer.Status()), ) } }5. 总结
OpenTelemetry为Go语言提供了完整的分布式追踪能力,通过统一的标准和丰富的SDK支持,可以轻松实现微服务架构下的全链路追踪。
