github.com/ManabuSeki/goa-v1@v1.4.3/middleware/xray/wrap_doer.go (about)

     1  package xray
     2  
     3  import (
     4  	"context"
     5  	"net/http"
     6  
     7  	"github.com/goadesign/goa/client"
     8  	"github.com/goadesign/goa/middleware"
     9  )
    10  
    11  // wrapDoer is a client.Doer middleware that will create xray subsegments for traced requests.
    12  type wrapDoer struct {
    13  	wrapped client.Doer
    14  }
    15  
    16  var _ client.Doer = (*wrapDoer)(nil)
    17  
    18  // WrapDoer wraps a goa client Doer, and creates xray subsegments for traced requests.
    19  func WrapDoer(wrapped client.Doer) client.Doer {
    20  	return &wrapDoer{wrapped}
    21  }
    22  
    23  // Do calls through to the wrapped Doer, creating subsegments as appropriate.
    24  func (r *wrapDoer) Do(ctx context.Context, req *http.Request) (*http.Response, error) {
    25  	s := ContextSegment(ctx)
    26  	if s == nil {
    27  		// this request isn't traced
    28  		return r.wrapped.Do(ctx, req)
    29  	}
    30  
    31  	sub := s.NewSubsegment(req.URL.Host)
    32  	sub.RecordRequest(req, "remote")
    33  	sub.SubmitInProgress()
    34  	defer sub.Close()
    35  
    36  	// update the context with the latest segment
    37  	ctx = middleware.WithTrace(ctx, sub.TraceID, sub.ID, sub.ParentID)
    38  	ctx = WithSegment(ctx, sub)
    39  
    40  	resp, err := r.wrapped.Do(ctx, req)
    41  
    42  	if err != nil {
    43  		sub.RecordError(err)
    44  	} else {
    45  		sub.RecordResponse(resp)
    46  	}
    47  
    48  	return resp, err
    49  }