Repository: zeromicro/go-zero (go)

Issue:
go-zero v1.4.2  TracingHandler Bug

![1669119140966](https://user-images.githubusercontent.com/58159880/203310983-377defd0-33cb-41a7-9e51-93be1f578c74.jpg)

defer next.ServeHTTP(w, r) cause **_span.IsRecording()_** is **_false_** in my handler

I cant' set other attributes to span.

Please check order of defers
or
```
r = r.WithContext(spanCtx)
next.ServeHTTP(w, r)
```

It work fine in older version.

Thanks.

Pull request description:
fix(rest): fix issues#2628
fixed #2628

Patch:
diff --git a/rest/handler/tracinghandler.go b/rest/handler/tracinghandler.go
index 9e258dfc..2d6b7119 100644
--- a/rest/handler/tracinghandler.go
+++ b/rest/handler/tracinghandler.go
@@ -26,20 +26,17 @@ func TracingHandler(serviceName, path string) func(http.Handler) http.Handler {
 		tracer := otel.GetTracerProvider().Tracer(trace.TraceName)
 
 		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-			defer func() {
-				next.ServeHTTP(w, r)
-			}()
-
-			ctx := propagator.Extract(r.Context(), propagation.HeaderCarrier(r.Header))
 			spanName := path
 			if len(spanName) == 0 {
 				spanName = r.URL.Path
 			}
 
 			if _, ok := notTracingSpans.Load(spanName); ok {
+				next.ServeHTTP(w, r)
 				return
 			}
 
+			ctx := propagator.Extract(r.Context(), propagation.HeaderCarrier(r.Header))
 			spanCtx, span := tracer.Start(
 				ctx,
 				spanName,
@@ -51,7 +48,7 @@ func TracingHandler(serviceName, path string) func(http.Handler) http.Handler {
 
 			// convenient for tracking error messages
 			propagator.Inject(spanCtx, propagation.HeaderCarrier(w.Header()))
-			r = r.WithContext(spanCtx)
+			next.ServeHTTP(w, r.WithContext(spanCtx))
 		})
 	}
 }


Test patch:
diff --git a/rest/handler/tracinghandler_test.go b/rest/handler/tracinghandler_test.go
index c1d224d6..f33d5926 100644
--- a/rest/handler/tracinghandler_test.go
+++ b/rest/handler/tracinghandler_test.go
@@ -27,9 +27,9 @@ func TestOtelHandler(t *testing.T) {
 		t.Run(test, func(t *testing.T) {
 			h := chain.New(TracingHandler("foo", test)).Then(
 				http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-					ctx := otel.GetTextMapPropagator().Extract(r.Context(), propagation.HeaderCarrier(r.Header))
-					spanCtx := trace.SpanContextFromContext(ctx)
-					assert.True(t, spanCtx.IsValid())
+					span := trace.SpanFromContext(r.Context())
+					assert.True(t, span.SpanContext().IsValid())
+					assert.True(t, span.IsRecording())
 				}))
 			ts := httptest.NewServer(h)
 			defer ts.Close()
@@ -52,7 +52,7 @@ func TestOtelHandler(t *testing.T) {
 	}
 }
 
-func TestDontTracingSpanName(t *testing.T) {
+func TestDontTracingSpan(t *testing.T) {
 	ztrace.StartAgent(ztrace.Config{
 		Name:     "go-zero-test",
 		Endpoint: "http://localhost:14268/api/traces",
@@ -66,12 +66,15 @@ func TestDontTracingSpanName(t *testing.T) {
 		t.Run(test, func(t *testing.T) {
 			h := chain.New(TracingHandler("foo", test)).Then(
 				http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-					spanCtx := trace.SpanContextFromContext(r.Context())
+					span := trace.SpanFromContext(r.Context())
+					spanCtx := span.SpanContext()
 					if test == "bar" {
 						assert.False(t, spanCtx.IsValid())
+						assert.False(t, span.IsRecording())
 						return
 					}
 
+					assert.True(t, span.IsRecording())
 					assert.True(t, spanCtx.IsValid())
 				}))
 			ts := httptest.NewServer(h)