mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
metrics: split up resetting timer interface
This commit is contained in:
parent
7b9dfc72c1
commit
73687d9a60
2 changed files with 67 additions and 115 deletions
|
|
@ -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.ResettingTimer) {
|
func (c *collector) addResettingTimer(name string, m metrics.ResettingTimerSnapshot) {
|
||||||
if len(m.Values()) <= 0 {
|
if len(m.Values()) <= 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,12 +11,15 @@ import (
|
||||||
// Initial slice capacity for the values stored in a ResettingTimer
|
// Initial slice capacity for the values stored in a ResettingTimer
|
||||||
const InitialResettingTimerSliceCap = 10
|
const InitialResettingTimerSliceCap = 10
|
||||||
|
|
||||||
|
type ResettingTimerSnapshot interface {
|
||||||
|
Values() []int64
|
||||||
|
Mean() float64
|
||||||
|
Percentiles([]float64) []int64
|
||||||
|
}
|
||||||
|
|
||||||
// ResettingTimer is used for storing aggregated values for timers, which are reset on every flush interval.
|
// ResettingTimer is used for storing aggregated values for timers, which are reset on every flush interval.
|
||||||
type ResettingTimer interface {
|
type ResettingTimer interface {
|
||||||
Values() []int64
|
Snapshot() ResettingTimerSnapshot
|
||||||
Snapshot() ResettingTimer
|
|
||||||
Percentiles([]float64) []int64
|
|
||||||
Mean() float64
|
|
||||||
Time(func())
|
Time(func())
|
||||||
Update(time.Duration)
|
Update(time.Duration)
|
||||||
UpdateSince(time.Time)
|
UpdateSince(time.Time)
|
||||||
|
|
@ -52,37 +55,15 @@ func NewResettingTimer() ResettingTimer {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NilResettingTimer is a no-op ResettingTimer.
|
// NilResettingTimer is a no-op ResettingTimer.
|
||||||
type NilResettingTimer struct {
|
type NilResettingTimer struct{}
|
||||||
}
|
|
||||||
|
|
||||||
// Values is a no-op.
|
func (NilResettingTimer) Values() []int64 { return nil }
|
||||||
func (NilResettingTimer) Values() []int64 { return nil }
|
func (n NilResettingTimer) Snapshot() ResettingTimerSnapshot { return n }
|
||||||
|
func (NilResettingTimer) Time(f func()) { f() }
|
||||||
// Snapshot is a no-op.
|
func (NilResettingTimer) Update(time.Duration) {}
|
||||||
func (NilResettingTimer) Snapshot() ResettingTimer {
|
func (NilResettingTimer) Percentiles([]float64) []int64 { return nil }
|
||||||
return &ResettingTimerSnapshot{
|
func (NilResettingTimer) Mean() float64 { return 0.0 }
|
||||||
values: []int64{},
|
func (NilResettingTimer) UpdateSince(time.Time) {}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Time is a no-op.
|
|
||||||
func (NilResettingTimer) Time(f func()) { f() }
|
|
||||||
|
|
||||||
// Update is a no-op.
|
|
||||||
func (NilResettingTimer) Update(time.Duration) {}
|
|
||||||
|
|
||||||
// Percentiles panics.
|
|
||||||
func (NilResettingTimer) Percentiles([]float64) []int64 {
|
|
||||||
panic("Percentiles called on a NilResettingTimer")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mean panics.
|
|
||||||
func (NilResettingTimer) Mean() float64 {
|
|
||||||
panic("Mean called on a NilResettingTimer")
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateSince is a no-op.
|
|
||||||
func (NilResettingTimer) UpdateSince(time.Time) {}
|
|
||||||
|
|
||||||
// StandardResettingTimer is the standard implementation of a ResettingTimer.
|
// StandardResettingTimer is the standard implementation of a ResettingTimer.
|
||||||
// and Meter.
|
// and Meter.
|
||||||
|
|
@ -91,33 +72,23 @@ type StandardResettingTimer struct {
|
||||||
mutex sync.Mutex
|
mutex sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// Values returns a slice with all measurements.
|
//// Values returns a slice with all measurements.
|
||||||
func (t *StandardResettingTimer) Values() []int64 {
|
//func (t *StandardResettingTimer) Values() []int64 {
|
||||||
return t.values
|
// return t.values
|
||||||
}
|
//}
|
||||||
|
|
||||||
// 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() ResettingTimer {
|
func (t *StandardResettingTimer) Snapshot() ResettingTimerSnapshot {
|
||||||
t.mutex.Lock()
|
t.mutex.Lock()
|
||||||
defer t.mutex.Unlock()
|
defer t.mutex.Unlock()
|
||||||
currentValues := t.values
|
currentValues := t.values
|
||||||
t.values = make([]int64, 0, InitialResettingTimerSliceCap)
|
t.values = make([]int64, 0, InitialResettingTimerSliceCap)
|
||||||
|
|
||||||
return &ResettingTimerSnapshot{
|
return &resettingTimerSnapshot{
|
||||||
values: currentValues,
|
values: currentValues,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Percentiles panics.
|
|
||||||
func (t *StandardResettingTimer) Percentiles([]float64) []int64 {
|
|
||||||
panic("Percentiles called on a StandardResettingTimer")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mean panics.
|
|
||||||
func (t *StandardResettingTimer) Mean() float64 {
|
|
||||||
panic("Mean called on a StandardResettingTimer")
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 *StandardResettingTimer) Time(f func()) {
|
||||||
ts := time.Now()
|
ts := time.Now()
|
||||||
|
|
@ -139,46 +110,29 @@ func (t *StandardResettingTimer) UpdateSince(ts time.Time) {
|
||||||
t.values = append(t.values, int64(time.Since(ts)))
|
t.values = append(t.values, int64(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
|
||||||
thresholdBoundaries []int64
|
thresholdBoundaries []int64
|
||||||
calculated bool
|
calculated bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Snapshot returns the snapshot.
|
|
||||||
func (t *ResettingTimerSnapshot) Snapshot() ResettingTimer { return t }
|
|
||||||
|
|
||||||
// Time panics.
|
|
||||||
func (*ResettingTimerSnapshot) Time(func()) {
|
|
||||||
panic("Time called on a ResettingTimerSnapshot")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update panics.
|
|
||||||
func (*ResettingTimerSnapshot) Update(time.Duration) {
|
|
||||||
panic("Update called on a ResettingTimerSnapshot")
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateSince panics.
|
|
||||||
func (*ResettingTimerSnapshot) UpdateSince(time.Time) {
|
|
||||||
panic("UpdateSince called on a ResettingTimerSnapshot")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Values returns all values from snapshot.
|
// Values returns all values from snapshot.
|
||||||
func (t *ResettingTimerSnapshot) Values() []int64 {
|
func (t *resettingTimerSnapshot) Values() []int64 {
|
||||||
return t.values
|
return t.values
|
||||||
}
|
}
|
||||||
|
|
||||||
// Percentiles returns the boundaries for the input percentiles.
|
// Percentiles returns the boundaries for the input percentiles.
|
||||||
func (t *ResettingTimerSnapshot) Percentiles(percentiles []float64) []int64 {
|
// note: this method is not thread safe
|
||||||
|
func (t *resettingTimerSnapshot) Percentiles(percentiles []float64) []int64 {
|
||||||
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
|
||||||
func (t *ResettingTimerSnapshot) Mean() float64 {
|
// note: this method is not thread safe
|
||||||
|
func (t *resettingTimerSnapshot) Mean() float64 {
|
||||||
if !t.calculated {
|
if !t.calculated {
|
||||||
t.calc([]float64{})
|
t.calc([]float64{})
|
||||||
}
|
}
|
||||||
|
|
@ -186,50 +140,48 @@ func (t *ResettingTimerSnapshot) Mean() float64 {
|
||||||
return t.mean
|
return t.mean
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *ResettingTimerSnapshot) calc(percentiles []float64) {
|
func (t *resettingTimerSnapshot) calc(percentiles []float64) {
|
||||||
slices.Sort(t.values)
|
slices.Sort(t.values)
|
||||||
|
|
||||||
count := len(t.values)
|
count := len(t.values)
|
||||||
if count > 0 {
|
if count == 0 {
|
||||||
min := t.values[0]
|
|
||||||
max := t.values[count-1]
|
|
||||||
|
|
||||||
cumulativeValues := make([]int64, count)
|
|
||||||
cumulativeValues[0] = min
|
|
||||||
for i := 1; i < count; i++ {
|
|
||||||
cumulativeValues[i] = t.values[i] + cumulativeValues[i-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
t.thresholdBoundaries = make([]int64, len(percentiles))
|
|
||||||
|
|
||||||
thresholdBoundary := max
|
|
||||||
|
|
||||||
for i, pct := range percentiles {
|
|
||||||
if count > 1 {
|
|
||||||
var abs float64
|
|
||||||
if pct >= 0 {
|
|
||||||
abs = pct
|
|
||||||
} else {
|
|
||||||
abs = 100 + pct
|
|
||||||
}
|
|
||||||
// poor man's math.Round(x):
|
|
||||||
// math.Floor(x + 0.5)
|
|
||||||
indexOfPerc := int(math.Floor(((abs / 100.0) * float64(count)) + 0.5))
|
|
||||||
if pct >= 0 && indexOfPerc > 0 {
|
|
||||||
indexOfPerc -= 1 // index offset=0
|
|
||||||
}
|
|
||||||
thresholdBoundary = t.values[indexOfPerc]
|
|
||||||
}
|
|
||||||
|
|
||||||
t.thresholdBoundaries[i] = thresholdBoundary
|
|
||||||
}
|
|
||||||
|
|
||||||
sum := cumulativeValues[count-1]
|
|
||||||
t.mean = float64(sum) / float64(count)
|
|
||||||
} else {
|
|
||||||
t.thresholdBoundaries = make([]int64, len(percentiles))
|
t.thresholdBoundaries = make([]int64, len(percentiles))
|
||||||
t.mean = 0
|
t.mean = 0
|
||||||
|
t.calculated = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
min := t.values[0]
|
||||||
|
max := t.values[count-1]
|
||||||
|
|
||||||
|
cumulativeValues := make([]int64, count)
|
||||||
|
cumulativeValues[0] = min
|
||||||
|
for i := 1; i < count; i++ {
|
||||||
|
cumulativeValues[i] = t.values[i] + cumulativeValues[i-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
t.calculated = true
|
t.thresholdBoundaries = make([]int64, len(percentiles))
|
||||||
|
|
||||||
|
thresholdBoundary := max
|
||||||
|
|
||||||
|
for i, pct := range percentiles {
|
||||||
|
if count > 1 {
|
||||||
|
var abs float64
|
||||||
|
if pct >= 0 {
|
||||||
|
abs = pct
|
||||||
|
} else {
|
||||||
|
abs = 100 + pct
|
||||||
|
}
|
||||||
|
// poor man's math.Round(x):
|
||||||
|
// math.Floor(x + 0.5)
|
||||||
|
indexOfPerc := int(math.Floor(((abs / 100.0) * float64(count)) + 0.5))
|
||||||
|
if pct >= 0 && indexOfPerc > 0 {
|
||||||
|
indexOfPerc -= 1 // index offset=0
|
||||||
|
}
|
||||||
|
thresholdBoundary = t.values[indexOfPerc]
|
||||||
|
}
|
||||||
|
|
||||||
|
t.thresholdBoundaries[i] = thresholdBoundary
|
||||||
|
}
|
||||||
|
|
||||||
|
sum := cumulativeValues[count-1]
|
||||||
|
t.mean = float64(sum) / float64(count)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue