fork of https://github.com/sourcegraph/zoekt
1package trace
2
3import (
4 "context"
5 "net/http"
6
7 "github.com/opentracing/opentracing-go"
8)
9
10// Middleware wraps an http.Handler to extract opentracing span information from the request headers.
11// The opentracing.SpanContext is added to the request context, and can be retrieved by SpanContextFromContext.
12func Middleware(next http.Handler) http.Handler {
13 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
14 tracer := opentracing.GlobalTracer()
15 spanContext, err := tracer.Extract(opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(r.Header))
16 if err == nil {
17 r = r.WithContext(ContextWithSpanContext(r.Context(), spanContext))
18 }
19 next.ServeHTTP(w, r)
20 })
21}
22
23type spanContextKey struct{}
24
25// SpanContextFromContext retrieves the opentracing.SpanContext set on the context by Middleware
26func SpanContextFromContext(ctx context.Context) opentracing.SpanContext {
27 if v := ctx.Value(spanContextKey{}); v != nil {
28 return v.(opentracing.SpanContext)
29 }
30 return nil
31}
32
33// ContextWithSpanContext creates a new context with the opentracing.SpanContext set
34func ContextWithSpanContext(ctx context.Context, sc opentracing.SpanContext) context.Context {
35 return context.WithValue(ctx, spanContextKey{}, sc)
36}