package handler import ( "net/http" "github.com/zeromicro/go-zero/core/trace" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/propagation" semconv "go.opentelemetry.io/otel/semconv/v1.4.0" oteltrace "go.opentelemetry.io/otel/trace" ) // TracingHandler return a middleware that process the opentelemetry. func TracingHandler(serviceName, path string) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { propagator := otel.GetTextMapPropagator() tracer := otel.GetTracerProvider().Tracer(trace.TraceName) return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ctx := propagator.Extract(r.Context(), propagation.HeaderCarrier(r.Header)) spanName := path if len(spanName) == 0 { spanName = r.URL.Path } spanCtx, span := tracer.Start( ctx, spanName, oteltrace.WithSpanKind(oteltrace.SpanKindServer), oteltrace.WithAttributes(semconv.HTTPServerAttributesFromHTTPRequest( serviceName, spanName, r)...), ) defer span.End() // convenient for tracking error messages sc := span.SpanContext() if sc.HasTraceID() { w.Header().Set(trace.TraceIdKey, sc.TraceID().String()) } next.ServeHTTP(w, r.WithContext(spanCtx)) }) } }