mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 09:53:48 +00:00
metrics: fix resetting timer
This commit is contained in:
parent
4111636841
commit
9e22de7c47
5 changed files with 31 additions and 68 deletions
|
|
@ -174,7 +174,7 @@ func (exp *exp) publishTimer(name string, metric *metrics.Timer) {
|
|||
exp.getFloat(name + ".mean-rate").Set(t.RateMean())
|
||||
}
|
||||
|
||||
func (exp *exp) publishResettingTimer(name string, metric metrics.ResettingTimer) {
|
||||
func (exp *exp) publishResettingTimer(name string, metric *metrics.ResettingTimer) {
|
||||
t := metric.Snapshot()
|
||||
ps := t.Percentiles([]float64{0.50, 0.75, 0.95, 0.99})
|
||||
exp.getInt(name + ".count").Set(int64(t.Count()))
|
||||
|
|
@ -204,7 +204,7 @@ func (exp *exp) syncToExpvar() {
|
|||
exp.publishMeter(name, i)
|
||||
case *metrics.Timer:
|
||||
exp.publishTimer(name, i)
|
||||
case metrics.ResettingTimer:
|
||||
case *metrics.ResettingTimer:
|
||||
exp.publishResettingTimer(name, i)
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported type for '%s': %T", name, i))
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ func readMeter(namespace, name string, i interface{}) (string, map[string]interf
|
|||
"meanrate": ms.RateMean(),
|
||||
}
|
||||
return measurement, fields
|
||||
case metrics.ResettingTimer:
|
||||
case *metrics.ResettingTimer:
|
||||
ms := metric.Snapshot()
|
||||
if ms.Count() == 0 {
|
||||
break
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ func (c *collector) Add(name string, i any) error {
|
|||
c.addMeter(name, m.Snapshot())
|
||||
case *metrics.Timer:
|
||||
c.addTimer(name, m.Snapshot())
|
||||
case metrics.ResettingTimer:
|
||||
case *metrics.ResettingTimer:
|
||||
c.addResettingTimer(name, m.Snapshot())
|
||||
default:
|
||||
return fmt.Errorf("unknown prometheus metric type %T", i)
|
||||
|
|
@ -121,7 +121,7 @@ func (c *collector) addTimer(name string, m *metrics.TimerSnapshot) {
|
|||
c.buff.WriteRune('\n')
|
||||
}
|
||||
|
||||
func (c *collector) addResettingTimer(name string, m metrics.ResettingTimerSnapshot) {
|
||||
func (c *collector) addResettingTimer(name string, m *metrics.ResettingTimerSnapshot) {
|
||||
if m.Count() <= 0 {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ func (r *StandardRegistry) Unregister(name string) {
|
|||
|
||||
func (r *StandardRegistry) loadOrRegister(name string, i interface{}) (interface{}, bool, bool) {
|
||||
switch i.(type) {
|
||||
case *Counter, *CounterFloat64, *Gauge, *GaugeFloat64, *GaugeInfo, *Healthcheck, Histogram, *Meter, *Timer, ResettingTimer:
|
||||
case *Counter, *CounterFloat64, *Gauge, *GaugeFloat64, *GaugeInfo, *Healthcheck, Histogram, *Meter, *Timer, *ResettingTimer:
|
||||
default:
|
||||
return nil, false, false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,36 +5,17 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// Initial slice capacity for the values stored in a ResettingTimer
|
||||
const InitialResettingTimerSliceCap = 10
|
||||
|
||||
type ResettingTimerSnapshot interface {
|
||||
Count() int
|
||||
Mean() float64
|
||||
Max() int64
|
||||
Min() int64
|
||||
Percentiles([]float64) []float64
|
||||
}
|
||||
|
||||
// ResettingTimer is used for storing aggregated values for timers, which are reset on every flush interval.
|
||||
type ResettingTimer interface {
|
||||
Snapshot() ResettingTimerSnapshot
|
||||
Time(func())
|
||||
Update(time.Duration)
|
||||
UpdateSince(time.Time)
|
||||
}
|
||||
|
||||
// GetOrRegisterResettingTimer returns an existing ResettingTimer or constructs and registers a
|
||||
// new StandardResettingTimer.
|
||||
func GetOrRegisterResettingTimer(name string, r Registry) ResettingTimer {
|
||||
// new ResettingTimer.
|
||||
func GetOrRegisterResettingTimer(name string, r Registry) *ResettingTimer {
|
||||
if nil == r {
|
||||
r = DefaultRegistry
|
||||
}
|
||||
return r.GetOrRegister(name, NewResettingTimer).(ResettingTimer)
|
||||
return r.GetOrRegister(name, NewResettingTimer).(*ResettingTimer)
|
||||
}
|
||||
|
||||
// NewRegisteredResettingTimer constructs and registers a new StandardResettingTimer.
|
||||
func NewRegisteredResettingTimer(name string, r Registry) ResettingTimer {
|
||||
// NewRegisteredResettingTimer constructs and registers a new ResettingTimer.
|
||||
func NewRegisteredResettingTimer(name string, r Registry) *ResettingTimer {
|
||||
c := NewResettingTimer()
|
||||
if nil == r {
|
||||
r = DefaultRegistry
|
||||
|
|
@ -43,33 +24,15 @@ func NewRegisteredResettingTimer(name string, r Registry) ResettingTimer {
|
|||
return c
|
||||
}
|
||||
|
||||
// NewResettingTimer constructs a new StandardResettingTimer
|
||||
func NewResettingTimer() ResettingTimer {
|
||||
if !metricsEnabled {
|
||||
return NilResettingTimer{}
|
||||
}
|
||||
return &StandardResettingTimer{
|
||||
values: make([]int64, 0, InitialResettingTimerSliceCap),
|
||||
// NewResettingTimer constructs a new ResettingTimer
|
||||
func NewResettingTimer() *ResettingTimer {
|
||||
return &ResettingTimer{
|
||||
values: make([]int64, 0, 10),
|
||||
}
|
||||
}
|
||||
|
||||
// NilResettingTimer is a no-op ResettingTimer.
|
||||
type NilResettingTimer struct{}
|
||||
|
||||
func (NilResettingTimer) Values() []int64 { return nil }
|
||||
func (n NilResettingTimer) Snapshot() ResettingTimerSnapshot { return n }
|
||||
func (NilResettingTimer) Time(f func()) { f() }
|
||||
func (NilResettingTimer) Update(time.Duration) {}
|
||||
func (NilResettingTimer) Percentiles([]float64) []float64 { return nil }
|
||||
func (NilResettingTimer) Mean() float64 { return 0.0 }
|
||||
func (NilResettingTimer) Max() int64 { return 0 }
|
||||
func (NilResettingTimer) Min() int64 { return 0 }
|
||||
func (NilResettingTimer) UpdateSince(time.Time) {}
|
||||
func (NilResettingTimer) Count() int { return 0 }
|
||||
|
||||
// StandardResettingTimer is the standard implementation of a ResettingTimer.
|
||||
// and Meter.
|
||||
type StandardResettingTimer struct {
|
||||
// ResettingTimer is used for storing aggregated values for timers, which are reset on every flush interval.
|
||||
type ResettingTimer struct {
|
||||
values []int64
|
||||
sum int64 // sum is a running count of the total sum, used later to calculate mean
|
||||
|
||||
|
|
@ -77,28 +40,28 @@ type StandardResettingTimer struct {
|
|||
}
|
||||
|
||||
// Snapshot resets the timer and returns a read-only copy of its contents.
|
||||
func (t *StandardResettingTimer) Snapshot() ResettingTimerSnapshot {
|
||||
func (t *ResettingTimer) Snapshot() *ResettingTimerSnapshot {
|
||||
t.mutex.Lock()
|
||||
defer t.mutex.Unlock()
|
||||
snapshot := &resettingTimerSnapshot{}
|
||||
snapshot := &ResettingTimerSnapshot{}
|
||||
if len(t.values) > 0 {
|
||||
snapshot.mean = float64(t.sum) / float64(len(t.values))
|
||||
snapshot.values = t.values
|
||||
t.values = make([]int64, 0, InitialResettingTimerSliceCap)
|
||||
t.values = make([]int64, 0, 10)
|
||||
}
|
||||
t.sum = 0
|
||||
return snapshot
|
||||
}
|
||||
|
||||
// Record the duration of the execution of the given function.
|
||||
func (t *StandardResettingTimer) Time(f func()) {
|
||||
func (t *ResettingTimer) Time(f func()) {
|
||||
ts := time.Now()
|
||||
f()
|
||||
t.Update(time.Since(ts))
|
||||
}
|
||||
|
||||
// Record the duration of an event.
|
||||
func (t *StandardResettingTimer) Update(d time.Duration) {
|
||||
func (t *ResettingTimer) Update(d time.Duration) {
|
||||
t.mutex.Lock()
|
||||
defer t.mutex.Unlock()
|
||||
t.values = append(t.values, int64(d))
|
||||
|
|
@ -106,12 +69,12 @@ func (t *StandardResettingTimer) Update(d time.Duration) {
|
|||
}
|
||||
|
||||
// Record the duration of an event that started at a time and ends now.
|
||||
func (t *StandardResettingTimer) UpdateSince(ts time.Time) {
|
||||
func (t *ResettingTimer) UpdateSince(ts time.Time) {
|
||||
t.Update(time.Since(ts))
|
||||
}
|
||||
|
||||
// resettingTimerSnapshot is a point-in-time copy of another ResettingTimer.
|
||||
type resettingTimerSnapshot struct {
|
||||
// ResettingTimerSnapshot is a point-in-time copy of another ResettingTimer.
|
||||
type ResettingTimerSnapshot struct {
|
||||
values []int64
|
||||
mean float64
|
||||
max int64
|
||||
|
|
@ -121,20 +84,20 @@ type resettingTimerSnapshot struct {
|
|||
}
|
||||
|
||||
// Count return the length of the values from snapshot.
|
||||
func (t *resettingTimerSnapshot) Count() int {
|
||||
func (t *ResettingTimerSnapshot) Count() int {
|
||||
return len(t.values)
|
||||
}
|
||||
|
||||
// Percentiles returns the boundaries for the input percentiles.
|
||||
// note: this method is not thread safe
|
||||
func (t *resettingTimerSnapshot) Percentiles(percentiles []float64) []float64 {
|
||||
func (t *ResettingTimerSnapshot) Percentiles(percentiles []float64) []float64 {
|
||||
t.calc(percentiles)
|
||||
return t.thresholdBoundaries
|
||||
}
|
||||
|
||||
// Mean returns the mean of the snapshotted values
|
||||
// note: this method is not thread safe
|
||||
func (t *resettingTimerSnapshot) Mean() float64 {
|
||||
func (t *ResettingTimerSnapshot) Mean() float64 {
|
||||
if !t.calculated {
|
||||
t.calc(nil)
|
||||
}
|
||||
|
|
@ -144,7 +107,7 @@ func (t *resettingTimerSnapshot) Mean() float64 {
|
|||
|
||||
// Max returns the max of the snapshotted values
|
||||
// note: this method is not thread safe
|
||||
func (t *resettingTimerSnapshot) Max() int64 {
|
||||
func (t *ResettingTimerSnapshot) Max() int64 {
|
||||
if !t.calculated {
|
||||
t.calc(nil)
|
||||
}
|
||||
|
|
@ -153,14 +116,14 @@ func (t *resettingTimerSnapshot) Max() int64 {
|
|||
|
||||
// Min returns the min of the snapshotted values
|
||||
// note: this method is not thread safe
|
||||
func (t *resettingTimerSnapshot) Min() int64 {
|
||||
func (t *ResettingTimerSnapshot) Min() int64 {
|
||||
if !t.calculated {
|
||||
t.calc(nil)
|
||||
}
|
||||
return t.min
|
||||
}
|
||||
|
||||
func (t *resettingTimerSnapshot) calc(percentiles []float64) {
|
||||
func (t *ResettingTimerSnapshot) calc(percentiles []float64) {
|
||||
scores := CalculatePercentiles(t.values, percentiles)
|
||||
t.thresholdBoundaries = scores
|
||||
if len(t.values) == 0 {
|
||||
|
|
|
|||
Loading…
Reference in a new issue