Skip to content

Commit 86d5f52

Browse files
authored
Query Frontend: Fix slow query logging if 'LogQueriesLongerThan' is set to < 0 (#4633)
* Fix slow query log parameter if < 0 Signed-off-by: Matej Gera <[email protected]> * Update CHANGELOG Signed-off-by: Matej Gera <[email protected]> * Extend the query frontend tests Signed-off-by: Matej Gera <[email protected]>
1 parent 6408117 commit 86d5f52

File tree

3 files changed

+72
-44
lines changed

3 files changed

+72
-44
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
* [BUGFIX] Set appropriate `Content-Type` header for /services endpoint, which previously hard-coded `text/plain`. #4596
2727
* [BUGFIX] Querier: Disable query scheduler SRV DNS lookup, which removes noisy log messages about "failed DNS SRV record lookup". #4601
2828
* [BUGFIX] Memberlist: fixed corrupted packets when sending compound messages with more than 255 messages or messages bigger than 64KB. #4601
29+
* [BUGIX] Query Frontend: If 'LogQueriesLongerThan' is set to < 0, log all queries as described in the docs. #4633
2930

3031
## 1.11.0 2021-11-25
3132

pkg/frontend/frontend_test.go

+70-43
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func TestFrontend_RequestHostHeaderWhenDownstreamURLIsConfigured(t *testing.T) {
9393
testFrontend(t, config, nil, test, true, nil)
9494
}
9595

96-
func TestFrontend_LogsSlowQueriesFormValues(t *testing.T) {
96+
func TestFrontend_LogsSlowQueries(t *testing.T) {
9797
// Create an HTTP server listening locally. This server mocks the downstream
9898
// Prometheus API-compatible server.
9999
downstreamListen, err := net.Listen("tcp", "localhost:0")
@@ -109,50 +109,77 @@ func TestFrontend_LogsSlowQueriesFormValues(t *testing.T) {
109109
defer downstreamServer.Shutdown(context.Background()) //nolint:errcheck
110110
go downstreamServer.Serve(downstreamListen) //nolint:errcheck
111111

112-
// Configure the query-frontend with the mocked downstream server.
113-
config := defaultFrontendConfig()
114-
config.Handler.LogQueriesLongerThan = 1 * time.Microsecond
115-
config.DownstreamURL = fmt.Sprintf("http://%s", downstreamListen.Addr())
116-
117-
var buf concurrency.SyncBuffer
118-
l := log.NewLogfmtLogger(&buf)
119-
120-
test := func(addr string) {
121-
data := url.Values{}
122-
data.Set("test", "form")
123-
data.Set("issue", "3111")
124-
125-
req, _ := http.NewRequest(http.MethodPost, fmt.Sprintf("http://%s/?foo=bar", addr), strings.NewReader(data.Encode()))
126-
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
127-
req.Header.Add("Content-Length", strconv.Itoa(len(data.Encode())))
128-
129-
ctx := context.Background()
130-
req = req.WithContext(ctx)
131-
assert.NoError(t, err)
132-
err = user.InjectOrgIDIntoHTTPRequest(user.InjectOrgID(ctx, "1"), req)
133-
assert.NoError(t, err)
134-
135-
client := http.Client{
136-
Transport: &nethttp.Transport{},
137-
}
138-
139-
resp, err := client.Do(req)
140-
assert.NoError(t, err)
141-
b, err := ioutil.ReadAll(resp.Body)
142-
resp.Body.Close()
143-
144-
assert.NoError(t, err)
145-
assert.Equal(t, 200, resp.StatusCode, string(b))
146-
147-
logs := buf.String()
148-
assert.NotContains(t, logs, "unable to parse form for request")
149-
assert.Contains(t, logs, "msg=\"slow query detected\"")
150-
assert.Contains(t, logs, "param_issue=3111")
151-
assert.Contains(t, logs, "param_test=form")
152-
assert.Contains(t, logs, "param_foo=bar")
112+
tests := map[string]struct {
113+
longerThan time.Duration
114+
shouldLog bool
115+
}{
116+
"longer than set to > 0": {
117+
longerThan: 1 * time.Microsecond,
118+
shouldLog: true,
119+
},
120+
"longer than set to < 0": {
121+
longerThan: -1 * time.Microsecond,
122+
shouldLog: true,
123+
},
124+
"logging disabled": {
125+
longerThan: 0,
126+
shouldLog: false,
127+
},
153128
}
154129

155-
testFrontend(t, config, nil, test, false, l)
130+
for testName, testData := range tests {
131+
t.Run(testName, func(t *testing.T) {
132+
// Configure the query-frontend with the mocked downstream server.
133+
config := defaultFrontendConfig()
134+
config.Handler.LogQueriesLongerThan = testData.longerThan
135+
config.DownstreamURL = fmt.Sprintf("http://%s", downstreamListen.Addr())
136+
137+
var buf concurrency.SyncBuffer
138+
139+
test := func(addr string) {
140+
// To assert form values are logged as well.
141+
data := url.Values{}
142+
data.Set("test", "form")
143+
data.Set("issue", "3111")
144+
145+
req, _ := http.NewRequest(http.MethodPost, fmt.Sprintf("http://%s/?foo=bar", addr), strings.NewReader(data.Encode()))
146+
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
147+
req.Header.Add("Content-Length", strconv.Itoa(len(data.Encode())))
148+
149+
ctx := context.Background()
150+
req = req.WithContext(ctx)
151+
assert.NoError(t, err)
152+
err = user.InjectOrgIDIntoHTTPRequest(user.InjectOrgID(ctx, "1"), req)
153+
assert.NoError(t, err)
154+
155+
client := http.Client{
156+
Transport: &nethttp.Transport{},
157+
}
158+
159+
resp, err := client.Do(req)
160+
assert.NoError(t, err)
161+
b, err := ioutil.ReadAll(resp.Body)
162+
resp.Body.Close()
163+
164+
assert.NoError(t, err)
165+
assert.Equal(t, 200, resp.StatusCode, string(b))
166+
167+
logs := buf.String()
168+
assert.NotContains(t, logs, "unable to parse form for request")
169+
170+
if testData.shouldLog {
171+
assert.Contains(t, logs, "msg=\"slow query detected\"")
172+
assert.Contains(t, logs, "param_issue=3111")
173+
assert.Contains(t, logs, "param_test=form")
174+
assert.Contains(t, logs, "param_foo=bar")
175+
} else {
176+
assert.NotContains(t, logs, "msg=\"slow query detected\"")
177+
}
178+
}
179+
180+
testFrontend(t, config, nil, test, false, log.NewLogfmtLogger(&buf))
181+
})
182+
}
156183
}
157184

158185
func TestFrontend_ReturnsRequestBodyTooLargeError(t *testing.T) {

pkg/frontend/transport/handler.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ func (f *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
147147
_, _ = io.Copy(w, resp.Body)
148148

149149
// Check whether we should parse the query string.
150-
shouldReportSlowQuery := f.cfg.LogQueriesLongerThan > 0 && queryResponseTime > f.cfg.LogQueriesLongerThan
150+
shouldReportSlowQuery := f.cfg.LogQueriesLongerThan != 0 && queryResponseTime > f.cfg.LogQueriesLongerThan
151151
if shouldReportSlowQuery || f.cfg.QueryStatsEnabled {
152152
queryString = f.parseRequestQueryString(r, buf)
153153
}

0 commit comments

Comments
 (0)