diff --git a/metrics/inactive.go b/metrics/inactive.go index 1f47f0210af3..37f45732520b 100644 --- a/metrics/inactive.go +++ b/metrics/inactive.go @@ -16,6 +16,8 @@ package metrics +import "time" + // compile-time checks that interfaces are implemented. var ( _ SampleSnapshot = (*emptySnapshot)(nil) @@ -46,3 +48,4 @@ func (*emptySnapshot) Rate1() float64 { return 0.0 } func (*emptySnapshot) Rate5() float64 { return 0.0 } func (*emptySnapshot) Rate15() float64 { return 0.0 } func (*emptySnapshot) RateMean() float64 { return 0.0 } +func (*emptySnapshot) Total() time.Duration { return 0 } diff --git a/metrics/influxdb/influxdb.go b/metrics/influxdb/influxdb.go index 9a1b462f7e11..ff0d9d37f31e 100644 --- a/metrics/influxdb/influxdb.go +++ b/metrics/influxdb/influxdb.go @@ -95,6 +95,7 @@ func readMeter(namespace, name string, i interface{}) (string, map[string]interf "m5": ms.Rate5(), "m15": ms.Rate15(), "meanrate": ms.RateMean(), + "total": int64(ms.Total()), } return measurement, fields case metrics.ResettingTimer: diff --git a/metrics/influxdb/influxdbv2.go b/metrics/influxdb/influxdbv2.go index b17024b36b45..1b0f92ca0245 100644 --- a/metrics/influxdb/influxdbv2.go +++ b/metrics/influxdb/influxdbv2.go @@ -4,10 +4,10 @@ import ( "context" "time" - "github.com/scroll-tech/go-ethereum/log" - "github.com/scroll-tech/go-ethereum/metrics" influxdb2 "github.com/influxdata/influxdb-client-go/v2" "github.com/influxdata/influxdb-client-go/v2/api" + "github.com/scroll-tech/go-ethereum/log" + "github.com/scroll-tech/go-ethereum/metrics" ) type v2Reporter struct { diff --git a/metrics/timer.go b/metrics/timer.go index 576ad8aa3e63..03d840999c77 100644 --- a/metrics/timer.go +++ b/metrics/timer.go @@ -8,6 +8,7 @@ import ( type TimerSnapshot interface { HistogramSnapshot MeterSnapshot + Total() time.Duration } // Timers capture the duration and rate of events. @@ -17,6 +18,7 @@ type Timer interface { Time(func()) UpdateSince(time.Time) Update(time.Duration) + Total() time.Duration } // GetOrRegisterTimer returns an existing Timer or constructs and registers a @@ -76,11 +78,14 @@ func (NilTimer) Time(f func()) { f() } func (NilTimer) Update(time.Duration) {} func (NilTimer) UpdateSince(time.Time) {} +func (NilTimer) Total() time.Duration { return time.Duration(0) } + // StandardTimer is the standard implementation of a Timer and uses a Histogram // and Meter. type StandardTimer struct { histogram Histogram meter Meter + total time.Duration mutex sync.Mutex } @@ -91,6 +96,7 @@ func (t *StandardTimer) Snapshot() TimerSnapshot { return &timerSnapshot{ histogram: t.histogram.Snapshot(), meter: t.meter.Snapshot(), + total: t.total, } } @@ -112,20 +118,24 @@ func (t *StandardTimer) Update(d time.Duration) { defer t.mutex.Unlock() t.histogram.Update(int64(d)) t.meter.Mark(1) + t.total += d } // 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) + t.Update(time.Since(ts)) +} + +// Total returns the total time that events observed by this timer took +func (t *StandardTimer) Total() time.Duration { + return t.total } // timerSnapshot is a read-only copy of another Timer. type timerSnapshot struct { histogram HistogramSnapshot meter MeterSnapshot + total time.Duration } // Count returns the number of events recorded at the time the snapshot was @@ -182,3 +192,8 @@ func (t *timerSnapshot) Sum() int64 { return t.histogram.Sum() } // Variance returns the variance of the values at the time the snapshot was // taken. func (t *timerSnapshot) Variance() float64 { return t.histogram.Variance() } + +// Total returns the total time that events observed by this timer took +func (t *timerSnapshot) Total() time.Duration { + return t.total +} diff --git a/metrics/timer_test.go b/metrics/timer_test.go index f10de16c9c23..5eb8f5513df1 100644 --- a/metrics/timer_test.go +++ b/metrics/timer_test.go @@ -112,3 +112,18 @@ func ExampleGetOrRegisterTimer() { t.Update(47) fmt.Println(t.Snapshot().Max()) // Output: 47 } + +func TestTimerSum(t *testing.T) { + tm := GetOrRegisterTimer("test.timer.sum", nil) + times := 5000000 + for i := 0; i < times; i++ { + tm.Update(time.Second) + } + ss := tm.Snapshot() + if total := tm.Total().Seconds(); total != float64(times) { + t.Errorf("tm.Total().Seconds(): 5000000.0 != %v\n", total) + } + if total := ss.Total().Seconds(); total != float64(times) { + t.Errorf("ss.Total().Seconds(): 5000000.0 != %v\n", total) + } +}