github.com/brycereitano/goa@v0.0.0-20170315073847-8ffa6c85e265/middleware/xray/client.go (about) 1 package xray 2 3 import ( 4 "net/http" 5 6 "golang.org/x/net/context" 7 ) 8 9 type ( 10 // Doer is the http Client interface. 11 Doer interface { 12 Do(*http.Request) (*http.Response, error) 13 } 14 15 // httpTracer is a http client that creates subsegments for each request 16 // it makes. 17 httpTracer struct { 18 client *http.Client 19 segment *Segment 20 } 21 ) 22 23 // WrapClient wraps a http client and creates subsegments of the segment in the 24 // context for each request it makes. The subsegments created this way have 25 // their namespace set to "remote". 26 // 27 // ctx must contain the current request segment as set by the xray middleware or 28 // the client passed as argument is returned. 29 func WrapClient(ctx context.Context, c *http.Client) Doer { 30 s := ContextSegment(ctx) 31 if s == nil { 32 return c 33 } 34 return &httpTracer{ 35 client: c, 36 segment: s, 37 } 38 } 39 40 // Do reates a subsegment and makes the request. 41 func (r *httpTracer) Do(req *http.Request) (*http.Response, error) { 42 sub := r.segment.NewSubsegment(req.URL.Host) 43 defer sub.Close() 44 sub.Namespace = "remote" 45 sub.HTTP = &HTTP{Request: requestData(req)} 46 47 resp, err := r.client.Do(req) 48 49 if err != nil { 50 sub.Fault = resp.StatusCode < http.StatusInternalServerError && 51 resp.StatusCode != http.StatusTooManyRequests 52 sub.RecordError(err) 53 return nil, err 54 } 55 sub.HTTP.Response = responseData(resp) 56 57 return resp, err 58 }