...
1 package debug
2
3 import (
4 "encoding/json"
5 "fmt"
6 "net/http"
7 "sync"
8 "time"
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 type Timer struct {
40 mutex sync.Mutex
41 count int
42 total time.Duration
43 min time.Duration
44 max time.Duration
45
46 clock func() time.Time
47 }
48
49
50 type ClockFunc func() time.Time
51
52
53 type StopFunc func()
54
55
56 func NewTimer() *Timer {
57 return NewTimerWithClock(time.Now)
58 }
59
60
61 func NewTimerWithClock(clock ClockFunc) *Timer {
62 return &Timer{
63 clock: clock,
64 }
65 }
66
67
68 func (t *Timer) Start() StopFunc {
69 start := t.clock()
70 return func() {
71 t.record(start, t.clock())
72 }
73 }
74
75
76 func (t *Timer) record(start time.Time, stop time.Time) {
77 t.withMutex(func() {
78 delta := stop.Sub(start)
79
80 if t.count == 0 {
81
82 t.min = delta
83 t.max = delta
84 } else {
85
86 if delta < t.min {
87 t.min = delta
88 }
89 if delta > t.max {
90 t.max = delta
91 }
92 }
93
94 t.count++
95 t.total += delta
96 })
97 }
98
99
100 func (t *Timer) withMutex(f func()) {
101 t.mutex.Lock()
102 defer t.mutex.Unlock()
103 f()
104 }
105
106
107
108 func (t *Timer) Copy() (result *Timer) {
109 t.withMutex(func() {
110 result = &Timer{}
111 *result = *t
112 result.mutex = sync.Mutex{}
113 })
114 return
115 }
116
117
118 func (t *Timer) Count() (result int) {
119 t.withMutex(func() {
120 result = t.count
121 })
122 return
123 }
124
125
126 func (t *Timer) Min() (result time.Duration) {
127 t.withMutex(func() {
128 result = t.min
129 })
130 return
131 }
132
133
134 func (t *Timer) Max() (result time.Duration) {
135 t.withMutex(func() {
136 result = t.max
137 })
138 return
139 }
140
141
142 func (t *Timer) Average() (result time.Duration) {
143 t.withMutex(func() {
144 if t.count > 0 {
145 result = t.total / time.Duration(t.count)
146 } else {
147 result = 0
148 }
149 })
150 return
151 }
152
153
154 func (t *Timer) Total() (result time.Duration) {
155 t.withMutex(func() {
156 result = t.total
157 })
158 return
159 }
160
161
162 func (t *Timer) Time(f func()) {
163 defer t.Start()()
164 f()
165 }
166
167
168 func (t *Timer) TimedHandler(h http.Handler) http.Handler {
169 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
170 defer t.Start()()
171 h.ServeHTTP(w, r)
172 })
173 }
174
175
176 func (t *Timer) TimedHandlerFunc(h http.HandlerFunc) http.HandlerFunc {
177 return func(w http.ResponseWriter, r *http.Request) {
178 defer t.Start()()
179 h(w, r)
180 }
181 }
182
183 func (t *Timer) MarshalJSON() ([]byte, error) {
184 c := t.Copy()
185 return json.Marshal(fmt.Sprintf("%d, %s/%s/%s", c.Count(), c.Min().String(), c.Average().String(), c.Max().String()))
186 }
187
View as plain text