aboutsummaryrefslogblamecommitdiffstats
path: root/metrics/timer.go
blob: 89e22208fde0fa2757ee0f9f4ccd59b2b59934cd (plain) (tree)




















                                                  
              








                                                                             

                                                                            







                                                                              
                                                                                      
                                                 
                     








                                                                   

                                                                            










                                                                          
                                                                                      
                       
                     



















































                                                                        


                         
























































































                                                                               




                                






















































































                                                                               


                                 




















                                                                            
package metrics

import (
    "sync"
    "time"
)

// Timers capture the duration and rate of events.
type Timer interface {
    Count() int64
    Max() int64
    Mean() float64
    Min() int64
    Percentile(float64) float64
    Percentiles([]float64) []float64
    Rate1() float64
    Rate5() float64
    Rate15() float64
    RateMean() float64
    Snapshot() Timer
    StdDev() float64
    Stop()
    Sum() int64
    Time(func())
    Update(time.Duration)
    UpdateSince(time.Time)
    Variance() float64
}

// GetOrRegisterTimer returns an existing Timer or constructs and registers a
// new StandardTimer.
// Be sure to unregister the meter from the registry once it is of no use to
// allow for garbage collection.
func GetOrRegisterTimer(name string, r Registry) Timer {
    if nil == r {
        r = DefaultRegistry
    }
    return r.GetOrRegister(name, NewTimer).(Timer)
}

// NewCustomTimer constructs a new StandardTimer from a Histogram and a Meter.
// Be sure to call Stop() once the timer is of no use to allow for garbage collection.
func NewCustomTimer(h Histogram, m Meter) Timer {
    if !Enabled {
        return NilTimer{}
    }
    return &StandardTimer{
        histogram: h,
        meter:     m,
    }
}

// NewRegisteredTimer constructs and registers a new StandardTimer.
// Be sure to unregister the meter from the registry once it is of no use to
// allow for garbage collection.
func NewRegisteredTimer(name string, r Registry) Timer {
    c := NewTimer()
    if nil == r {
        r = DefaultRegistry
    }
    r.Register(name, c)
    return c
}

// NewTimer constructs a new StandardTimer using an exponentially-decaying
// sample with the same reservoir size and alpha as UNIX load averages.
// Be sure to call Stop() once the timer is of no use to allow for garbage collection.
func NewTimer() Timer {
    if !Enabled {
        return NilTimer{}
    }
    return &StandardTimer{
        histogram: NewHistogram(NewExpDecaySample(1028, 0.015)),
        meter:     NewMeter(),
    }
}

// NilTimer is a no-op Timer.
type NilTimer struct {
    h Histogram
    m Meter
}

// Count is a no-op.
func (NilTimer) Count() int64 { return 0 }

// Max is a no-op.
func (NilTimer) Max() int64 { return 0 }

// Mean is a no-op.
func (NilTimer) Mean() float64 { return 0.0 }

// Min is a no-op.
func (NilTimer) Min() int64 { return 0 }

// Percentile is a no-op.
func (NilTimer) Percentile(p float64) float64 { return 0.0 }

// Percentiles is a no-op.
func (NilTimer) Percentiles(ps []float64) []float64 {
    return make([]float64, len(ps))
}

// Rate1 is a no-op.
func (NilTimer) Rate1() float64 { return 0.0 }

// Rate5 is a no-op.
func (NilTimer) Rate5() float64 { return 0.0 }

// Rate15 is a no-op.
func (NilTimer) Rate15() float64 { return 0.0 }

// RateMean is a no-op.
func (NilTimer) RateMean() float64 { return 0.0 }

// Snapshot is a no-op.
func (NilTimer) Snapshot() Timer { return NilTimer{} }

// StdDev is a no-op.
func (NilTimer) StdDev() float64 { return 0.0 }

// Stop is a no-op.
func (NilTimer) Stop() {}

// Sum is a no-op.
func (NilTimer) Sum() int64 { return 0 }

// Time is a no-op.
func (NilTimer) Time(func()) {}

// Update is a no-op.
func (NilTimer) Update(time.Duration) {}

// UpdateSince is a no-op.
func (NilTimer) UpdateSince(time.Time) {}

// Variance is a no-op.
func (NilTimer) Variance() float64 { return 0.0 }

// StandardTimer is the standard implementation of a Timer and uses a Histogram
// and Meter.
type StandardTimer struct {
    histogram Histogram
    meter     Meter
    mutex     sync.Mutex
}

// Count returns the number of events recorded.
func (t *StandardTimer) Count() int64 {
    return t.histogram.Count()
}

// Max returns the maximum value in the sample.
func (t *StandardTimer) Max() int64 {
    return t.histogram.Max()
}

// Mean returns the mean of the values in the sample.
func (t *StandardTimer) Mean() float64 {
    return t.histogram.Mean()
}

// Min returns the minimum value in the sample.
func (t *StandardTimer) Min() int64 {
    return t.histogram.Min()
}

// Percentile returns an arbitrary percentile of the values in the sample.
func (t *StandardTimer) Percentile(p float64) float64 {
    return t.histogram.Percentile(p)
}

