github.com/dominant-strategies/go-quai@v0.28.2/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 81 // Count is a no-op. 82 func (NilTimer) Count() int64 { return 0 } 83 84 // Max is a no-op. 85 func (NilTimer) Max() int64 { return 0 } 86 87 // Mean is a no-op. 88 func (NilTimer) Mean() float64 { return 0.0 } 89 90 // Min is a no-op. 91 func (NilTimer) Min() int64 { return 0 } 92 93 // Percentile is a no-op. 94 func (NilTimer) Percentile(p float64) float64 { return 0.0 } 95 96 // Percentiles is a no-op. 97 func (NilTimer) Percentiles(ps []float64) []float64 { 98 return make([]float64, len(ps)) 99 } 100 101 // Rate1 is a no-op. 102 func (NilTimer) Rate1() float64 { return 0.0 } 103 104 // Rate5 is a no-op. 105 func (NilTimer) Rate5() float64 { return 0.0 } 106 107 // Rate15 is a no-op. 108 func (NilTimer) Rate15() float64 { return 0.0 } 109 110 // RateMean is a no-op. 111 func (NilTimer) RateMean() float64 { return 0.0 } 112 113 // Snapshot is a no-op. 114 func (NilTimer) Snapshot() Timer { return NilTimer{} } 115 116 // StdDev is a no-op. 117 func (NilTimer) StdDev() float64 { return 0.0 } 118 119 // Stop is a no-op. 120 func (NilTimer) Stop() {} 121 122 // Sum is a no-op. 123 func (NilTimer) Sum() int64 { return 0 } 124 125 // Time is a no-op. 126 func (NilTimer) Time(func()) {} 127 128 // Update is a no-op. 129 func (NilTimer) Update(time.Duration) {} 130 131 // UpdateSince is a no-op. 132 func (NilTimer) UpdateSince(time.Time) {} 133 134 // Variance is a no-op. 135 func (NilTimer) Variance() float64 { return 0.0 } 136 137 // StandardTimer is the standard implementation of a Timer and uses a Histogram 138 // and Meter. 139 type StandardTimer struct { 140 histogram Histogram 141 meter Meter 142 mutex sync.Mutex 143 } 144 145 // Count returns the number of events recorded. 146 func (t *StandardTimer) Count() int64 { 147 return t.histogram.Count() 148 } 149 150 // Max returns the maximum value in the sample. 151 func (t *StandardTimer) Max() int64 { 152 return t.histogram.Max() 153 } 154 155 // Mean returns the mean of the values in the sample. 156 func (t *StandardTimer) Mean() float64 { 157 return t.histogram.Mean() 158 } 159 160 // Min returns the minimum value in the sample. 161 func (t *StandardTimer) Min() int64 { 162 return t.histogram.Min() 163 } 164 165 // Percentile returns an arbitrary percentile of the values in the sample. 166 func (t *StandardTimer) Percentile(p float64) float64 { 167 return t.histogram.Percentile(p) 168 } 169 170 // Percentiles returns a slice of arbitrary percentiles of the values in the 171 // sample. 172 func (t *StandardTimer) Percentiles(ps []float64) []float64 { 173 return t.histogram.Percentiles(ps) 174 } 175 176 // Rate1 returns the one-minute moving average rate of events per second. 177 func (t *StandardTimer) Rate1() float64 { 178 return t.meter.Rate1() 179 } 180 181 // Rate5 returns the five-minute moving average rate of events per second. 182 func (t *StandardTimer) Rate5() float64 { 183 return t.meter.Rate5() 184 } 185 186 // Rate15 returns the fifteen-minute moving average rate of events per second. 187 func (t *StandardTimer) Rate15() float64 { 188 return t.meter.Rate15() 189 } 190 191 // RateMean returns the meter's mean rate of events per second. 192 func (t *StandardTimer) RateMean() float64 { 193 return t.meter.RateMean() 194 } 195 196 // Snapshot returns a read-only copy of the timer. 197 func (t *StandardTimer) Snapshot() Timer { 198 t.mutex.Lock() 199 defer t.mutex.Unlock() 200 return &TimerSnapshot{ 201 histogram: t.histogram.Snapshot().(*HistogramSnapshot), 202 meter: t.meter.Snapshot().(*MeterSnapshot), 203 } 204 } 205 206 // StdDev returns the standard deviation of the values in the sample. 207 func (t *StandardTimer) StdDev() float64 { 208 return t.histogram.StdDev() 209 } 210 211 // Stop stops the meter. 212 func (t *StandardTimer) Stop() { 213 t.meter.Stop() 214 } 215 216 // Sum returns the sum in the sample. 217 func (t *StandardTimer) Sum() int64 { 218 return t.histogram.Sum() 219 } 220 221 // Record the duration of the execution of the given function. 222 func (t *StandardTimer) Time(f func()) { 223 ts := time.Now() 224 f() 225 t.Update(time.Since(ts)) 226 } 227 228 // Record the duration of an event. 229 func (t *StandardTimer) Update(d time.Duration) { 230 t.mutex.Lock() 231 defer t.mutex.Unlock() 232 t.histogram.Update(int64(d)) 233 t.meter.Mark(1) 234 } 235 236 // Record the duration of an event that started at a time and ends now. 237 func (t *StandardTimer) UpdateSince(ts time.Time) { 238 t.mutex.Lock() 239 defer t.mutex.Unlock() 240 t.histogram.Update(int64(time.Since(ts))) 241 t.meter.Mark(1) 242 } 243 244 // Variance returns the variance of the values in the sample. 245 func (t *StandardTimer) Variance() float64 { 246 return t.histogram.Variance() 247 } 248 249 // TimerSnapshot is a read-only copy of another Timer. 250 type TimerSnapshot struct { 251 histogram *HistogramSnapshot 252 meter *MeterSnapshot 253 } 254 255 // Count returns the number of events recorded at the time the snapshot was 256 // taken. 257 func (t *TimerSnapshot) Count() int64 { return t.histogram.Count() } 258 259 // Max returns the maximum value at the time the snapshot was taken. 260 func (t *TimerSnapshot) Max() int64 { return t.histogram.Max() } 261 262 // Mean returns the mean value at the time the snapshot was taken. 263 func (t *TimerSnapshot) Mean() float64 { return t.histogram.Mean() } 264 265 // Min returns the minimum value at the time the snapshot was taken. 266 func (t *TimerSnapshot) Min() int64 { return t.histogram.Min() } 267 268 // Percentile returns an arbitrary percentile of sampled values at the time the 269 // snapshot was taken. 270 func (t *TimerSnapshot) Percentile(p float64) float64 { 271 return t.histogram.Percentile(p) 272 } 273 274 // Percentiles returns a slice of arbitrary percentiles of sampled values at 275 // the time the snapshot was taken. 276 func (t *TimerSnapshot) Percentiles(ps []float64) []float64 { 277 return t.histogram.Percentiles(ps) 278 } 279 280 // Rate1 returns the one-minute moving average rate of events per second at the 281 // time the snapshot was taken. 282 func (t *TimerSnapshot) Rate1() float64 { return t.meter.Rate1() } 283 284 // Rate5 returns the five-minute moving average rate of events per second at 285 // the time the snapshot was taken. 286 func (t *TimerSnapshot) Rate5() float64 { return t.meter.Rate5() } 287 288 // Rate15 returns the fifteen-minute moving average rate of events per second 289 // at the time the snapshot was taken. 290 func (t *TimerSnapshot) Rate15() float64 { return t.meter.Rate15() } 291 292 // RateMean returns the meter's mean rate of events per second at the time the 293 // snapshot was taken. 294 func (t *TimerSnapshot) RateMean() float64 { return t.meter.RateMean() } 295 296 // Snapshot returns the snapshot. 297 func (t *TimerSnapshot) Snapshot() Timer { return t } 298 299 // StdDev returns the standard deviation of the values at the time the snapshot 300 // was taken. 301 func (t *TimerSnapshot) StdDev() float64 { return t.histogram.StdDev() } 302 303 // Stop is a no-op. 304 func (t *TimerSnapshot) Stop() {} 305 306 // Sum returns the sum at the time the snapshot was taken. 307 func (t *TimerSnapshot) Sum() int64 { return t.histogram.Sum() } 308 309 // Time panics. 310 func (*TimerSnapshot) Time(func()) { 311 panic("Time called on a TimerSnapshot") 312 } 313 314 // Update panics. 315 func (*TimerSnapshot) Update(time.Duration) { 316 panic("Update called on a TimerSnapshot") 317 } 318 319 // UpdateSince panics. 320 func (*TimerSnapshot) UpdateSince(time.Time) { 321 panic("UpdateSince called on a TimerSnapshot") 322 } 323 324 // Variance returns the variance of the values at the time the snapshot was 325 // taken. 326 func (t *TimerSnapshot) Variance() float64 { return t.histogram.Variance() }