Skip to content

Commit 32d8b00

Browse files
feat: show user when displaying or logging queries (#26981) (#26985)
To assist customers in debugging long-running queries, display the user that submitted them in the following situations: - SHOW QUERIES - For log-queries-after > 0 - log-timedout-queries is true - When termination-query-log is true Fixes #26980 (cherry picked from commit 1f5c2b8) Fixes #26984
1 parent 542ce7f commit 32d8b00

File tree

4 files changed

+27
-6
lines changed

4 files changed

+27
-6
lines changed

query/executor.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,9 @@ type ExecutionOptions struct {
201201

202202
// AbortCh is a channel that signals when results are no longer desired by the caller.
203203
AbortCh <-chan struct{}
204+
205+
// UserID is the ID of the user executing the query.
206+
UserID string
204207
}
205208

206209
type (
@@ -470,6 +473,7 @@ func (e *Executor) recover(query *influxql.Query, results chan *Result) {
470473
type Task struct {
471474
query string
472475
database string
476+
userID string
473477
status TaskStatus
474478
startTime time.Time
475479
closing chan struct{}

query/executor_test.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,8 @@ func TestQueryExecutor_Abort(t *testing.T) {
318318
}
319319

320320
func TestQueryExecutor_ShowQueries(t *testing.T) {
321+
const testUser = "Fred"
322+
const userColumn = 5
321323
e := NewQueryExecutor()
322324
e.StatementExecutor = &StatementExecutor{
323325
ExecuteStatementFn: func(stmt influxql.Statement, ctx *query.ExecutionContext) error {
@@ -336,12 +338,16 @@ func TestQueryExecutor_ShowQueries(t *testing.T) {
336338
t.Fatal(err)
337339
}
338340

339-
results := e.ExecuteQuery(q, query.ExecutionOptions{}, nil)
341+
results := e.ExecuteQuery(q, query.ExecutionOptions{UserID: testUser}, nil)
340342
result := <-results
341343
if len(result.Series) != 1 {
342344
t.Errorf("expected %d series, got %d", 1, len(result.Series))
343345
} else if len(result.Series[0].Values) != 1 {
344346
t.Errorf("expected %d row, got %d", 1, len(result.Series[0].Values))
347+
} else if result.Series[0].Values[0][userColumn] != testUser {
348+
t.Errorf("unexpected user: %s", result.Series[0].Values[0][0])
349+
} else if result.Series[0].Columns[userColumn] != "user" {
350+
t.Errorf("unexpected column: %s", result.Series[0].Columns[5])
345351
}
346352
if result.Err != nil {
347353
t.Errorf("unexpected error: %s", result.Err)

query/task_manager.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const (
3131
)
3232

3333
var (
34-
queryFieldNames []string = []string{"qid", "query", "database", "duration", "status"}
34+
queryFieldNames []string = []string{"qid", "query", "database", "duration", "status", "user"}
3535
)
3636

3737
func (t TaskStatus) String() string {
@@ -145,7 +145,7 @@ func (t *TaskManager) executeShowQueriesStatement(q *influxql.ShowQueriesStateme
145145

146146
d = prettyTime(d)
147147

148-
values = append(values, []interface{}{id, qi.query, qi.database, d.String(), qi.status.String()})
148+
values = append(values, []interface{}{id, qi.query, qi.database, d.String(), qi.status.String(), qi.userID})
149149
}
150150

151151
return []*models.Row{{
@@ -172,7 +172,8 @@ func (t *TaskManager) LogCurrentQueries(logFunc func(string, ...zap.Field)) {
172172
zap.String(queryFieldNames[1], queryInfo.Query),
173173
zap.String(queryFieldNames[2], queryInfo.Database),
174174
zap.String(queryFieldNames[3], prettyTime(queryInfo.Duration).String()),
175-
zap.String(queryFieldNames[4], queryInfo.Status.String()))
175+
zap.String(queryFieldNames[4], queryInfo.Status.String()),
176+
zap.String(queryFieldNames[5], queryInfo.User))
176177
}
177178
}
178179

@@ -208,6 +209,7 @@ func (t *TaskManager) AttachQuery(q *influxql.Query, opt ExecutionOptions, inter
208209
query := &Task{
209210
query: q.String(),
210211
database: opt.Database,
212+
userID: opt.UserID,
211213
status: RunningTask,
212214
startTime: time.Now(),
213215
closing: make(chan struct{}),
@@ -223,8 +225,8 @@ func (t *TaskManager) AttachQuery(q *influxql.Query, opt ExecutionOptions, inter
223225

224226
select {
225227
case <-timer.C:
226-
t.Logger.Warn(fmt.Sprintf("Detected slow query: %s (qid: %d, database: %s, threshold: %s)",
227-
query.query, qid, query.database, t.LogQueriesAfter))
228+
t.Logger.Warn(fmt.Sprintf("Detected slow query: %s (qid: %d, database: %s, user: %s, threshold: %s)",
229+
query.query, qid, query.database, query.userID, t.LogQueriesAfter))
228230
case <-closing:
229231
}
230232
return nil
@@ -279,6 +281,7 @@ type QueryInfo struct {
279281
Database string `json:"database"`
280282
Duration time.Duration `json:"duration"`
281283
Status TaskStatus `json:"status"`
284+
User string `json:"user"`
282285
}
283286

284287
// Queries returns a list of all running queries with information about them.
@@ -295,6 +298,7 @@ func (t *TaskManager) Queries() []QueryInfo {
295298
Database: qi.database,
296299
Duration: now.Sub(qi.startTime),
297300
Status: qi.status,
301+
User: qi.userID,
298302
})
299303
}
300304
return queries
@@ -323,6 +327,7 @@ func (t *TaskManager) waitForQuery(qid uint64, interrupt <-chan struct{}, closin
323327
"query killed for exceeding timeout limit",
324328
zap.String("query", t.queries[qid].query),
325329
zap.String("database", t.queries[qid].database),
330+
zap.String("user", t.queries[qid].userID),
326331
zap.String("timeout", prettyTime(t.QueryTimeout).String()),
327332
)
328333
}

services/httpd/handler.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,13 +685,19 @@ func (h *Handler) serveQuery(w http.ResponseWriter, r *http.Request, user meta.U
685685
// Parse whether this is an async command.
686686
async := r.FormValue("async") == "true"
687687

688+
var userName string
689+
690+
if user != nil {
691+
userName = user.ID()
692+
}
688693
opts := query.ExecutionOptions{
689694
Database: db,
690695
RetentionPolicy: r.FormValue("rp"),
691696
ChunkSize: chunkSize,
692697
ReadOnly: r.Method == "GET",
693698
NodeID: nodeID,
694699
Authorizer: fineAuthorizer,
700+
UserID: userName,
695701
}
696702

697703
if h.Config.AuthEnabled {

0 commit comments

Comments
 (0)