MCPcopy Index your code
hub / github.com/coder/coder / Middleware

Function Middleware

coderd/tracing/httpmw.go:20–76  ·  view source on GitHub ↗

Middleware adds tracing to http routes.

(tracerProvider trace.TracerProvider)

Source from the content-addressed store, hash-verified

18
19// Middleware adds tracing to http routes.
20func Middleware(tracerProvider trace.TracerProvider) func(http.Handler) http.Handler {
21 // We only want to create spans on the following route patterns, however
22 // we want the middleware to be very high in the middleware stack so it can
23 // capture the entire request.
24 re := patternmatcher.RoutePatterns{
25 "/api",
26 "/api/**",
27 "/@*/*/apps/**",
28 "/%40*/*/apps/**",
29 "/external-auth/*/callback",
30 }.MustCompile()
31
32 var tracer trace.Tracer
33 if tracerProvider != nil {
34 tracer = tracerProvider.Tracer(TracerName)
35 }
36
37 return func(next http.Handler) http.Handler {
38 return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
39 if tracer == nil || !re.MatchString(r.URL.Path) {
40 next.ServeHTTP(rw, r)
41 return
42 }
43
44 // Extract the trace context from the request headers.
45 tmp := otel.GetTextMapPropagator()
46 hc := propagation.HeaderCarrier(r.Header)
47 ctx := tmp.Extract(r.Context(), hc)
48
49 // start span with default span name. Span name will be updated to "method route" format once request finishes.
50 ctx, span := tracer.Start(ctx, fmt.Sprintf("%s %s", r.Method, r.RequestURI))
51 defer span.End()
52 r = r.WithContext(ctx)
53
54 if span.SpanContext().HasTraceID() && span.SpanContext().HasSpanID() {
55 // Technically these values are included in the Traceparent
56 // header, but they are easier to read for humans this way.
57 rw.Header().Set("X-Trace-ID", span.SpanContext().TraceID().String())
58 rw.Header().Set("X-Span-ID", span.SpanContext().SpanID().String())
59
60 // Inject the trace context into the response headers.
61 hc := propagation.HeaderCarrier(rw.Header())
62 tmp.Inject(ctx, hc)
63 }
64
65 sw, ok := rw.(*StatusWriter)
66 if !ok {
67 panic(fmt.Sprintf("ResponseWriter not a *tracing.StatusWriter; got %T", rw))
68 }
69
70 // pass the span through the request context and serve the request to the next middleware
71 next.ServeHTTP(sw, r)
72 // capture response data
73 EndHTTPSpan(r, sw.Status, span)
74 })
75 }
76}
77

Callers 3

NewFunction · 0.92
Test_MiddlewareFunction · 0.92
NewFunction · 0.92

Calls 10

EndHTTPSpanFunction · 0.85
MustCompileMethod · 0.80
TracerMethod · 0.80
WithContextMethod · 0.80
ContextMethod · 0.65
StartMethod · 0.65
SetMethod · 0.65
ServeHTTPMethod · 0.45
HeaderMethod · 0.45
StringMethod · 0.45

Tested by 1

Test_MiddlewareFunction · 0.74