Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

metrics: refactor metrics (part II) #28035

Merged
merged 26 commits into from
Sep 13, 2023
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
769aad4
metrics: add benchmarks
holiman Aug 30, 2023
1fc2e83
metrics: reduce lock contention in ewma
holiman Aug 30, 2023
16d39dd
metrics: update meter.go
holiman Aug 30, 2023
7e6f1a6
metrics: separate updatable/readonly meter, timer and histogram
holiman Aug 31, 2023
9591faf
metrics: separate updatable/readonly sample, runtimehistogram + do ea…
holiman Aug 31, 2023
b7f8d9b
metrics: split Gauge interface, fix tests, fix race on Sample
holiman Aug 31, 2023
36c31a6
metrics: split gaugefloat64 interface
holiman Aug 31, 2023
7b9dfc7
metrics: split up counter, counterfloat64
holiman Aug 31, 2023
73687d9
metrics: split up resetting timer interface
holiman Aug 31, 2023
fb8e300
metrics: make resettingtimer not expose internal values
holiman Aug 31, 2023
0abadec
metrics: align percentiles handling in resetting timer with rest of t…
holiman Aug 31, 2023
f4d0f94
metrics: split gaugeinfo into read/write
holiman Aug 31, 2023
4ae7427
metrics/infuxdb, metrics/prometheus: fix fallout from resetting-timer…
holiman Sep 1, 2023
9723df6
metrics: optimize expdecaysample, avoid iteration of values
holiman Sep 1, 2023
17765d2
metrics: linter nitpicks
holiman Sep 1, 2023
40f291b
metrics: optimize resetting timer, make influx resetting-timer span t…
holiman Sep 1, 2023
2ed1f05
metrics: split ewma, create dedicated nil snapshot type
holiman Sep 2, 2023
abefcdc
metrics: small leftover fixes
holiman Sep 3, 2023
55c3396
metrics: fix flaw re empty timer mean
holiman Sep 3, 2023
0295992
metrics: simplify interfaces, convert tests to table-driven
holiman Sep 4, 2023
90be12c
metrics: sample data for runtime metrics
holiman Sep 4, 2023
c8e1767
metrics: split read/write + improve runtime histogram speed
holiman Sep 4, 2023
2676560
metrics: apply suggestions from review
holiman Sep 11, 2023
8038c0f
metrics: cache sample variance, rm ineffectual clause rthistogram
holiman Sep 11, 2023
878680e
metrics: minor improvements to runtimehistogram loop
holiman Sep 11, 2023
7d352f8
metrics: oblige nitpicks from review
holiman Sep 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -1103,12 +1103,10 @@ func (s *StateDB) deleteStorage(addr common.Address, addrHash common.Hash, root
slotDeletionSkip.Inc(1)
}
n := int64(len(slots))
if n > slotDeletionMaxCount.Value() {
slotDeletionMaxCount.Update(n)
}
if int64(size) > slotDeletionMaxSize.Value() {
slotDeletionMaxSize.Update(int64(size))
}

slotDeletionMaxCount.UpdateIfGt(int64(len(slots)))
slotDeletionMaxSize.UpdateIfGt(int64(size))

slotDeletionTimer.UpdateSince(start)
slotDeletionCount.Mark(n)
slotDeletionSize.Mark(int64(size))
Expand Down
71 changes: 20 additions & 51 deletions metrics/counter.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ import (
"sync/atomic"
)

type CounterSnapshot interface {
Count() int64
}

// Counters hold an int64 value that can be incremented and decremented.
type Counter interface {
Clear()
Count() int64
Dec(int64)
Inc(int64)
Snapshot() Counter
Snapshot() CounterSnapshot
}

// GetOrRegisterCounter returns an existing Counter or constructs and registers
Expand Down Expand Up @@ -38,13 +41,13 @@ func NewCounter() Counter {
if !Enabled {
return NilCounter{}
}
return &StandardCounter{}
return new(StandardCounter)
}

