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