blob: d6ec4c6260fcb331d58540bc83f14244b9ef0d61 [file] [log] [blame]
Scott Baker2d897982019-09-24 11:50:08 -07001package metrics
2
3import (
4 "sync"
5 "time"
6)
7
8// Timers capture the duration and rate of events.
9type Timer interface {
10 Count() int64
11 Max() int64
12 Mean() float64
13 Min() int64
14 Percentile(float64) float64
15 Percentiles([]float64) []float64
16 Rate1() float64
17 Rate5() float64
18 Rate15() float64
19 RateMean() float64
20 Snapshot() Timer
21 StdDev() float64
22 Stop()
23 Sum() int64
24 Time(func())
25 Update(time.Duration)
26 UpdateSince(time.Time)
27 Variance() float64
28}
29
30// GetOrRegisterTimer returns an existing Timer or constructs and registers a
31// new StandardTimer.
32// Be sure to unregister the meter from the registry once it is of no use to
33// allow for garbage collection.
34func GetOrRegisterTimer(name string, r Registry) Timer {
35 if nil == r {
36 r = DefaultRegistry
37 }
38 return r.GetOrRegister(name, NewTimer).(Timer)
39}
40
41// NewCustomTimer constructs a new StandardTimer from a Histogram and a Meter.
42// Be sure to call Stop() once the timer is of no use to allow for garbage collection.
43func NewCustomTimer(h Histogram, m Meter) Timer {
44 if UseNilMetrics {
45 return NilTimer{}
46 }
47 return &StandardTimer{
48 histogram: h,
49 meter: m,
50 }
51}
52
53// NewRegisteredTimer constructs and registers a new StandardTimer.
54// Be sure to unregister the meter from the registry once it is of no use to
55// allow for garbage collection.
56func NewRegisteredTimer(name string, r Registry) Timer {
57 c := NewTimer()
58 if nil == r {
59 r = DefaultRegistry
60 }
61 r.Register(name, c)
62 return c
63}
64
65// NewTimer constructs a new StandardTimer using an exponentially-decaying
66// sample with the same reservoir size and alpha as UNIX load averages.
67// Be sure to call Stop() once the timer is of no use to allow for garbage collection.
68func NewTimer() Timer {
69 if UseNilMetrics {
70 return NilTimer{}
71 }
72 return &StandardTimer{
73 histogram: NewHistogram(NewExpDecaySample(1028, 0.015)),
74 meter: NewMeter(),
75 }
76}
77
78// NilTimer is a no-op Timer.
79type NilTimer struct {
80 h Histogram
81 m Meter
82}
83
84// Count is a no-op.
85func (NilTimer) Count() int64 { return 0 }
86
87// Max is a no-op.
88func (NilTimer) Max() int64 { return 0 }
89
90// Mean is a no-op.
91func (NilTimer) Mean() float64 { return 0.0 }
92
93// Min is a no-op.
94func (NilTimer) Min() int64 { return 0 }
95
96// Percentile is a no-op.
97func (NilTimer) Percentile(p float64) float64 { return 0.0 }
98
99// Percentiles is a no-op.
100func (NilTimer) Percentiles(ps []float64) []float64 {
101 return make([]float64, len(ps))
102}
103
104// Rate1 is a no-op.
105func (NilTimer) Rate1() float64 { return 0.0 }
106
107// Rate5 is a no-op.
108func (NilTimer) Rate5() float64 { return 0.0 }
109
110// Rate15 is a no-op.
111func (NilTimer) Rate15() float64 { return 0.0 }
112
113// RateMean is a no-op.
114func (NilTimer) RateMean() float64 { return 0.0 }
115
116// Snapshot is a no-op.
117func (NilTimer) Snapshot() Timer { return NilTimer{} }
118
119// StdDev is a no-op.
120func (NilTimer) StdDev() float64 { return 0.0 }
121
122// Stop is a no-op.
123func (NilTimer) Stop() {}
124
125// Sum is a no-op.
126func (NilTimer) Sum() int64 { return 0 }
127
128// Time is a no-op.
129func (NilTimer) Time(func()) {}
130
131// Update is a no-op.
132func (NilTimer) Update(time.Duration) {}
133
134// UpdateSince is a no-op.
135func (NilTimer) UpdateSince(time.Time) {}
136
137// Variance is a no-op.
138func (NilTimer) Variance() float64 { return 0.0 }
139
140// StandardTimer is the standard implementation of a Timer and uses a Histogram
141// and Meter.
142type StandardTimer struct {
143 histogram Histogram
144 meter Meter
145 mutex sync.Mutex
146}
147
148// Count returns the number of events recorded.
149func (t *StandardTimer) Count() int64 {
150 return t.histogram.Count()
151}
152
153// Max returns the maximum value in the sample.
154func (t *StandardTimer) Max() int64 {
155 return t.histogram.Max()
156}
157
158// Mean returns the mean of the values in the sample.
159func (t *StandardTimer) Mean() float64 {
160 return t.histogram.Mean()
161}
162
163// Min returns the minimum value in the sample.
164func (t *StandardTimer) Min() int64 {
165 return t.histogram.Min()
166}
167
168// Percentile returns an arbitrary percentile of the values in the sample.
169func (t *StandardTimer) Percentile(p float64) float64 {
170 return t.histogram.Percentile(p)
171}
172
173// Percentiles returns a slice of arbitrary percentiles of the values in the
174// sample.
175func (t *StandardTimer) Percentiles(ps []float64) []float64 {
176 return t.histogram.Percentiles(ps)
177}
178
179// Rate1 returns the one-minute moving average rate of events per second.
180func (t *StandardTimer) Rate1() float64 {
181 return t.meter.Rate1()
182}
183
184// Rate5 returns the five-minute moving average rate of events per second.
185func (t *StandardTimer) Rate5() float64 {
186 return t.meter.Rate5()
187}
188
189// Rate15 returns the fifteen-minute moving average rate of events per second.
190func (t *StandardTimer) Rate15() float64 {
191 return t.meter.Rate15()
192}
193
194// RateMean returns the meter's mean rate of events per second.
195func (t *StandardTimer) RateMean() float64 {
196 return t.meter.RateMean()
197}
198
199// Snapshot returns a read-only copy of the timer.
200func (t *StandardTimer) Snapshot() Timer {
201 t.mutex.Lock()
202 defer t.mutex.Unlock()
203 return &TimerSnapshot{
204 histogram: t.histogram.Snapshot().(*HistogramSnapshot),
205 meter: t.meter.Snapshot().(*MeterSnapshot),
206 }
207}
208
209// StdDev returns the standard deviation of the values in the sample.
210func (t *StandardTimer) StdDev() float64 {
211 return t.histogram.StdDev()
212}
213
214// Stop stops the meter.
215func (t *StandardTimer) Stop() {
216 t.meter.Stop()
217}
218
219// Sum returns the sum in the sample.
220func (t *StandardTimer) Sum() int64 {
221 return t.histogram.Sum()
222}
223
224// Record the duration of the execution of the given function.
225func (t *StandardTimer) Time(f func()) {
226 ts := time.Now()
227 f()
228 t.Update(time.Since(ts))
229}
230
231// Record the duration of an event.
232func (t *StandardTimer) Update(d time.Duration) {
233 t.mutex.Lock()
234 defer t.mutex.Unlock()
235 t.histogram.Update(int64(d))
236 t.meter.Mark(1)
237}
238
239// Record the duration of an event that started at a time and ends now.
240func (t *StandardTimer) UpdateSince(ts time.Time) {
241 t.mutex.Lock()
242 defer t.mutex.Unlock()
243 t.histogram.Update(int64(time.Since(ts)))
244 t.meter.Mark(1)
245}
246
247// Variance returns the variance of the values in the sample.
248func (t *StandardTimer) Variance() float64 {
249 return t.histogram.Variance()
250}
251
252// TimerSnapshot is a read-only copy of another Timer.
253type TimerSnapshot struct {
254 histogram *HistogramSnapshot
255 meter *MeterSnapshot
256}
257
258// Count returns the number of events recorded at the time the snapshot was
259// taken.
260func (t *TimerSnapshot) Count() int64 { return t.histogram.Count() }
261
262// Max returns the maximum value at the time the snapshot was taken.
263func (t *TimerSnapshot) Max() int64 { return t.histogram.Max() }
264
265// Mean returns the mean value at the time the snapshot was taken.
266func (t *TimerSnapshot) Mean() float64 { return t.histogram.Mean() }
267
268// Min returns the minimum value at the time the snapshot was taken.
269func (t *TimerSnapshot) Min() int64 { return t.histogram.Min() }
270
271// Percentile returns an arbitrary percentile of sampled values at the time the
272// snapshot was taken.
273func (t *TimerSnapshot) Percentile(p float64) float64 {
274 return t.histogram.Percentile(p)
275}
276
277// Percentiles returns a slice of arbitrary percentiles of sampled values at
278// the time the snapshot was taken.
279func (t *TimerSnapshot) Percentiles(ps []float64) []float64 {
280 return t.histogram.Percentiles(ps)
281}
282
283// Rate1 returns the one-minute moving average rate of events per second at the
284// time the snapshot was taken.
285func (t *TimerSnapshot) Rate1() float64 { return t.meter.Rate1() }
286
287// Rate5 returns the five-minute moving average rate of events per second at
288// the time the snapshot was taken.
289func (t *TimerSnapshot) Rate5() float64 { return t.meter.Rate5() }
290
291// Rate15 returns the fifteen-minute moving average rate of events per second
292// at the time the snapshot was taken.
293func (t *TimerSnapshot) Rate15() float64 { return t.meter.Rate15() }
294
295// RateMean returns the meter's mean rate of events per second at the time the
296// snapshot was taken.
297func (t *TimerSnapshot) RateMean() float64 { return t.meter.RateMean() }
298
299// Snapshot returns the snapshot.
300func (t *TimerSnapshot) Snapshot() Timer { return t }
301
302// StdDev returns the standard deviation of the values at the time the snapshot
303// was taken.
304func (t *TimerSnapshot) StdDev() float64 { return t.histogram.StdDev() }
305
306// Stop is a no-op.
307func (t *TimerSnapshot) Stop() {}
308
309// Sum returns the sum at the time the snapshot was taken.
310func (t *TimerSnapshot) Sum() int64 { return t.histogram.Sum() }
311
312// Time panics.
313func (*TimerSnapshot) Time(func()) {
314 panic("Time called on a TimerSnapshot")
315}
316
317// Update panics.
318func (*TimerSnapshot) Update(time.Duration) {
319 panic("Update called on a TimerSnapshot")
320}
321
322// UpdateSince panics.
323func (*TimerSnapshot) UpdateSince(time.Time) {
324 panic("UpdateSince called on a TimerSnapshot")
325}
326
327// Variance returns the variance of the values at the time the snapshot was
328// taken.
329func (t *TimerSnapshot) Variance() float64 { return t.histogram.Variance() }