github.com/icyphox/x@v0.0.355-0.20220311094250-029bd783e8b8/tracing/http_client.go (about) 1 package tracing 2 3 import ( 4 "net/http" 5 6 "github.com/opentracing/opentracing-go" 7 "github.com/opentracing/opentracing-go/ext" 8 otlog "github.com/opentracing/opentracing-go/log" 9 ) 10 11 // The RoundTripperFunc type is an adapter to allow the use of ordinary 12 // functions as RoundTrippers. If f is a function with the appropriate 13 // signature, RountTripperFunc(f) is a RoundTripper that calls f. 14 type RoundTripperFunc func(req *http.Request) (*http.Response, error) 15 16 // RoundTrip implements the RoundTripper interface. 17 func (rt RoundTripperFunc) RoundTrip(r *http.Request) (*http.Response, error) { 18 return rt(r) 19 } 20 21 func RoundTripper(tracer opentracing.Tracer, delegate http.RoundTripper) http.RoundTripper { 22 return RoundTripperFunc(func(req *http.Request) (*http.Response, error) { 23 ctx := req.Context() 24 25 saveURL := *req.URL 26 saveURL.RawQuery = "" 27 saveURL.User = nil 28 29 span, _ := opentracing.StartSpanFromContextWithTracer(ctx, tracer, "webhook", ext.SpanKindRPCClient, 30 opentracing.Tags{ 31 "http.url": saveURL.String(), 32 "http.method": req.Method, 33 }) 34 defer span.Finish() 35 carrier := opentracing.HTTPHeadersCarrier(req.Header) 36 span.Tracer().Inject(span.Context(), opentracing.HTTPHeaders, carrier) 37 38 if delegate == nil { 39 delegate = http.DefaultTransport 40 } 41 42 resp, err := delegate.RoundTrip(req) 43 44 if err != nil { 45 span.SetTag("http.error", err.Error()) 46 span.LogFields(otlog.Error(err)) 47 return resp, err 48 } 49 ext.HTTPStatusCode.Set(span, uint16(resp.StatusCode)) 50 return resp, err 51 }) 52 }