go-ethereum/metrics/metrics_test.go
Martin HS 9045b79bc2
metrics, cmd/geth: change init-process of metrics (#30814)
This PR modifies how the metrics library handles `Enabled`: previously,
the package `init` decided whether to serve real metrics or just
dummy-types.

This has several drawbacks: 
- During pkg init, we need to determine whether metrics are enabled or
not. So we first hacked in a check if certain geth-specific
commandline-flags were enabled. Then we added a similar check for
geth-env-vars. Then we almost added a very elaborate check for
toml-config-file, plus toml parsing.

- Using "real" types and dummy types interchangeably means that
everything is hidden behind interfaces. This has a performance penalty,
and also it just adds a lot of code.

This PR removes the interface stuff, uses concrete types, and allows for
the setting of Enabled to happen later. It is still assumed that
`metrics.Enable()` is invoked early on.

The somewhat 'heavy' operations, such as ticking meters and exp-decay,
now checks the enable-flag to prevent resource leak.

The change may be large, but it's mostly pretty trivial, and from the
last time I gutted the metrics, I ensured that we have fairly good test
coverage.

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
2024-12-10 13:27:29 +01:00

63 lines
1.2 KiB
Go

package metrics
import (
"fmt"
"sync"
"testing"
"time"
)
func TestReadRuntimeValues(t *testing.T) {
var v runtimeStats
readRuntimeStats(&v)
t.Logf("%+v", v)
}
func BenchmarkMetrics(b *testing.B) {
var (
r = NewRegistry()
c = NewRegisteredCounter("counter", r)
cf = NewRegisteredCounterFloat64("counterfloat64", r)
g = NewRegisteredGauge("gauge", r)
gf = NewRegisteredGaugeFloat64("gaugefloat64", r)
h = NewRegisteredHistogram("histogram", r, NewUniformSample(100))
m = NewRegisteredMeter("meter", r)
t = NewRegisteredTimer("timer", r)
)
RegisterDebugGCStats(r)
b.ResetTimer()
var wg sync.WaitGroup
wg.Add(128)
for i := 0; i < 128; i++ {
go func() {
defer wg.Done()
for i := 0; i < b.N; i++ {
c.Inc(1)
cf.Inc(1.0)
g.Update(int64(i))
gf.Update(float64(i))
h.Update(int64(i))
m.Mark(1)
t.Update(1)
}
}()
}
wg.Wait()
}
func Example() {
c := NewCounter()
Register("money", c)
c.Inc(17)
// Threadsafe registration
t := GetOrRegisterTimer("db.get.latency", nil)
t.Time(func() { time.Sleep(10 * time.Millisecond) })
t.Update(1)
fmt.Println(c.Snapshot().Count())
fmt.Println(t.Snapshot().Min())
// Output: 17
// 1
}