req
req copied to clipboard
Is it safe to call client.SetLogger(logger) concurrently?
Dear @imroc
My server is using zap logger. The logger is set to log correlation id of every inbound http request. My handlers for handling these inbound http requests use req http client. I want the call client.SetLogger(logger) concurrently on the same client (the looger logs the correlation id of different requests) so that the req http client also logs the correlation id.
Or should I create a new req client for different inboud http requests? Or, is it possible to write trace info into the dump file?
It's safe but may not work as expected due to the concurrency. Generally, client level setting should not call concurrently. you can enable dump at request level, get the dump string and write it with your correlation id anywhere you want.
ref: https://req.cool/docs/tutorial/debugging/#dump-the-content
You can also enable dump at request level, which will not override the client-level dump setting, it will dump to the internal buffer and do not print to stdout by default, you can call Response.Dump() to get the dump result and print only if you want to, typically used in production, only record the content of the request when the request is abnormal to help us troubleshoot problems
Thanks imroc! By the way, is resp.Body.Close() below still needed?
resp, err := httpClient.R().Get(url) if err != nil { this.Logger.Error(fmt.Sprintf("failed to fetch the page: %v", err)) return "", errors.New("httpClient.GetError") } defer resp.Body.Close() // is this still needed?
No, it's been closed automatically if you don't read resp.Body manually.
@imroc should I close the resp.Body manually in the following code snippet?
func middlewareDumpReqAndResp(client *req.Client, resp *req.Response) error {
ctx := resp.Request.Context()
logger := logger.GetLoggerFromCtx(ctx)
respBody, err := io.ReadAll(io.Reader(resp.Body))
if err != nil {
err = errors.New(fmt.Sprint("get response payload body failed: ", err.Error()))
logger.Error(err.Error())
panic(err.Error())
}
resp.Body = io.NopCloser(io.Reader(bytes.NewBuffer(respBody)))
logger.Info(fmt.Sprintf("request url: %s \n request body: %s \n response body: %s", resp.Request.RawURL, string(resp.Request.Body), string(respBody)))
return nil
}
@imroc should I close the resp.Body manually in the following code snippet?
func middlewareDumpReqAndResp(client *req.Client, resp *req.Response) error { ctx := resp.Request.Context() logger := logger.GetLoggerFromCtx(ctx) respBody, err := io.ReadAll(io.Reader(resp.Body)) if err != nil { err = errors.New(fmt.Sprint("get response payload body failed: ", err.Error())) logger.Error(err.Error()) panic(err.Error()) } resp.Body = io.NopCloser(io.Reader(bytes.NewBuffer(respBody))) logger.Info(fmt.Sprintf("request url: %s \n request body: %s \n response body: %s", resp.Request.RawURL, string(resp.Request.Body), string(respBody))) return nil }
Unnecessary