// Percentiles returns a slice of arbitrary percentiles of the values in the
// sample.
func (t *StandardTimer) Percentiles(ps []float64) []float64 {
    return t.histogram.Percentiles(ps)
}

// Rate1 returns the one-minute moving average rate of events per second.
func (t *StandardTimer) Rate1() float64 {
    return t.meter.Rate1()
}

// Rate5 returns the five-minute moving average rate of events per second.
func (t *StandardTimer) Rate5() float64 {
    return t.meter.Rate5()
}

// Rate15 returns the fifteen-minute moving average rate of events per second.
func (t *StandardTimer) Rate15() float64 {
    return t.meter.Rate15()
}

// RateMean returns the meter's mean rate of events per second.
func (t *StandardTimer) RateMean() float64 {
    return t.meter.RateMean()
}

// Snapshot returns a read-only copy of the timer.
func (t *StandardTimer) Snapshot() Timer {
    t.mutex.Lock()
    defer t.mutex.Unlock()
    return &TimerSnapshot{
        histogram: t.histogram.Snapshot().(*HistogramSnapshot),
        meter:     t.meter.Snapshot().(*MeterSnapshot),
    }
}

// StdDev returns the standard deviation of the values in the sample.
func (t *StandardTimer) StdDev() float64 {
    return t.histogram.StdDev()
}

// Stop stops the meter.
func (t *StandardTimer) Stop() {
    t.meter.Stop()
}

// Sum returns the sum in the sample.
func (t *StandardTimer) Sum() int64 {
    return t.histogram.Sum()
}

// Record the duration of the execution of the given function.
func (t *StandardTimer) Time(f func()) {
    ts := time.Now()
    f()
    t.Update(time.Since(ts))
}

// Record the duration of an event.
func (t *StandardTimer) Update(d time.Duration) {
    t.mutex.Lock()
    defer t.mutex.Unlock()
    t.histogram.Update(int64(d))
    t.meter.Mark(1)
}

// Record the duration of an event that started at a time and ends now.
func (t *StandardTimer) UpdateSince(ts time.Time) {
    t.mutex.Lock()
    defer t.mutex.Unlock()
    t.histogram.Update(int64(time.Since(ts)))
    t.meter.Mark(1)
}

// Variance returns the variance of the values in the sample.
func (t *StandardTimer) Variance() float64 {
    return t.histogram.Variance()
}

// TimerSnapshot is a read-only copy of another Timer.
type TimerSnapshot struct {
    histogram *HistogramSnapshot
    meter     *MeterSnapshot
}

// Count returns the number of events recorded at the time the snapshot was
// taken.
func (t *TimerSnapshot) Count() int64 { return t.histogram.Count() }

// Max returns the maximum value at the time the snapshot was taken.
func (t *TimerSnapshot) Max() int64 { return t.histogram.Max() }

// Mean returns the mean value at the time the snapshot was taken.
func (t *TimerSnapshot) Mean() float64 { return t.histogram.Mean() }

// Min returns the minimum value at the time the snapshot was taken.
func (t *TimerSnapshot) Min() int64 { return t.histogram.Min() }

// Percentile returns an arbitrary percentile of sampled values at the time the
// snapshot was taken.
func (t *TimerSnapshot) Percentile(p float64) float64 {
    return t.histogram.Percentile(p)
}

// Percentiles returns a slice of arbitrary percentiles of sampled values at
// the time the snapshot was taken.
func (t *TimerSnapshot) Percentiles(ps []float64) []float64 {
    return t.histogram.Percentiles(ps)
}

// Rate1 returns the one-minute moving average rate of events per second at the
// time the snapshot was taken.
func (t *TimerSnapshot) Rate1() float64 { return t.meter.Rate1() }

// Rate5 returns the five-minute moving average rate of events per second at
// the time the snapshot was taken.
func (t *TimerSnapshot) Rate5() float64 { return t.meter.Rate5() }

// Rate15 returns the fifteen-minute moving average rate of events per second
// at the time the snapshot was taken.
func (t *TimerSnapshot) Rate15() float64 { return t.meter.Rate15() }

// RateMean returns the meter's mean rate of events per second at the time the
// snapshot was taken.
func (t *TimerSnapshot) RateMean() float64 { return t.meter.RateMean() }

// Snapshot returns the snapshot.
func (t *TimerSnapshot) Snapshot() Timer { return t }

// StdDev returns the standard deviation of the values at the time the snapshot
// was taken.
func (t *TimerSnapshot) StdDev() float64 { return t.histogram.StdDev() }

// Stop is a no-op.
func (t *TimerSnapshot) Stop() {}

// Sum returns the sum at the time the snapshot was taken.
func (t *TimerSnapshot) Sum() int64 { return t.histogram.Sum() }

// Time panics.
func (*TimerSnapshot) Time(func()) {
    panic("Time called on a TimerSnapshot")
}

// Update panics.
func (*TimerSnapshot) Update(time.Duration) {
    panic("Update called on a TimerSnapshot")
}

// UpdateSince panics.
func (*TimerSnapshot) UpdateSince(time.Time) {
    panic("UpdateSince called on a TimerSnapshot")
}

// Variance returns the variance of the values at the time the snapshot was
// taken.
func (t *TimerSnapshot) Variance() float64 { return t.histogram.Variance() }