Go语言分布式追踪:OpenTelemetry实战
Go语言分布式追踪OpenTelemetry实战1. OpenTelemetry概述OpenTelemetryOTel是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支持可以轻松实现微服务架构下的全链路追踪。