mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
fix: use correct response writer for tracing middle (#3693)
This commit is contained in:
+31
-21
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/go-chi/chi/v5"
|
||||
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.10.0"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
// HTTPMW adds tracing to http routes.
|
||||
@@ -27,28 +28,37 @@ func HTTPMW(tracerProvider *sdktrace.TracerProvider, name string) func(http.Hand
|
||||
wrw := middleware.NewWrapResponseWriter(rw, r.ProtoMajor)
|
||||
|
||||
// pass the span through the request context and serve the request to the next middleware
|
||||
next.ServeHTTP(rw, r)
|
||||
next.ServeHTTP(wrw, r)
|
||||
|
||||
// set the resource name as we get it only once the handler is executed
|
||||
route := chi.RouteContext(r.Context()).RoutePattern()
|
||||
if route != "" {
|
||||
span.SetName(fmt.Sprintf("%s %s", r.Method, route))
|
||||
}
|
||||
span.SetName(fmt.Sprintf("%s %s", r.Method, route))
|
||||
span.SetAttributes(semconv.NetAttributesFromHTTPRequest("tcp", r)...)
|
||||
span.SetAttributes(semconv.EndUserAttributesFromHTTPRequest(r)...)
|
||||
span.SetAttributes(semconv.HTTPServerAttributesFromHTTPRequest("", route, r)...)
|
||||
span.SetAttributes(semconv.HTTPRouteKey.String(route))
|
||||
|
||||
// set the status code
|
||||
status := wrw.Status()
|
||||
// 0 status means one has not yet been sent in which case net/http library will write StatusOK
|
||||
if status == 0 {
|
||||
status = http.StatusOK
|
||||
}
|
||||
span.SetAttributes(semconv.HTTPStatusCodeKey.Int(status))
|
||||
spanStatus, spanMessage := semconv.SpanStatusFromHTTPStatusCode(status)
|
||||
span.SetStatus(spanStatus, spanMessage)
|
||||
// capture response data
|
||||
EndHTTPSpan(r, wrw.Status())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// EndHTTPSpan captures request and response data after the handler is done.
|
||||
func EndHTTPSpan(r *http.Request, status int) {
|
||||
span := trace.SpanFromContext(r.Context())
|
||||
|
||||
// set the resource name as we get it only once the handler is executed
|
||||
route := chi.RouteContext(r.Context()).RoutePattern()
|
||||
if route != "" {
|
||||
span.SetName(fmt.Sprintf("%s %s", r.Method, route))
|
||||
}
|
||||
span.SetName(fmt.Sprintf("%s %s", r.Method, route))
|
||||
span.SetAttributes(semconv.NetAttributesFromHTTPRequest("tcp", r)...)
|
||||
span.SetAttributes(semconv.EndUserAttributesFromHTTPRequest(r)...)
|
||||
span.SetAttributes(semconv.HTTPServerAttributesFromHTTPRequest("", route, r)...)
|
||||
span.SetAttributes(semconv.HTTPRouteKey.String(route))
|
||||
|
||||
// 0 status means one has not yet been sent in which case net/http library will write StatusOK
|
||||
if status == 0 {
|
||||
status = http.StatusOK
|
||||
}
|
||||
span.SetAttributes(semconv.HTTPStatusCodeKey.Int(status))
|
||||
spanStatus, spanMessage := semconv.SpanStatusFromHTTPStatusCode(status)
|
||||
span.SetStatus(spanStatus, spanMessage)
|
||||
|
||||
// finally end span
|
||||
span.End()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user