Support to dump request/response in router when debug mode enabled (#2119)
Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>
This commit is contained in:
@@ -176,8 +176,6 @@ func (roundTripper *RetryingRoundTripper) RoundTrip(req *http.Request) (*http.Re
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
roundTripper.logger.Debug("request headers", zap.Any("headers", req.Header))
|
|
||||||
|
|
||||||
// The reason for request failure may vary from case to case.
|
// The reason for request failure may vary from case to case.
|
||||||
// After some investigation, found most of the failure are due to
|
// After some investigation, found most of the failure are due to
|
||||||
// network timeout or target function is under heavy workload. In
|
// network timeout or target function is under heavy workload. In
|
||||||
@@ -192,6 +190,31 @@ func (roundTripper *RetryingRoundTripper) RoundTrip(req *http.Request) (*http.Re
|
|||||||
var err error
|
var err error
|
||||||
var fnMeta = &roundTripper.funcHandler.function.ObjectMeta
|
var fnMeta = &roundTripper.funcHandler.function.ObjectMeta
|
||||||
|
|
||||||
|
logger := roundTripper.logger.With(zap.String("function", fnMeta.Name), zap.String("namespace", fnMeta.Namespace))
|
||||||
|
|
||||||
|
dumpReqFunc := func(request *http.Request) {
|
||||||
|
if request == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
reqMsg, err := httputil.DumpRequest(request, false)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("failed to dump request", zap.Error(err))
|
||||||
|
} else {
|
||||||
|
logger.Debug("round tripper request", zap.String("request", string(reqMsg)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dumpRespFunc := func(response *http.Response) {
|
||||||
|
if response == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
respMsg, err := httputil.DumpResponse(response, false)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("failed to dump response", zap.Error(err))
|
||||||
|
} else {
|
||||||
|
logger.Debug("round tripper response", zap.String("response", string(respMsg)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for i := 0; i < roundTripper.funcHandler.tsRoundTripperParams.maxRetries; i++ {
|
for i := 0; i < roundTripper.funcHandler.tsRoundTripperParams.maxRetries; i++ {
|
||||||
// set service url of target service of request only when
|
// set service url of target service of request only when
|
||||||
// trying to get new service url from cache/executor.
|
// trying to get new service url from cache/executor.
|
||||||
@@ -220,7 +243,7 @@ func (roundTripper *RetryingRoundTripper) RoundTrip(req *http.Request) (*http.Re
|
|||||||
return nil, ferror.MakeError(http.StatusInternalServerError, err.Error())
|
return nil, ferror.MakeError(http.StatusInternalServerError, err.Error())
|
||||||
}
|
}
|
||||||
if roundTripper.serviceURL == nil {
|
if roundTripper.serviceURL == nil {
|
||||||
roundTripper.logger.Warn("serviceURL is empty for function, retrying", zap.Duration("executingTimeout", executingTimeout))
|
logger.Warn("serviceURL is empty for function, retrying", zap.Duration("executingTimeout", executingTimeout))
|
||||||
time.Sleep(executingTimeout)
|
time.Sleep(executingTimeout)
|
||||||
executingTimeout = executingTimeout * time.Duration(roundTripper.funcHandler.tsRoundTripperParams.timeoutExponent)
|
executingTimeout = executingTimeout * time.Duration(roundTripper.funcHandler.tsRoundTripperParams.timeoutExponent)
|
||||||
continue
|
continue
|
||||||
@@ -274,19 +297,29 @@ func (roundTripper *RetryingRoundTripper) RoundTrip(req *http.Request) (*http.Re
|
|||||||
// will be canceled when calling setContext.
|
// will be canceled when calling setContext.
|
||||||
newReq := roundTripper.setContext(req)
|
newReq := roundTripper.setContext(req)
|
||||||
|
|
||||||
|
if roundTripper.funcHandler.isDebugEnv {
|
||||||
|
dumpReqFunc(newReq)
|
||||||
|
}
|
||||||
|
|
||||||
// forward the request to the function service
|
// forward the request to the function service
|
||||||
resp, err := ocRoundTripper.RoundTrip(newReq)
|
resp, err := ocRoundTripper.RoundTrip(newReq)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// return response back to user
|
// return response back to user
|
||||||
|
if roundTripper.funcHandler.isDebugEnv {
|
||||||
|
dumpRespFunc(resp)
|
||||||
|
}
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if roundTripper.funcHandler.isDebugEnv && resp != nil {
|
||||||
|
dumpRespFunc(resp)
|
||||||
|
}
|
||||||
|
|
||||||
roundTripper.totalRetry++
|
roundTripper.totalRetry++
|
||||||
|
|
||||||
if i >= roundTripper.funcHandler.tsRoundTripperParams.maxRetries-1 {
|
if i >= roundTripper.funcHandler.tsRoundTripperParams.maxRetries-1 {
|
||||||
// return here if we are in the last round
|
// return here if we are in the last round
|
||||||
roundTripper.logger.Error("error getting response from function",
|
logger.Error("error getting response from function",
|
||||||
zap.String("function_name", fnMeta.Name),
|
|
||||||
zap.Error(err))
|
zap.Error(err))
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -303,7 +336,7 @@ func (roundTripper *RetryingRoundTripper) RoundTrip(req *http.Request) (*http.Re
|
|||||||
|
|
||||||
// if transport.RoundTrip returns a non-network dial error (e.g. "context canceled"), then relay it back to user
|
// if transport.RoundTrip returns a non-network dial error (e.g. "context canceled"), then relay it back to user
|
||||||
if !isNetDialErr {
|
if !isNetDialErr {
|
||||||
roundTripper.logger.Error("encountered non-network dial error", zap.Error(err))
|
logger.Error("encountered non-network dial error", zap.Error(err))
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,16 +347,15 @@ func (roundTripper *RetryingRoundTripper) RoundTrip(req *http.Request) (*http.Re
|
|||||||
|
|
||||||
// Check whether an error is an timeout error ("dial tcp i/o timeout").
|
// Check whether an error is an timeout error ("dial tcp i/o timeout").
|
||||||
if isNetTimeoutErr {
|
if isNetTimeoutErr {
|
||||||
roundTripper.logger.Debug("request errored out - backing off before retrying",
|
logger.Debug("request errored out - backing off before retrying",
|
||||||
zap.String("url", req.URL.Host),
|
zap.String("url", req.URL.Host),
|
||||||
zap.String("function_name", fnMeta.Name),
|
|
||||||
zap.Error(err))
|
zap.Error(err))
|
||||||
retryCounter++
|
retryCounter++
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it's not a timeout error or retryCounter exceeded pre-defined threshold,
|
// If it's not a timeout error or retryCounter exceeded pre-defined threshold,
|
||||||
if retryCounter >= roundTripper.funcHandler.tsRoundTripperParams.svcAddrRetryCount {
|
if retryCounter >= roundTripper.funcHandler.tsRoundTripperParams.svcAddrRetryCount {
|
||||||
roundTripper.logger.Debug(fmt.Sprintf(
|
logger.Debug(fmt.Sprintf(
|
||||||
"retry counter exceeded pre-defined threshold of %v",
|
"retry counter exceeded pre-defined threshold of %v",
|
||||||
roundTripper.funcHandler.tsRoundTripperParams.svcAddrRetryCount))
|
roundTripper.funcHandler.tsRoundTripperParams.svcAddrRetryCount))
|
||||||
if roundTripper.urlFromCache {
|
if roundTripper.urlFromCache {
|
||||||
@@ -332,13 +364,13 @@ func (roundTripper *RetryingRoundTripper) RoundTrip(req *http.Request) (*http.Re
|
|||||||
retryCounter = 0
|
retryCounter = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
roundTripper.logger.Debug("Backing off before retrying", zap.Any("backoff_time", executingTimeout), zap.Error(err))
|
logger.Debug("Backing off before retrying", zap.Duration("backoff_time", executingTimeout), zap.Error(err))
|
||||||
time.Sleep(executingTimeout)
|
time.Sleep(executingTimeout)
|
||||||
executingTimeout = executingTimeout * time.Duration(roundTripper.funcHandler.tsRoundTripperParams.timeoutExponent)
|
executingTimeout = executingTimeout * time.Duration(roundTripper.funcHandler.tsRoundTripperParams.timeoutExponent)
|
||||||
}
|
}
|
||||||
|
|
||||||
e := errors.New("Unable to get service url for connection")
|
e := errors.New("Unable to get service url for connection")
|
||||||
roundTripper.logger.Error(e.Error(), zap.String("function_name", fnMeta.Name))
|
logger.Error(e.Error())
|
||||||
return nil, e
|
return nil, e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user