github.com/lingyao2333/mo-zero@v1.4.1/rest/handler/tracinghandler.go (about) 1 package handler 2 3 import ( 4 "net/http" 5 "sync" 6 7 "github.com/lingyao2333/mo-zero/core/lang" 8 "github.com/lingyao2333/mo-zero/core/trace" 9 "go.opentelemetry.io/otel" 10 "go.opentelemetry.io/otel/propagation" 11 semconv "go.opentelemetry.io/otel/semconv/v1.4.0" 12 oteltrace "go.opentelemetry.io/otel/trace" 13 ) 14 15 var notTracingSpans sync.Map 16 17 // DontTraceSpan disable tracing for the specified span name. 18 func DontTraceSpan(spanName string) { 19 notTracingSpans.Store(spanName, lang.Placeholder) 20 } 21 22 // TracingHandler return a middleware that process the opentelemetry. 23 func TracingHandler(serviceName, path string) func(http.Handler) http.Handler { 24 return func(next http.Handler) http.Handler { 25 propagator := otel.GetTextMapPropagator() 26 tracer := otel.GetTracerProvider().Tracer(trace.TraceName) 27 28 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 29 defer func() { 30 next.ServeHTTP(w, r) 31 }() 32 33 ctx := propagator.Extract(r.Context(), propagation.HeaderCarrier(r.Header)) 34 spanName := path 35 if len(spanName) == 0 { 36 spanName = r.URL.Path 37 } 38 39 if _, ok := notTracingSpans.Load(spanName); ok { 40 return 41 } 42 43 spanCtx, span := tracer.Start( 44 ctx, 45 spanName, 46 oteltrace.WithSpanKind(oteltrace.SpanKindServer), 47 oteltrace.WithAttributes(semconv.HTTPServerAttributesFromHTTPRequest( 48 serviceName, spanName, r)...), 49 ) 50 defer span.End() 51 52 // convenient for tracking error messages 53 propagator.Inject(spanCtx, propagation.HeaderCarrier(w.Header())) 54 r = r.WithContext(spanCtx) 55 }) 56 } 57 }