@@ -38,7 +38,7 @@ type Tracer struct {
38
38
// in the steady state, a sync.Map would be a faster object
39
39
// here.
40
40
mu sync.RWMutex
41
- queries map [string ]* QueryStats // normalized query -> stats
41
+ queries map [string ]* queryStats // normalized query -> stats
42
42
}
43
43
44
44
// Reset resets the state of t to its initial conditions.
@@ -101,8 +101,6 @@ func (t *Tracer) done(s *connStats) (why string, readOnly bool) {
101
101
type QueryStats struct {
102
102
Query string
103
103
104
- // When inside the queries map all fields must be accessed as atomics.
105
-
106
104
// Count represents the number of times this query has been
107
105
// executed.
108
106
Count int64
@@ -116,8 +114,23 @@ type QueryStats struct {
116
114
117
115
// MeanDuration represents the average time spent executing the query.
118
116
MeanDuration time.Duration
117
+ }
118
+
119
+ // queryStats is the internal stats for a given Query containing
120
+ // atomics and updated at runtime.
121
+ type queryStats struct {
122
+ Query string
119
123
120
- // TODO lastErr atomic.Value
124
+ // Count represents the number of times this query has been
125
+ // executed.
126
+ Count atomic.Int64
127
+
128
+ // Errors represents the number of errors encountered executing
129
+ // this query.
130
+ Errors atomic.Int64
131
+
132
+ // TotalDurationNanos represents the accumulated time spent executing the query.
133
+ TotalDurationNanos atomic.Int64 // a time.Duration in nanoseconds
121
134
}
122
135
123
136
var rxRemoveInClause = regexp .MustCompile (`(?i)\s+in\s*\((?:\s*\d+\s*(?:,\s*\d+\s*)*)\)` )
@@ -129,7 +142,7 @@ func normalizeQuery(q string) string {
129
142
return q
130
143
}
131
144
132
- func (t * Tracer ) queryStats (query string ) * QueryStats {
145
+ func (t * Tracer ) queryStats (query string ) * queryStats {
133
146
query = normalizeQuery (query )
134
147
135
148
t .mu .RLock ()
@@ -143,11 +156,11 @@ func (t *Tracer) queryStats(query string) *QueryStats {
143
156
t .mu .Lock ()
144
157
defer t .mu .Unlock ()
145
158
if t .queries == nil {
146
- t .queries = make (map [string ]* QueryStats )
159
+ t .queries = make (map [string ]* queryStats )
147
160
}
148
161
stats = t .queries [query ]
149
162
if stats == nil {
150
- stats = & QueryStats {Query : query }
163
+ stats = & queryStats {Query : query }
151
164
t .queries [query ] = stats
152
165
}
153
166
return stats
@@ -161,15 +174,15 @@ func (t *Tracer) Collect() (rows []*QueryStats) {
161
174
162
175
rows = make ([]* QueryStats , 0 , len (t .queries ))
163
176
for query , s := range t .queries {
164
- row := QueryStats {
177
+ row := & QueryStats {
165
178
Query : query ,
166
- Count : atomic . LoadInt64 ( & s .Count ),
167
- Errors : atomic . LoadInt64 ( & s .Errors ),
168
- TotalDuration : time .Duration (atomic . LoadInt64 (( * int64 )( & s . TotalDuration ) )),
179
+ Count : s .Count . Load ( ),
180
+ Errors : s .Errors . Load ( ),
181
+ TotalDuration : time .Duration (s . TotalDurationNanos . Load ( )),
169
182
}
170
183
171
184
row .MeanDuration = time .Duration (int64 (row .TotalDuration ) / row .Count )
172
- rows = append (rows , & row )
185
+ rows = append (rows , row )
173
186
}
174
187
return rows
175
188
}
@@ -183,11 +196,11 @@ func (t *Tracer) Query(
183
196
) {
184
197
stats := t .queryStats (query )
185
198
186
- atomic . AddInt64 ( & stats .Count , 1 )
187
- atomic . AddInt64 (( * int64 )( & stats .TotalDuration ), int64 (duration ))
199
+ stats .Count . Add ( 1 )
200
+ stats .TotalDurationNanos . Add ( int64 (duration ))
188
201
189
202
if err != nil {
190
- atomic . AddInt64 ( & stats .Errors , 1 )
203
+ stats .Errors . Add ( 1 )
191
204
}
192
205
}
193
206
@@ -349,11 +362,15 @@ func (t *Tracer) Handle(w http.ResponseWriter, r *http.Request) {
349
362
</tr>
350
363
` )
351
364
for _ , row := range rows {
365
+ d := row .MeanDuration .Round (time .Microsecond )
366
+ if d > 1 * time .Millisecond {
367
+ d = d .Round (time .Millisecond )
368
+ }
352
369
fmt .Fprintf (w , "<tr><td>%s</td><td>%d</td><td>%s</td><td>%s</td><td>%d</td></tr>\n " ,
353
370
row .Query ,
354
371
row .Count ,
355
372
row .TotalDuration .Round (time .Second ),
356
- row . MeanDuration . Round ( time . Millisecond ) ,
373
+ d ,
357
374
row .Errors ,
358
375
)
359
376
}
0 commit comments