Repository: go-resty/resty
Pull request #584 (2022-09-30 04:21:06)

feat: add SetLogger() method on Request
Working to integrate resty with [xop](https://github.com/muir/xop-go), I need request-scoped logs.  My need would be replicated by anyone else working to integrate resty with span/trace-based logging.



codecov[bot]: # [Codecov](https://codecov.io/gh/go-resty/resty/pull/584?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-resty) Report
> Merging [#584](https://codecov.io/gh/go-resty/resty/pull/584?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-resty) (e58935e) into [master](https://codecov.io/gh/go-resty/resty/commit/840c825f188beb3973aafd66f8b1bc1d5ad4ee46?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-resty) (840c825) will **increase** coverage by `0.01%`.
> The diff coverage is `100.00%`.

```diff
@@            Coverage Diff             @@
##           master     #584      +/-   ##
==========================================
+ Coverage   95.85%   95.86%   +0.01%     
==========================================
  Files          10       10              
  Lines        1326     1330       +4     
==========================================
+ Hits         1271     1275       +4     
  Misses         34       34              
  Partials       21       21              
```


| [Impacted Files](https://codecov.io/gh/go-resty/resty/pull/584?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-resty) | Coverage Δ | |
|---|---|---|
| [client.go](https://codecov.io/gh/go-resty/resty/pull/584?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-resty#diff-Y2xpZW50Lmdv) | `97.64% <100.00%> (+<0.01%)` | :arrow_up: |
| [middleware.go](https://codecov.io/gh/go-resty/resty/pull/584?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-resty#diff-bWlkZGxld2FyZS5nbw==) | `91.27% <100.00%> (ø)` | |
| [request.go](https://codecov.io/gh/go-resty/resty/pull/584?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-resty#diff-cmVxdWVzdC5nbw==) | `95.32% <100.00%> (+0.05%)` | :arrow_up: |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-resty). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-resty)


Patch:
diff --git a/client.go b/client.go
index 1a03efa..aa96070 100644
--- a/client.go
+++ b/client.go
@@ -390,6 +390,7 @@ func (c *Client) R() *Request {
 		multipartFields: []*MultipartField{},
 		PathParams:      map[string]string{},
 		jsonEscapeHTML:  true,
+		log:             c.log,
 	}
 	return r
 }
diff --git a/middleware.go b/middleware.go
index e11e4d7..2e311d9 100644
--- a/middleware.go
+++ b/middleware.go
@@ -233,7 +233,7 @@ func addCredentials(c *Client, r *Request) error {
 
 	if !c.DisableWarn {
 		if isBasicAuth && !strings.HasPrefix(r.URL, "https") {
-			c.log.Warnf("Using Basic Auth in HTTP mode is not secure, use HTTPS")
+			r.log.Warnf("Using Basic Auth in HTTP mode is not secure, use HTTPS")
 		}
 	}
 
@@ -311,7 +311,7 @@ func responseLogger(c *Client, res *Response) error {
 		}
 		debugLog += "==============================================================================\n"
 
-		c.log.Debugf("%s", debugLog)
+		res.Request.log.Debugf("%s", debugLog)
 	}
 
 	return nil
diff --git a/request.go b/request.go
index e2f9aed..585bf93 100644
--- a/request.go
+++ b/request.go
@@ -65,6 +65,7 @@ type Request struct {
 	client              *Client
 	bodyBuf             *bytes.Buffer
 	clientTrace         *clientTrace
+	log                 Logger
 	multipartFiles      []*File
 	multipartFields     []*MultipartField
 	retryConditions     []RetryConditionFunc
@@ -212,7 +213,7 @@ func (r *Request) SetQueryString(query string) *Request {
 			}
 		}
 	} else {
-		r.client.log.Errorf("%v", err)
+		r.log.Errorf("%v", err)
 	}
 	return r
 }
@@ -596,6 +597,15 @@ func (r *Request) SetCookies(rs []*http.Cookie) *Request {
 	return r
 }
 
+// SetLogger method sets given writer for logging Resty request and response details.
+// By default, requests and responses inherit their logger from the client.
+//
+// Compliant to interface `resty.Logger`.
+func (r *Request) SetLogger(l Logger) *Request {
+	r.log = l
+	return r
+}
+
 // AddRetryCondition method adds a retry condition function to the request's
 // array of functions that are checked to determine if the request is retried.
 // The request will retry if any of the functions return true and error is nil.
@@ -770,7 +780,7 @@ func (r *Request) Execute(method, url string) (*Response, error) {
 
 			resp, err = r.client.execute(r)
 			if err != nil {
-				r.client.log.Errorf("%v, Attempt %v", err, r.Attempt)
+				r.log.Errorf("%v, Attempt %v", err, r.Attempt)
 			}
 
 			return resp, err


Test patch:
diff --git a/request_test.go b/request_test.go
index 06aef36..09e57f2 100644
--- a/request_test.go
+++ b/request_test.go
@@ -551,6 +551,32 @@ func TestRequestBasicAuth(t *testing.T) {
 	logResponse(t, resp)
 }
 
+func TestRequestInsecureBasicAuth(t *testing.T) {
+	ts := createAuthServerTLSOptional(t, false)
+	defer ts.Close()
+
+	var logBuf bytes.Buffer
+	logger := createLogger()
+	logger.l.SetOutput(&logBuf)
+
+	c := dc()
+	c.SetHostURL(ts.URL)
+
+	resp, err := c.R().
+		SetBasicAuth("myuser", "basicauth").
+		SetResult(&AuthSuccess{}).
+		SetLogger(logger).
+		Post("/login")
+
+	assertError(t, err)
+	assertEqual(t, http.StatusOK, resp.StatusCode())
+	assertEqual(t, true, strings.Contains(logBuf.String(), "WARN RESTY Using Basic Auth in HTTP mode is not secure, use HTTPS"))
+
+	t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
+	logResponse(t, resp)
+	t.Logf("captured request-level logs: %s", logBuf.String())
+}
+
 func TestRequestBasicAuthFail(t *testing.T) {
 	ts := createAuthServer(t)
 	defer ts.Close()
diff --git a/resty_test.go b/resty_test.go
index cd7b3b1..b815418 100644
--- a/resty_test.go
+++ b/resty_test.go
@@ -448,7 +448,11 @@ func createFilePostServer(t *testing.T) *httptest.Server {
 }
 
 func createAuthServer(t *testing.T) *httptest.Server {
-	ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+	return createAuthServerTLSOptional(t, true)
+}
+
+func createAuthServerTLSOptional(t *testing.T, useTLS bool) *httptest.Server {
+	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		t.Logf("Method: %v", r.Method)
 		t.Logf("Path: %v", r.URL.Path)
 		t.Logf("Content-Type: %v", r.Header.Get(hdrContentTypeKey))
@@ -498,9 +502,11 @@ func createAuthServer(t *testing.T) *httptest.Server {
 
 			return
 		}
-	}))
-
-	return ts
+	})
+	if useTLS {
+		return httptest.NewTLSServer(handler)
+	}
+	return httptest.NewServer(handler)
 }
 
 func createGenServer(t *testing.T) *httptest.Server {