// NewCounterForced constructs a new StandardCounter and returns it no matter if
// the global switch is enabled or not.
func NewCounterForced() Counter {
return &StandardCounter{}
return new(StandardCounter)
}

// NewRegisteredCounter constructs and registers a new StandardCounter.
Expand All @@ -70,75 +73,41 @@ func NewRegisteredCounterForced(name string, r Registry) Counter {
return c
}

// CounterSnapshot is a read-only copy of another Counter.
type CounterSnapshot int64

// Clear panics.
func (CounterSnapshot) Clear() {
panic("Clear called on a CounterSnapshot")
}
// counterSnapshot is a read-only copy of another Counter.
type counterSnapshot int64

// Count returns the count at the time the snapshot was taken.
func (c CounterSnapshot) Count() int64 { return int64(c) }

// Dec panics.
func (CounterSnapshot) Dec(int64) {
panic("Dec called on a CounterSnapshot")
}

// Inc panics.
func (CounterSnapshot) Inc(int64) {
panic("Inc called on a CounterSnapshot")
}

// Snapshot returns the snapshot.
func (c CounterSnapshot) Snapshot() Counter { return c }
func (c counterSnapshot) Count() int64 { return int64(c) }

// NilCounter is a no-op Counter.
type NilCounter struct{}

// Clear is a no-op.
holiman marked this conversation as resolved.
Show resolved Hide resolved
func (NilCounter) Clear() {}

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

// Dec is a no-op.
func (NilCounter) Dec(i int64) {}

// Inc is a no-op.
func (NilCounter) Inc(i int64) {}

// Snapshot is a no-op.
func (NilCounter) Snapshot() Counter { return NilCounter{} }
func (NilCounter) Clear() {}
func (NilCounter) Dec(i int64) {}
func (NilCounter) Inc(i int64) {}
func (NilCounter) Snapshot() CounterSnapshot { return (*emptySnapshot)(nil) }

// StandardCounter is the standard implementation of a Counter and uses the
// sync/atomic package to manage a single int64 value.
type StandardCounter struct {
count atomic.Int64
}
type StandardCounter atomic.Int64

// Clear sets the counter to zero.
func (c *StandardCounter) Clear() {
c.count.Store(0)
}

// Count returns the current count.
func (c *StandardCounter) Count() int64 {
return c.count.Load()
(*atomic.Int64)(c).Store(0)
}

// Dec decrements the counter by the given amount.
func (c *StandardCounter) Dec(i int64) {
c.count.Add(-i)
(*atomic.Int64)(c).Add(-i)
}

// Inc increments the counter by the given amount.
func (c *StandardCounter) Inc(i int64) {
c.count.Add(i)
(*atomic.Int64)(c).Add(i)
}

