func (t *RequestTrace) TraceRequest(r *request.Request) {
	t.Start = time.Now()
	r.Handlers.Complete.PushBack(t.onComplete)

	r.Handlers.Validate.PushFront(t.onValidateStart)
	r.Handlers.Validate.PushBack(t.onValidateDone)

	r.Handlers.Build.PushFront(t.onBuildStart)
	r.Handlers.Build.PushBack(t.onBuildDone)

	var attempt *RequestAttemptTrace

	// Signing and Start attempt
	r.Handlers.Sign.PushFront(func(rr *request.Request) {
		attempt = &RequestAttemptTrace{Start: time.Now()}
		attempt.SignStart = attempt.Start
	})
	r.Handlers.Sign.PushBack(func(rr *request.Request) {
		attempt.SignDone = time.Now()
	})

	// Ensure that the http trace added to the request always uses the original
	// context instead of each following attempt's context to prevent conflict
	// with previous http traces used.
	origContext := r.Context()

	// Send
	r.Handlers.Send.PushFront(func(rr *request.Request) {
		attempt.SendStart = time.Now()
		attempt.HTTPTrace = NewHTTPTrace(origContext)
		rr.SetContext(attempt.HTTPTrace)
	})
	r.Handlers.Send.PushBack(func(rr *request.Request) {
		attempt.SendDone = time.Now()
		defer func() {
			attempt.HTTPTrace.Finish = time.Now()
		}()

		if rr.Error != nil {
			return
		}

		attempt.HTTPTrace.ReadHeaderDone = time.Now()
		if t.ReadResponseBody {
			attempt.HTTPTrace.ReadBodyStart = time.Now()
			var w bytes.Buffer
			if _, err := io.Copy(&w, rr.HTTPResponse.Body); err != nil {
				rr.Error = err
				return
			}
			rr.HTTPResponse.Body.Close()
			rr.HTTPResponse.Body = ioutil.NopCloser(&w)

			attempt.HTTPTrace.ReadBodyDone = time.Now()
		}
	})

	// Unmarshal
	r.Handlers.Unmarshal.PushFront(func(rr *request.Request) {
		attempt.UnmarshalStart = time.Now()
	})
	r.Handlers.Unmarshal.PushBack(func(rr *request.Request) {
		attempt.UnmarshalDone = time.Now()
	})

	// Unmarshal Error
	r.Handlers.UnmarshalError.PushFront(func(rr *request.Request) {
		attempt.UnmarshalErrorStart = time.Now()
	})
	r.Handlers.UnmarshalError.PushBack(func(rr *request.Request) {
		attempt.UnmarshalErrorDone = time.Now()
	})

	// Retry handling and delay
	r.Handlers.Retry.PushFront(func(rr *request.Request) {
		attempt.RetryStart = time.Now()
		attempt.Err = rr.Error
	})
	r.Handlers.AfterRetry.PushBack(func(rr *request.Request) {
		attempt.RetryDone = time.Now()
		attempt.WillRetry = rr.WillRetry()
	})

	// Complete Attempt
	r.Handlers.CompleteAttempt.PushBack(func(rr *request.Request) {
		attempt.Finish = time.Now()
		t.Attempts = append(t.Attempts, attempt)
	})
}
// TraceRequest is a SDK request Option that will add request handlers to an
// individual request to track request latencies per attempt. Must be used only
// for a single request call per RequestTrace value.
TraceRequest is a SDK request Option that will add request handlers to an
individual request to track request latencies per attempt. Must be used only
for a single request call per RequestTrace value.
// TraceRequest is a SDK request Option that will add request handlers to an // individual request to track request latencies per attempt . Must be used only // for a single request call per RequestTrace value .
func (t *RequestTrace) TraceRequest(r *request.Request) {
	t.Start = time.Now()
	r.Handlers.Complete.PushBack(t.onComplete)
	r.Handlers.Validate.PushFront(t.onValidateStart)
	r.Handlers.Validate.PushBack(t.onValidateDone)
	r.Handlers.Build.PushFront(t.onBuildStart)
	r.Handlers.Build.PushBack(t.onBuildDone)
	var attempt *RequestAttemptTrace
	r.Handlers.Sign.PushFront(func(rr *request.Request) {
		attempt = &RequestAttemptTrace{Start: time.Now()}
		attempt.SignStart = attempt.Start
	})
	r.Handlers.Sign.PushBack(func(rr *request.Request) {
		attempt.SignDone = time.Now()
	})
	origContext := r.Context()
	r.Handlers.Send.PushFront(func(rr *request.Request) {
		attempt.SendStart = time.Now()
		attempt.HTTPTrace = NewHTTPTrace(origContext)
		rr.SetContext(attempt.HTTPTrace)
	})
	r.Handlers.Send.PushBack(func(rr *request.Request) {
		attempt.SendDone = time.Now()
		defer func() {
			attempt.HTTPTrace.Finish = time.Now()
		}()
		if rr.Error != nil {
			return
		}
		attempt.HTTPTrace.ReadHeaderDone = time.Now()
		if t.ReadResponseBody {
			attempt.HTTPTrace.ReadBodyStart = time.Now()
			var w bytes.Buffer
			if _, err := io.Copy(&w, rr.HTTPResponse.Body); err != nil {
				rr.Error = err
				return
			}
			rr.HTTPResponse.Body.Close()
			rr.HTTPResponse.Body = ioutil.NopCloser(&w)
			attempt.HTTPTrace.ReadBodyDone = time.Now()
		}
	})
	r.Handlers.Unmarshal.PushFront(func(rr *request.Request) {
		attempt.UnmarshalStart = time.Now()
	})
	r.Handlers.Unmarshal.PushBack(func(rr *request.Request) {
		attempt.UnmarshalDone = time.Now()
	})
	 Error
	r.Handlers.UnmarshalError.PushFront(func(rr *request.Request) {
		attempt.UnmarshalErrorStart = time.Now()
	})
	r.Handlers.UnmarshalError.PushBack(func(rr *request.Request) {
		attempt.UnmarshalErrorDone = time.Now()
	})
	r.Handlers.Retry.PushFront(func(rr *request.Request) {
		attempt.RetryStart = time.Now()
		attempt.Err = rr.Error
	})
	r.Handlers.AfterRetry.PushBack(func(rr *request.Request) {
		attempt.RetryDone = time.Now()
		attempt.WillRetry = rr.WillRetry()
	})
	r.Handlers.CompleteAttempt.PushBack(func(rr *request.Request) {
		attempt.Finish = time.Now()
		t.Attempts = append(t.Attempts, attempt)
	})
}
func ( t * RequestTrace ) TraceRequest ( r * request . Request ) { t . Start = time . Now ( ) r . Handlers . Complete . PushBack ( t . onComplete ) r . Handlers . Validate . PushFront ( t . onValidateStart ) r . Handlers . Validate . PushBack ( t . onValidateDone ) r . Handlers . Build . PushFront ( t . onBuildStart ) r . Handlers . Build . PushBack ( t . onBuildDone ) var attempt * RequestAttemptTrace r . Handlers . Sign . PushFront ( func ( rr * request . Request ) { attempt = & RequestAttemptTrace { Start : time . Now ( ) } attempt . SignStart = attempt . Start } ) r . Handlers . Sign . PushBack ( func ( rr * request . Request ) { attempt . SignDone = time . Now ( ) } ) origContext := r . Context ( ) r . Handlers . Send . PushFront ( func ( rr * request . Request ) { attempt . SendStart = time . Now ( ) attempt . HTTPTrace = NewHTTPTrace ( origContext ) rr . SetContext ( attempt . HTTPTrace ) } ) r . Handlers . Send . PushBack ( func ( rr * request . Request ) { attempt . SendDone = time . Now ( ) defer func ( ) { attempt . HTTPTrace . Finish = time . Now ( ) } ( ) if rr . Error != nil { return } attempt . HTTPTrace . ReadHeaderDone = time . Now ( ) if t . ReadResponseBody { attempt . HTTPTrace . ReadBodyStart = time . Now ( ) var w bytes . Buffer if _ , err := io . Copy ( & w , rr . HTTPResponse . Body ) ; err != nil { rr . Error = err return } rr . HTTPResponse . Body . Close ( ) rr . HTTPResponse . Body = ioutil . NopCloser ( & w ) attempt . HTTPTrace . ReadBodyDone = time . Now ( ) } } ) r . Handlers . Unmarshal . PushFront ( func ( rr * request . Request ) { attempt . UnmarshalStart = time . Now ( ) } ) r . Handlers . Unmarshal . PushBack ( func ( rr * request . Request ) { attempt . UnmarshalDone = time . Now ( ) } ) r . Handlers . UnmarshalError . PushFront ( func ( rr * request . Request ) { attempt . UnmarshalErrorStart = time . Now ( ) } ) r . Handlers . UnmarshalError . PushBack ( func ( rr * request . Request ) { attempt . UnmarshalErrorDone = time . Now ( ) } ) r . Handlers . Retry . PushFront ( func ( rr * request . Request ) { attempt . RetryStart = time . Now ( ) attempt . Err = rr . Error } ) r . Handlers . AfterRetry . PushBack ( func ( rr * request . Request ) { attempt . RetryDone = time . Now ( ) attempt . WillRetry = rr . WillRetry ( ) } ) r . Handlers . CompleteAttempt . PushBack ( func ( rr * request . Request ) { attempt . Finish = time . Now ( ) t . Attempts = append ( t . Attempts , attempt ) } ) }
TraceRequest is a SDK request Option that will add request handlers to an
individual request to track request latencies per attempt.
TraceRequest is a SDK request Option that will add request handlers to an individual request to track request latencies per attempt .
// Signing and Start attempt // Ensure that the http trace added to the request always uses the original // context instead of each following attempt's context to prevent conflict // with previous http traces used. // Send // Unmarshal // Unmarshal Error // Retry handling and delay // Complete Attempt