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

Log failed query information in the query-frontend #3190

Merged
merged 12 commits into from Oct 17, 2022

Conversation

fayzal-g
Copy link
Contributor

@fayzal-g fayzal-g commented Oct 11, 2022

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

  • Tests updated
  • Documentation added
  • CHANGELOG.md updated - the order of entries should be [CHANGE], [FEATURE], [ENHANCEMENT], [BUGFIX]

@fayzal-g fayzal-g marked this pull request as ready for review October 11, 2022 11:53
@fayzal-g fayzal-g requested a review from a team as a code owner October 11, 2022 11:53
Copy link
Member

@pstibrany pstibrany left a 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)
Copy link
Member

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.

Comment on lines 115 to 132
roundTripper := roundTripperFunc(func(req *http.Request) (*http.Response, error) {
return nil, context.Canceled
})

Copy link
Member

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.

@@ -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)
Copy link
Member

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?

Copy link
Contributor

@aknuds1 aknuds1 Oct 11, 2022

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.

Copy link
Contributor

@aknuds1 aknuds1 left a comment

Choose a reason for hiding this comment

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

Left some questions.

CHANGELOG.md Outdated Show resolved Hide resolved
pkg/frontend/transport/handler.go Outdated Show resolved Hide resolved
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",
Copy link
Collaborator

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

Copy link
Contributor Author

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()

Copy link
Contributor

@aknuds1 aknuds1 Oct 12, 2022

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?

Copy link
Contributor

@aknuds1 aknuds1 left a 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 Show resolved Hide resolved
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",
Copy link
Contributor

@aknuds1 aknuds1 Oct 12, 2022

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?

pkg/frontend/transport/handler_test.go Outdated Show resolved Hide resolved
Copy link
Contributor

@aknuds1 aknuds1 left a comment

Choose a reason for hiding this comment

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

Left a suggestion.

pkg/frontend/transport/handler_test.go Outdated Show resolved Hide resolved
Copy link
Contributor

@aknuds1 aknuds1 left a 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?

Comment on lines 230 to 233
logMessage = append(logMessage, []interface{}{
"status", "failed",
"err", queryErr,
})
Copy link
Member

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)

Suggested change
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.

Copy link
Contributor Author

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

Copy link
Member

@pstibrany pstibrany left a comment

Choose a reason for hiding this comment

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

Thank you!

Copy link
Collaborator

@pracucci pracucci left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Query-frontend should log failed queries
5 participants