github.com/intfoundation/intchain@v0.0.0-20220727031208-4316ad31ca73/metrics/timer.go (about) 1 package metrics 2 3 import ( 4 "sync" 5 "time" 6 ) 7 8 // Timers capture the duration and rate of events. 9 type 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. 34 func 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. 43 func NewCustomTimer(h Histogram, m Meter) Timer { 44 if !Enabled { 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. 56 func 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. 68 func NewTimer() Timer { 69 if !Enabled { 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. 79 type NilTimer struct { 80 h Histogram 81 m Meter 82 } 83 84 // Count is a no-op. 85 func (NilTimer) Count() int64 { return 0 } 86 87 // Max is a no-op. 88 func (NilTimer) Max() int64 { return 0 } 89 90 // Mean is a no-op. 91 func (NilTimer) Mean() float64 { return 0.0 } 92 93 // Min is a no-op. 94 func (NilTimer) Min() int64 { return 0 } 95 96 // Percentile is a no-op. 97 func (NilTimer) Percentile(p float64) float64 { return 0.0 } 98 99 // Percentiles is a no-op. 100 func (NilTimer) Percentiles(ps []float64) []float64 { 101 return make([]float64, len(ps)) 102 } 103 104 // Rate1 is a no-op. 105 func (NilTimer) Rate1() float64 { return 0.0 } 106 107 // Rate5 is a no-op. 108 func (NilTimer) Rate5() float64 { return 0.0 } 109 110 // Rate15 is a no-op. 111 func (NilTimer) Rate15() float64 { return 0.0 } 112 113 // RateMean is a no-op. 114 func (NilTimer) RateMean() float64 { return 0.0 } 115 116 // Snapshot is a no-op. 117 func (NilTimer) Snapshot() Timer { return NilTimer{} } 118 119 // StdDev is a no-op. 120 func (NilTimer) StdDev() float64 { return 0.0 } 121 122 // Stop is a no-op. 123 func (NilTimer) Stop() {} 124 125 // Sum is a no-op. 126 func (NilTimer) Sum() int64 { return 0 } 127 128 // Time is a no-op. 129 func (NilTimer) Time(func()) {} 130 131 // Update is a no-op. 132 func (NilTimer) Update(time.Duration) {} 133 134 // UpdateSince is a no-op. 135 func (NilTimer) UpdateSince(time.Time) {} 136 137 // Variance is a no-op. 138 func (NilTimer) Variance() float64 { return 0.0 } 139 140 // StandardTimer is the standard implementation of a Timer and uses a Histogram 141 // and Meter. 142 type StandardTimer struct { 143 histogram Histogram 144 meter Meter 145 mutex sync.Mutex 146 } 147 148 // Count returns the number of events recorded. 149 func (t *StandardTimer) Count() int64 { 150 return t.histogram.Count() 151 } 152 153 // Max returns the maximum value in the sample. 154 func (t *StandardTimer) Max() int64 { 155 return t.histogram.Max() 156 } 157 158 // Mean returns the mean of the values in the sample. 159 func (t *StandardTimer) Mean() float64 { 160 return t.histogram.Mean() 161 } 162 163 // Min returns the minimum value in the sample. 164 func (t *StandardTimer) Min() int64 { 165 return t.histogram.Min() 166 } 167 168 // Percentile returns an arbitrary percentile of the values in the sample. 169 func (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. 175 func (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. 180 func (t *StandardTimer) Rate1() float64 { 181 return t.meter.Rate1() 182 } 183 184 // Rate5 returns the five-minute moving average rate of events per second. 185 func (t *StandardTimer) Rate5() float64 { 186 return t.meter.Rate5() 187 } 188 189 // Rate15 returns the fifteen-minute moving average rate of events per second. 190 func (t *StandardTimer) Rate15() float64 { 191 return t.meter.Rate15() 192 } 193 194 // RateMean returns the meter's mean rate of events per second. 195 func (t *StandardTimer) RateMean() float64 { 196 return t.meter.RateMean() 197 } 198 199 // Snapshot returns a read-only copy of the timer. 200 func (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. 210 func (t *StandardTimer) StdDev() float64 { 211 return t.histogram.StdDev() 212 } 213 214 // Stop stops the meter. 215 func (t *StandardTimer) Stop() { 216 t.meter.Stop() 217 } 218 219 // Sum returns the sum in the sample. 220 func (t *StandardTimer) Sum() int64 { 221 return t.histogram.Sum() 222 } 223 224 // Record the duration of the execution of the given function. 225 func (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. 232 func (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. 240 func (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. 248 func (t *StandardTimer) Variance() float64 { 249 return t.histogram.Variance() 250 } 251 252 // TimerSnapshot is a read-only copy of another Timer. 253 type 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. 260 func (t *TimerSnapshot) Count() int64 { return t.histogram.Count() } 261 262 // Max returns the maximum value at the time the snapshot was taken. 263 func (t *TimerSnapshot) Max() int64 { return t.histogram.Max() } 264 265 // Mean returns the mean value at the time the snapshot was taken. 266 func (t *TimerSnapshot) Mean() float64 { return t.histogram.Mean() } 267 268 // Min returns the minimum value at the time the snapshot was taken. 269 func (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. 273 func (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. 279 func (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. 285 func (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. 289 func (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. 293 func (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. 297 func (t *TimerSnapshot) RateMean() float64 { return t.meter.RateMean() } 298 299 // Snapshot returns the snapshot. 300 func (t *TimerSnapshot) Snapshot() Timer { return t } 301 302 // StdDev returns the standard deviation of the values at the time the snapshot 303 // was taken. 304 func (t *TimerSnapshot) StdDev() float64 { return t.histogram.StdDev() } 305 306 // Stop is a no-op. 307 func (t *TimerSnapshot) Stop() {} 308 309 // Sum returns the sum at the time the snapshot was taken. 310 func (t *TimerSnapshot) Sum() int64 { return t.histogram.Sum() } 311 312 // Time panics. 313 func (*TimerSnapshot) Time(func()) { 314 panic("Time called on a TimerSnapshot") 315 } 316 317 // Update panics. 318 func (*TimerSnapshot) Update(time.Duration) { 319 panic("Update called on a TimerSnapshot") 320 } 321 322 // UpdateSince panics. 323 func (*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. 329 func (t *TimerSnapshot) Variance() float64 { return t.histogram.Variance() }