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