// Snapshot returns a read-only copy of the counter.
func (c *StandardCounter) Snapshot() Counter {
return CounterSnapshot(c.Count())
func (c *StandardCounter) Snapshot() CounterSnapshot {
return counterSnapshot((*atomic.Int64)(c).Load())
}
61 changes: 16 additions & 45 deletions metrics/counter_float64.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ import (
"sync/atomic"
)

type CounterFloat64Snapshot interface {
Count() float64
}

// CounterFloat64 holds a float64 value that can be incremented and decremented.
type CounterFloat64 interface {
Clear()
Count() float64
Dec(float64)
Inc(float64)
Snapshot() CounterFloat64
Snapshot() CounterFloat64Snapshot
}

// GetOrRegisterCounterFloat64 returns an existing CounterFloat64 or constructs and registers
Expand Down Expand Up @@ -71,47 +74,19 @@ func NewRegisteredCounterFloat64Forced(name string, r Registry) CounterFloat64 {
return c
}

// CounterFloat64Snapshot is a read-only copy of another CounterFloat64.
type CounterFloat64Snapshot float64

// Clear panics.
func (CounterFloat64Snapshot) Clear() {
panic("Clear called on a CounterFloat64Snapshot")
}
// counterFloat64Snapshot is a read-only copy of another CounterFloat64.
type counterFloat64Snapshot float64

// Count returns the value at the time the snapshot was taken.
func (c CounterFloat64Snapshot) Count() float64 { return float64(c) }

// Dec panics.
func (CounterFloat64Snapshot) Dec(float64) {
panic("Dec called on a CounterFloat64Snapshot")
}
func (c counterFloat64Snapshot) Count() float64 { return float64(c) }

// Inc panics.
func (CounterFloat64Snapshot) Inc(float64) {
panic("Inc called on a CounterFloat64Snapshot")
}

// Snapshot returns the snapshot.
func (c CounterFloat64Snapshot) Snapshot() CounterFloat64 { return c }

// NilCounterFloat64 is a no-op CounterFloat64.
type NilCounterFloat64 struct{}

// Clear is a no-op.
func (NilCounterFloat64) Clear() {}

// Count is a no-op.
func (NilCounterFloat64) Count() float64 { return 0.0 }

// Dec is a no-op.
func (NilCounterFloat64) Dec(i float64) {}

// Inc is a no-op.
func (NilCounterFloat64) Inc(i float64) {}

// Snapshot is a no-op.
func (NilCounterFloat64) Snapshot() CounterFloat64 { return NilCounterFloat64{} }
func (NilCounterFloat64) Clear() {}
func (NilCounterFloat64) Count() float64 { return 0.0 }
func (NilCounterFloat64) Dec(i float64) {}
func (NilCounterFloat64) Inc(i float64) {}
func (NilCounterFloat64) Snapshot() CounterFloat64Snapshot { return NilCounterFloat64{} }

// StandardCounterFloat64 is the standard implementation of a CounterFloat64 and uses the
// atomic to manage a single float64 value.
Expand All @@ -124,11 +99,6 @@ func (c *StandardCounterFloat64) Clear() {
c.floatBits.Store(0)
}

// Count returns the current value.
func (c *StandardCounterFloat64) Count() float64 {
return math.Float64frombits(c.floatBits.Load())
}

// Dec decrements the counter by the given amount.
func (c *StandardCounterFloat64) Dec(v float64) {
atomicAddFloat(&c.floatBits, -v)
Expand All @@ -140,8 +110,9 @@ func (c *StandardCounterFloat64) Inc(v float64) {
}

// Snapshot returns a read-only copy of the counter.
func (c *StandardCounterFloat64) Snapshot() CounterFloat64 {
return CounterFloat64Snapshot(c.Count())
func (c *StandardCounterFloat64) Snapshot() CounterFloat64Snapshot {
v := math.Float64frombits(c.floatBits.Load())
return counterFloat64Snapshot(v)
}

func atomicAddFloat(fbits *atomic.Uint64, v float64) {
Expand Down
16 changes: 8 additions & 8 deletions metrics/counter_float_64_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func BenchmarkCounterFloat64Parallel(b *testing.B) {
}()
}
wg.Wait()
if have, want := c.Count(), 10.0*float64(b.N); have != want {
if have, want := c.Snapshot().Count(), 10.0*float64(b.N); have != want {
b.Fatalf("have %f want %f", have, want)
}
}
Expand All @@ -36,39 +36,39 @@ func TestCounterFloat64Clear(t *testing.T) {
c := NewCounterFloat64()
c.Inc(1.0)
c.Clear()
if count := c.Count(); count != 0 {
if count := c.Snapshot().Count(); count != 0 {
t.Errorf("c.Count(): 0 != %v\n", count)
}
}

func TestCounterFloat64Dec1(t *testing.T) {
c := NewCounterFloat64()
c.Dec(1.0)
if count := c.Count(); count != -1.0 {
if count := c.Snapshot().Count(); count != -1.0 {
t.Errorf("c.Count(): -1.0 != %v\n", count)
}
}

func TestCounterFloat64Dec2(t *testing.T) {
c := NewCounterFloat64()
c.Dec(2.0)
if count := c.Count(); count != -2.0 {
if count := c.Snapshot().Count(); count != -2.0 {
t.Errorf("c.Count(): -2.0 != %v\n", count)
}
}

func TestCounterFloat64Inc1(t *testing.T) {
c := NewCounterFloat64()
c.Inc(1.0)
if count := c.Count(); count != 1.0 {
if count := c.Snapshot().Count(); count != 1.0 {
t.Errorf("c.Count(): 1.0 != %v\n", count)
}
}

func TestCounterFloat64Inc2(t *testing.T) {
c := NewCounterFloat64()
c.Inc(2.0)
if count := c.Count(); count != 2.0 {
if count := c.Snapshot().Count(); count != 2.0 {
t.Errorf("c.Count(): 2.0 != %v\n", count)
}
}
Expand All @@ -85,15 +85,15 @@ func TestCounterFloat64Snapshot(t *testing.T) {

func TestCounterFloat64Zero(t *testing.T) {
c := NewCounterFloat64()
if count := c.Count(); count != 0 {
if count := c.Snapshot().Count(); count != 0 {
t.Errorf("c.Count(): 0 != %v\n", count)
}
}

func TestGetOrRegisterCounterFloat64(t *testing.T) {
r := NewRegistry()
NewRegisteredCounterFloat64("foo", r).Inc(47.0)
if c := GetOrRegisterCounterFloat64("foo", r); c.Count() != 47.0 {
if c := GetOrRegisterCounterFloat64("foo", r).Snapshot(); c.Count() != 47.0 {
t.Fatal(c)
}
}
14 changes: 7 additions & 7 deletions metrics/counter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,39 +14,39 @@ func TestCounterClear(t *testing.T) {
c := NewCounter()
c.Inc(1)
c.Clear()
if count := c.Count(); count != 0 {
if count := c.Snapshot().Count(); count != 0 {
t.Errorf("c.Count(): 0 != %v\n", count)
}
}

func TestCounterDec1(t *testing.T) {
c := NewCounter()
c.Dec(1)
if count := c.Count(); count != -1 {
if count := c.Snapshot().Count(); count != -1 {
t.Errorf("c.Count(): -1 != %v\n", count)
}
}

func TestCounterDec2(t *testing.T) {
c := NewCounter()
c.Dec(2)
if count := c.Count(); count != -2 {
if count := c.Snapshot().Count(); count != -2 {
t.Errorf("c.Count(): -2 != %v\n", count)
}
}

func TestCounterInc1(t *testing.T) {
c := NewCounter()
c.Inc(1)
if count := c.Count(); count != 1 {
if count := c.Snapshot().Count(); count != 1 {
t.Errorf("c.Count(): 1 != %v\n", count)
}
}

func TestCounterInc2(t *testing.T) {
c := NewCounter()
c.Inc(2)
if count := c.Count(); count != 2 {
if count := c.Snapshot().Count(); count != 2 {
t.Errorf("c.Count(): 2 != %v\n", count)
}
}
Expand All @@ -63,15 +63,15 @@ func TestCounterSnapshot(t *testing.T) {

func TestCounterZero(t *testing.T) {
c := NewCounter()
if count := c.Count(); count != 0 {
if count := c.Snapshot().Count(); count != 0 {
t.Errorf("c.Count(): 0 != %v\n", count)
}
}

func TestGetOrRegisterCounter(t *testing.T) {
r := NewRegistry()
NewRegisteredCounter("foo", r).Inc(47)
if c := GetOrRegisterCounter("foo", r); c.Count() != 47 {
if c := GetOrRegisterCounter("foo", r).Snapshot(); c.Count() != 47 {
t.Fatal(c)
}
}
4 changes: 0 additions & 4 deletions metrics/doc.go

This file was deleted.

Loading