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())
|
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()
|
t := metric.Snapshot()
|
||||||
ps := t.Percentiles([]float64{0.50, 0.75, 0.95, 0.99})
|
ps := t.Percentiles([]float64{0.50, 0.75, 0.95, 0.99})
|
||||||
exp.getInt(name + ".count").Set(int64(t.Count()))
|
exp.getInt(name + ".count").Set(int64(t.Count()))
|
||||||
|
|
@ -204,7 +204,7 @@ func (exp *exp) syncToExpvar() {
|
||||||
exp.publishMeter(name, i)
|
exp.publishMeter(name, i)
|
||||||
case *metrics.Timer:
|
case *metrics.Timer:
|
||||||
exp.publishTimer(name, i)
|
exp.publishTimer(name, i)
|
||||||
case metrics.ResettingTimer:
|
case *metrics.ResettingTimer:
|
||||||
exp.publishResettingTimer(name, i)
|
exp.publishResettingTimer(name, i)
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("unsupported type for '%s': %T", name, i))
|
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(),
|
"meanrate": ms.RateMean(),
|
||||||
}
|
}
|
||||||
return measurement, fields
|
return measurement, fields
|
||||||
case metrics.ResettingTimer:
|
case *metrics.ResettingTimer:
|
||||||
ms := metric.Snapshot()
|
ms := metric.Snapshot()
|
||||||
if ms.Count() == 0 {
|
if ms.Count() == 0 {
|
||||||
break
|
break
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ func (c *collector) Add(name string, i any) error {
|
||||||
c.addMeter(name, m.Snapshot())
|
c.addMeter(name, m.Snapshot())
|
||||||
case *metrics.Timer:
|
case *metrics.Timer:
|
||||||
c.addTimer(name, m.Snapshot())
|
c.addTimer(name, m.Snapshot())
|
||||||
case metrics.ResettingTimer:
|
case *metrics.ResettingTimer:
|
||||||
c.addResettingTimer(name, m.Snapshot())
|
c.addResettingTimer(name, m.Snapshot())
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unknown prometheus metric type %T", i)
|
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')
|
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 {
|
if m.Count() <= 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -211,7 +211,7 @@ func (r *StandardRegistry) Unregister(name string) {
|
||||||
|
|
||||||
func (r *StandardRegistry) loadOrRegister(name string, i interface{}) (interface{}, bool, bool) {
|
func (r *StandardRegistry) loadOrRegister(name string, i interface{}) (interface{}, bool, bool) {
|
||||||
switch i.(type) {
|
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:
|
default:
|
||||||
return nil, false, false
|
return nil, false, false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,36 +5,17 @@ import (
|
||||||
"time"
|
"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
|
// GetOrRegisterResettingTimer returns an existing ResettingTimer or constructs and registers a
|
||||||
// new StandardResettingTimer.
|
// new ResettingTimer.
|
||||||
func GetOrRegisterResettingTimer(name string, r Registry) ResettingTimer {
|
func GetOrRegisterResettingTimer(name string, r Registry) *ResettingTimer {
|
||||||
if nil == r {
|
if nil == r {
|
||||||
r = DefaultRegistry
|
r = DefaultRegistry
|
||||||
}
|
}
|
||||||
return r.GetOrRegister(name, NewResettingTimer).(ResettingTimer)
|
return r.GetOrRegister(name, NewResettingTimer).(*ResettingTimer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRegisteredResettingTimer constructs and registers a new StandardResettingTimer.
|
// NewRegisteredResettingTimer constructs and registers a new ResettingTimer.
|
||||||
func NewRegisteredResettingTimer(name string, r Registry) ResettingTimer {
|
func NewRegisteredResettingTimer(name string, r Registry) *ResettingTimer {
|
||||||
c := NewResettingTimer()
|
c := NewResettingTimer()
|
||||||
if nil == r {
|
if nil == r {
|
||||||
r = DefaultRegistry
|
r = DefaultRegistry
|
||||||
|
|
@ -43,33 +24,15 @@ func NewRegisteredResettingTimer(name string, r Registry) ResettingTimer {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewResettingTimer constructs a new StandardResettingTimer
|
// NewResettingTimer constructs a new ResettingTimer
|
||||||
func NewResettingTimer() ResettingTimer {
|
func NewResettingTimer() *ResettingTimer {
|
||||||
if !metricsEnabled {
|
return &ResettingTimer{
|
||||||
return NilResettingTimer{}
|
values: make([]int64, 0, 10),
|
||||||
}
|
|
||||||
return &StandardResettingTimer{
|
|
||||||
values: make([]int64, 0, InitialResettingTimerSliceCap),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NilResettingTimer is a no-op ResettingTimer.
|
// ResettingTimer is used for storing aggregated values for timers, which are reset on every flush interval.
|
||||||
type NilResettingTimer struct{}
|
type ResettingTimer 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 {
|
|
||||||
values []int64
|
values []int64
|
||||||
sum int64 // sum is a running count of the total sum, used later to calculate mean
|
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.
|
// 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()
|
t.mutex.Lock()
|
||||||
defer t.mutex.Unlock()
|
defer t.mutex.Unlock()
|
||||||
snapshot := &resettingTimerSnapshot{}
|
snapshot := &ResettingTimerSnapshot{}
|
||||||
if len(t.values) > 0 {
|
if len(t.values) > 0 {
|
||||||
snapshot.mean = float64(t.sum) / float64(len(t.values))
|
snapshot.mean = float64(t.sum) / float64(len(t.values))
|
||||||
snapshot.values = t.values
|
snapshot.values = t.values
|
||||||
t.values = make([]int64, 0, InitialResettingTimerSliceCap)
|
t.values = make([]int64, 0, 10)
|
||||||
}
|
}
|
||||||
t.sum = 0
|
t.sum = 0
|
||||||
return snapshot
|
return snapshot
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record the duration of the execution of the given function.
|
// 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()
|
ts := time.Now()
|
||||||
f()
|
f()
|
||||||
t.Update(time.Since(ts))
|
t.Update(time.Since(ts))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record the duration of an event.
|
// Record the duration of an event.
|
||||||
func (t *StandardResettingTimer) Update(d time.Duration) {
|
func (t *ResettingTimer) Update(d time.Duration) {
|
||||||
t.mutex.Lock()
|
t.mutex.Lock()
|
||||||
defer t.mutex.Unlock()
|
defer t.mutex.Unlock()
|
||||||
t.values = append(t.values, int64(d))
|
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.
|
// 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))
|
t.Update(time.Since(ts))
|
||||||
}
|
}
|
||||||
|
|
||||||
// resettingTimerSnapshot is a point-in-time copy of another ResettingTimer.
|
// ResettingTimerSnapshot is a point-in-time copy of another ResettingTimer.
|
||||||
type resettingTimerSnapshot struct {
|
type ResettingTimerSnapshot struct {
|
||||||
values []int64
|
values []int64
|
||||||
mean float64
|
mean float64
|
||||||
max int64
|
max int64
|
||||||
|
|
@ -121,20 +84,20 @@ type resettingTimerSnapshot struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count return the length of the values from snapshot.
|
// Count return the length of the values from snapshot.
|
||||||
func (t *resettingTimerSnapshot) Count() int {
|
func (t *ResettingTimerSnapshot) Count() int {
|
||||||
return len(t.values)
|
return len(t.values)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Percentiles returns the boundaries for the input percentiles.
|
// Percentiles returns the boundaries for the input percentiles.
|
||||||
// note: this method is not thread safe
|
// note: this method is not thread safe
|
||||||
func (t *resettingTimerSnapshot) Percentiles(percentiles []float64) []float64 {
|
func (t *ResettingTimerSnapshot) Percentiles(percentiles []float64) []float64 {
|
||||||
t.calc(percentiles)
|
t.calc(percentiles)
|
||||||
return t.thresholdBoundaries
|
return t.thresholdBoundaries
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mean returns the mean of the snapshotted values
|
// Mean returns the mean of the snapshotted values
|
||||||
// note: this method is not thread safe
|
// note: this method is not thread safe
|
||||||
func (t *resettingTimerSnapshot) Mean() float64 {
|
func (t *ResettingTimerSnapshot) Mean() float64 {
|
||||||
if !t.calculated {
|
if !t.calculated {
|
||||||
t.calc(nil)
|
t.calc(nil)
|
||||||
}
|
}
|
||||||
|
|
@ -144,7 +107,7 @@ func (t *resettingTimerSnapshot) Mean() float64 {
|
||||||
|
|
||||||
// Max returns the max of the snapshotted values
|
// Max returns the max of the snapshotted values
|
||||||
// note: this method is not thread safe
|
// note: this method is not thread safe
|
||||||
func (t *resettingTimerSnapshot) Max() int64 {
|
func (t *ResettingTimerSnapshot) Max() int64 {
|
||||||
if !t.calculated {
|
if !t.calculated {
|
||||||
t.calc(nil)
|
t.calc(nil)
|
||||||
}
|
}
|
||||||
|
|
@ -153,14 +116,14 @@ func (t *resettingTimerSnapshot) Max() int64 {
|
||||||
|
|
||||||
// Min returns the min of the snapshotted values
|
// Min returns the min of the snapshotted values
|
||||||
// note: this method is not thread safe
|
// note: this method is not thread safe
|
||||||
func (t *resettingTimerSnapshot) Min() int64 {
|
func (t *ResettingTimerSnapshot) Min() int64 {
|
||||||
if !t.calculated {
|
if !t.calculated {
|
||||||
t.calc(nil)
|
t.calc(nil)
|
||||||
}
|
}
|
||||||
return t.min
|
return t.min
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *resettingTimerSnapshot) calc(percentiles []float64) {
|
func (t *ResettingTimerSnapshot) calc(percentiles []float64) {
|
||||||
scores := CalculatePercentiles(t.values, percentiles)
|
scores := CalculatePercentiles(t.values, percentiles)
|
||||||
t.thresholdBoundaries = scores
|
t.thresholdBoundaries = scores
|
||||||
if len(t.values) == 0 {
|
if len(t.values) == 0 {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue