Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

logging: fix the HTTP logger #4041

Merged
merged 3 commits into from
Apr 10, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ We use _breaking :warning:_ to mark changes that are not backward compatible (re
- [#3960](https://github.com/thanos-io/thanos/pull/3960) fix deduplication of equal alerts with different labels
- [#3937](https://github.com/thanos-io/thanos/pull/3937) Store: Fix race condition in chunk pool.
- [#4017](https://github.com/thanos-io/thanos/pull/4017) Query Frontend: fix downsampling iterator returning duplicate samples.
- [#4017](https://github.com/thanos-io/thanos/pull/4041) Logging: fix the HTTP logger
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's mention what is the fix exactly 🤗


### Changed
- [#3929](https://github.com/thanos-io/thanos/pull/3929) Store: Adds the name of the instantiated memcached client to log info
Expand Down
6 changes: 5 additions & 1 deletion pkg/logging/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ func (m *HTTPServerMiddleware) HTTPMiddleware(name string, next http.Handler) ht
return func(w http.ResponseWriter, r *http.Request) {
wrapped := httputil.WrapResponseWriterWithStatus(w)
start := time.Now()
_, port, err := net.SplitHostPort(r.Host)
hostPort := r.Host
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What should we do, if both r.Host and r.URL.Host is set, which one should we display?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If r.Host is there, it will get priority. We are only using r.URL.Host if r.Host is an empty string.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can print anyone of them, as long one of them is non-empty.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the docs:

    // For client requests, the URL's Host specifies the server to
    // connect to, while the Request's Host field optionally
    // specifies the Host header value to send in the HTTP
    // request.

So, we should give priority to r.Host over r.URL.Host because r.Host might be more specific i.e. it's the Host header 😛

Copy link
Contributor

@yashrsharma44 yashrsharma44 Apr 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the current implementation is comprehensive 😄 !

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏽

if hostPort == "" {
hostPort = r.URL.Host
}
_, port, err := net.SplitHostPort(hostPort)
if err != nil {
level.Error(m.logger).Log("msg", "failed to parse host port for http log decision", "err", err)
next.ServeHTTP(w, r)
Expand Down
38 changes: 34 additions & 4 deletions pkg/logging/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,64 @@
package logging

import (
"bytes"
"io"
"io/ioutil"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"

"github.com/go-kit/kit/log"
"github.com/thanos-io/thanos/pkg/testutil"
)

func TestHTTPServerMiddleware(t *testing.T) {
m := NewHTTPServerMiddleware(log.NewNopLogger())
b := bytes.Buffer{}

m := NewHTTPServerMiddleware(log.NewLogfmtLogger(io.Writer(&b)))
handler := func(w http.ResponseWriter, r *http.Request) {
_, err := io.WriteString(w, "Test Works")
if err != nil {
t.Log(err)
testutil.Ok(t, err)
}
}
hm := m.HTTPMiddleware("test", http.HandlerFunc(handler))

req := httptest.NewRequest("GET", "http://example.com/foo", nil)
// Cortex way:
GiedriusS marked this conversation as resolved.
Show resolved Hide resolved
u, err := url.Parse("http://example.com:5555/foo")
testutil.Ok(t, err)
req := &http.Request{
Method: "GET",
URL: u,
Body: nil,
}

w := httptest.NewRecorder()

hm(w, req)

resp := w.Result()
body, _ := ioutil.ReadAll(resp.Body)
body, err := ioutil.ReadAll(resp.Body)
testutil.Ok(t, err)

testutil.Equals(t, 200, resp.StatusCode)
testutil.Equals(t, "Test Works", string(body))
testutil.Assert(t, !strings.Contains(b.String(), "err="))

// Typical way:
req = httptest.NewRequest("GET", "http://example.com:5555/foo", nil)
b.Reset()

w = httptest.NewRecorder()
hm(w, req)

resp = w.Result()
body, err = ioutil.ReadAll(resp.Body)
testutil.Ok(t, err)

testutil.Equals(t, 200, resp.StatusCode)
testutil.Equals(t, "Test Works", string(body))
testutil.Assert(t, !strings.Contains(b.String(), "err="))
}