@@ -3,6 +3,7 @@ package sqlstats
33
44import (
55 "context"
6+ "expvar"
67 "fmt"
78 "html"
89 "net/http"
@@ -21,6 +22,12 @@ import (
2122// To use, pass the tracer object to sqlite.Connector, then start a debug
2223// web server with http.HandlerFunc(sqlTracer.Handle).
2324type Tracer struct {
25+ TxCount * expvar.Map
26+ TxCommit * expvar.Map
27+ TxCommitError * expvar.Map
28+ TxRollback * expvar.Map
29+ TxTotalSeconds * expvar.Map
30+
2431 curTxs sync.Map // TraceConnID -> *connStats
2532
2633 // Once a query has been seen once, only the read lock
@@ -40,12 +47,26 @@ type connStats struct {
4047 readOnly bool
4148}
4249
43- func (s * connStats ) clear ( ) {
50+ func (t * Tracer ) done ( s * connStats ) ( why string , readOnly bool ) {
4451 s .mu .Lock ()
45- defer s .mu .Unlock ()
52+ why = s .why
53+ readOnly = s .readOnly
54+ at := s .at
4655 s .why = ""
4756 s .at = time.Time {}
4857 s .readOnly = false
58+ s .mu .Unlock ()
59+
60+ if t .TxTotalSeconds != nil {
61+ sec := time .Since (at ).Seconds ()
62+ t .TxTotalSeconds .AddFloat (why , sec )
63+ if readOnly {
64+ t .TxTotalSeconds .AddFloat ("read" , sec )
65+ } else {
66+ t .TxTotalSeconds .AddFloat ("write" , sec )
67+ }
68+ }
69+ return why , readOnly
4970}
5071
5172type queryStats struct {
@@ -128,16 +149,52 @@ func (t *Tracer) BeginTx(beginCtx context.Context, id sqliteh.TraceConnID, why s
128149 s .at = time .Now ()
129150 s .readOnly = readOnly
130151 s .mu .Unlock ()
152+
153+ if t .TxCount != nil {
154+ t .TxCount .Add (why , 1 )
155+ if readOnly {
156+ t .TxCount .Add ("read" , 1 )
157+ } else {
158+ t .TxCount .Add ("write" , 1 )
159+ }
160+ }
131161}
132162
133163func (t * Tracer ) Commit (id sqliteh.TraceConnID , err error ) {
134164 s := t .connStats (id )
135- s .clear ()
165+ why , readOnly := t .done (s )
166+ if err == nil {
167+ if t .TxCommit != nil {
168+ t .TxCommit .Add (why , 1 )
169+ if readOnly {
170+ t .TxCommit .Add ("read" , 1 )
171+ } else {
172+ t .TxCommit .Add ("write" , 1 )
173+ }
174+ }
175+ } else {
176+ if t .TxCommitError != nil {
177+ t .TxCommitError .Add (why , 1 )
178+ if readOnly {
179+ t .TxCommitError .Add ("read" , 1 )
180+ } else {
181+ t .TxCommitError .Add ("write" , 1 )
182+ }
183+ }
184+ }
136185}
137186
138187func (t * Tracer ) Rollback (id sqliteh.TraceConnID , err error ) {
139188 s := t .connStats (id )
140- s .clear ()
189+ why , readOnly := t .done (s )
190+ if t .TxRollback != nil {
191+ t .TxRollback .Add (why , 1 )
192+ if readOnly {
193+ t .TxRollback .Add ("read" , 1 )
194+ } else {
195+ t .TxRollback .Add ("write" , 1 )
196+ }
197+ }
141198}
142199
143200func (t * Tracer ) HandleConns (w http.ResponseWriter , r * http.Request ) {
0 commit comments