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  }