-
Notifications
You must be signed in to change notification settings - Fork 219
Expand file tree
/
Copy pathqueryz.go
More file actions
104 lines (90 loc) · 2.27 KB
/
queryz.go
File metadata and controls
104 lines (90 loc) · 2.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*
* Radon
*
* Copyright 2018 The Radon Authors.
* Code is licensed under the GPLv3.
*
* This code was derived from https://github.com/youtube/vitess.
*/
package backend
import (
"sort"
"sync"
"time"
"xbase"
)
// QueryDetail is a simple wrapper for Query
type QueryDetail struct {
ID uint64
connID uint32
query string
conn Connection
start time.Time
}
// NewQueryDetail creates a new QueryDetail
func NewQueryDetail(conn Connection, query string) *QueryDetail {
q := xbase.TruncateQuery(query, 256)
return &QueryDetail{conn: conn, connID: conn.ID(), query: q, start: time.Now()}
}
// Queryz holds a thread safe list of QueryDetails
type Queryz struct {
ID uint64
mu sync.RWMutex
queryDetails map[uint64]*QueryDetail
}
// NewQueryz creates a new Queryz
func NewQueryz() *Queryz {
return &Queryz{queryDetails: make(map[uint64]*QueryDetail)}
}
// Add adds a QueryDetail to Queryz
func (qz *Queryz) Add(qd *QueryDetail) {
qz.mu.Lock()
defer qz.mu.Unlock()
qz.ID++
qd.ID = qz.ID
qz.queryDetails[qd.ID] = qd
}
// Remove removes a QueryDetail from Queryz
func (qz *Queryz) Remove(qd *QueryDetail) {
qz.mu.Lock()
defer qz.mu.Unlock()
delete(qz.queryDetails, qd.ID)
}
// QueryDetailzRow is used for rendering QueryDetail in a template
type QueryDetailzRow struct {
Start time.Time
Duration time.Duration
ConnID uint32
Query string
Address string
Color string
}
type byStartTime []QueryDetailzRow
func (a byStartTime) Len() int { return len(a) }
func (a byStartTime) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a byStartTime) Less(i, j int) bool { return a[i].Start.Before(a[j].Start) }
// GetQueryzRows returns a list of QueryDetailzRow sorted by start time
func (qz *Queryz) GetQueryzRows() byStartTime {
qz.mu.RLock()
rows := []QueryDetailzRow{}
for _, qd := range qz.queryDetails {
row := QueryDetailzRow{
Query: qd.query,
Address: qd.conn.Address(),
Start: qd.start,
Duration: time.Since(qd.start),
ConnID: qd.connID,
}
if row.Duration < 10*time.Millisecond {
row.Color = "low"
} else if row.Duration < 100*time.Millisecond {
row.Color = "medium"
} else {
row.Color = "high"
}
rows = append(rows, row)
}
qz.mu.RUnlock()
sort.Sort(byStartTime(rows))
return rows
}