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  }