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
Log failed query information in the query-frontend #3190
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you.
handler := NewHandler(test.cfg, roundTripper, logger, reg) | ||
|
||
ctx := user.InjectOrgID(context.Background(), "12345") | ||
req := httptest.NewRequest("GET", "/api/v1/query?query=up&time=2015-07-01T20:10:51.781Z", nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a test with no query parameters too, ie. GET /api/v1/query
. That should fail and log error message.
roundTripper := roundTripperFunc(func(req *http.Request) (*http.Response, error) { | ||
return nil, context.Canceled | ||
}) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should only be part of "Failed round trip with context cancelled"
test, not all tests.
pkg/frontend/transport/handler.go
Outdated
@@ -145,6 +145,8 @@ func (f *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { | |||
|
|||
if err != nil { | |||
writeError(w, err) | |||
queryString = f.parseRequestQueryString(r, buf) | |||
f.reportFailedQueryStats(r, queryString, queryResponseTime, stats) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we include the error in the log message?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also ask if we shouldn't include an err
field in the log.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some questions.
pkg/frontend/transport/handler.go
Outdated
func (f *Handler) reportFailedQuery(r *http.Request, queryString url.Values, queryResponseTime time.Duration, stats *querier_stats.Stats, err error) { | ||
// Log failed query info | ||
logMessage := append([]interface{}{ | ||
"msg", "failed query stats", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of having a different log message, what if we just reuse reportQueryStats()
(so that even partially collected information about the query complexity may be logged) and we add a status field to the log to track whether the query succeeded or failed? /cc @aknuds1 @56quarters @pstibrany
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't feel too strongly about this either way, was thinking it might be better to keep the failed query reporting quite lightweight, but if all the additional info is going to add a lot of value I can re-use reportQueryStats()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What @pracucci says sounds reasonable. The benefit of re-using reportQueryStats
(with error info) is you get all the same stats for failed queries. Is there any argument against calling reportQueryStats
for failed queries?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comments.
pkg/frontend/transport/handler.go
Outdated
func (f *Handler) reportFailedQuery(r *http.Request, queryString url.Values, queryResponseTime time.Duration, stats *querier_stats.Stats, err error) { | ||
// Log failed query info | ||
logMessage := append([]interface{}{ | ||
"msg", "failed query stats", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What @pracucci says sounds reasonable. The benefit of re-using reportQueryStats
(with error info) is you get all the same stats for failed queries. Is there any argument against calling reportQueryStats
for failed queries?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a suggestion.
2a8c0bb
to
1496bd6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but let's see if @pstibrany, @56quarters or @pracucci want to leave a review as well?
pkg/frontend/transport/handler.go
Outdated
logMessage = append(logMessage, []interface{}{ | ||
"status", "failed", | ||
"err", queryErr, | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we want to append these values as individual values, not within a slice, right? (same for else
condition)
logMessage = append(logMessage, []interface{}{ | |
"status", "failed", | |
"err", queryErr, | |
}) | |
logMessage = append(logMessage, | |
"status", "failed", | |
"err", queryErr, | |
) |
Adding assert assert.Contains(t, strings.TrimSpace(logs.String()), "status=failed")
to the test shows that this is currently broken.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, initially intended to append a slice to slice but forgot the ...
i.e
logMessage = append(logMessage, []interface{}{
"status", "failed",
"err", queryErr,
}...)
Will update to individual values like you suggested as it looks a bit cleaner
Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com>
399e095
to
8c1878d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
What this PR does
Logs useful information about the query in the case of a failed query (context cancelled etc) - current logging information was making it hard for other engineers to debug issues.
Which issue(s) this PR fixes or relates to
#3146
Fixes #3146
Checklist
CHANGELOG.md
updated - the order of entries should be[CHANGE]
,[FEATURE]
,[ENHANCEMENT]
,[BUGFIX]