@@ -38,7 +38,7 @@ type Tracer struct {
3838 // in the steady state, a sync.Map would be a faster object
3939 // here.
4040 mu sync.RWMutex
41- queries map [string ]* QueryStats // normalized query -> stats
41+ queries map [string ]* queryStats // normalized query -> stats
4242}
4343
4444// Reset resets the state of t to its initial conditions.
@@ -101,8 +101,6 @@ func (t *Tracer) done(s *connStats) (why string, readOnly bool) {
101101type QueryStats struct {
102102 Query string
103103
104- // When inside the queries map all fields must be accessed as atomics.
105-
106104 // Count represents the number of times this query has been
107105 // executed.
108106 Count int64
@@ -116,8 +114,23 @@ type QueryStats struct {
116114
117115 // MeanDuration represents the average time spent executing the query.
118116 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
119123
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
121134}
122135
123136var rxRemoveInClause = regexp .MustCompile (`(?i)\s+in\s*\((?:\s*\d+\s*(?:,\s*\d+\s*)*)\)` )
@@ -129,7 +142,7 @@ func normalizeQuery(q string) string {
129142 return q
130143}
131144
132- func (t * Tracer ) queryStats (query string ) * QueryStats {
145+ func (t * Tracer ) queryStats (query string ) * queryStats {
133146 query = normalizeQuery (query )
134147
135148 t .mu .RLock ()
@@ -143,11 +156,11 @@ func (t *Tracer) queryStats(query string) *QueryStats {
143156 t .mu .Lock ()
144157 defer t .mu .Unlock ()
145158 if t .queries == nil {
146- t .queries = make (map [string ]* QueryStats )
159+ t .queries = make (map [string ]* queryStats )
147160 }
148161 stats = t .queries [query ]
149162 if stats == nil {
150- stats = & QueryStats {Query : query }
163+ stats = & queryStats {Query : query }
151164 t .queries [query ] = stats
152165 }
153166 return stats
@@ -161,15 +174,15 @@ func (t *Tracer) Collect() (rows []*QueryStats) {
161174
162175 rows = make ([]* QueryStats , 0 , len (t .queries ))
163176 for query , s := range t .queries {
164- row := QueryStats {
177+ row := & QueryStats {
165178 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 ( )),
169182 }
170183
171184 row .MeanDuration = time .Duration (int64 (row .TotalDuration ) / row .Count )
172- rows = append (rows , & row )
185+ rows = append (rows , row )
173186 }
174187 return rows
175188}
@@ -183,11 +196,11 @@ func (t *Tracer) Query(
183196) {
184197 stats := t .queryStats (query )
185198
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 ))
188201
189202 if err != nil {
190- atomic . AddInt64 ( & stats .Errors , 1 )
203+ stats .Errors . Add ( 1 )
191204 }
192205}
193206
@@ -349,11 +362,15 @@ func (t *Tracer) Handle(w http.ResponseWriter, r *http.Request) {
349362 </tr>
350363 ` )
351364 for _ , row := range rows {
365+ d := row .MeanDuration .Round (time .Microsecond )
366+ if d > 1 * time .Millisecond {
367+ d = d .Round (time .Millisecond )
368+ }
352369 fmt .Fprintf (w , "<tr><td>%s</td><td>%d</td><td>%s</td><td>%s</td><td>%d</td></tr>\n " ,
353370 row .Query ,
354371 row .Count ,
355372 row .TotalDuration .Round (time .Second ),
356- row . MeanDuration . Round ( time . Millisecond ) ,
373+ d ,
357374 row .Errors ,
358375 )
359376 }
0 commit comments