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