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