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() }