mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-02-26 07:37:20 +00:00
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>
83 lines
2.1 KiB
Go
83 lines
2.1 KiB
Go
//go:build !windows
|
|
// +build !windows
|
|
|
|
package metrics
|
|
|
|
import (
|
|
"fmt"
|
|
"log/syslog"
|
|
"time"
|
|
)
|
|
|
|
// Output each metric in the given registry to syslog periodically using
|
|
// the given syslogger.
|
|
func Syslog(r Registry, d time.Duration, w *syslog.Writer) {
|
|
for range time.Tick(d) {
|
|
r.Each(func(name string, i interface{}) {
|
|
switch metric := i.(type) {
|
|
case *Counter:
|
|
w.Info(fmt.Sprintf("counter %s: count: %d", name, metric.Snapshot().Count()))
|
|
case *CounterFloat64:
|
|
w.Info(fmt.Sprintf("counter %s: count: %f", name, metric.Snapshot().Count()))
|
|
case *Gauge:
|
|
w.Info(fmt.Sprintf("gauge %s: value: %d", name, metric.Snapshot().Value()))
|
|
case *GaugeFloat64:
|
|
w.Info(fmt.Sprintf("gauge %s: value: %f", name, metric.Snapshot().Value()))
|
|
case *GaugeInfo:
|
|
w.Info(fmt.Sprintf("gauge %s: value: %s", name, metric.Snapshot().Value()))
|
|
case *Healthcheck:
|
|
metric.Check()
|
|
w.Info(fmt.Sprintf("healthcheck %s: error: %v", name, metric.Error()))
|
|
case Histogram:
|
|
h := metric.Snapshot()
|
|
ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
|
|
w.Info(fmt.Sprintf(
|
|
"histogram %s: count: %d min: %d max: %d mean: %.2f stddev: %.2f median: %.2f 75%%: %.2f 95%%: %.2f 99%%: %.2f 99.9%%: %.2f",
|
|
name,
|
|
h.Count(),
|
|
h.Min(),
|
|
h.Max(),
|
|
h.Mean(),
|
|
h.StdDev(),
|
|
ps[0],
|
|
ps[1],
|
|
ps[2],
|
|
ps[3],
|
|
ps[4],
|
|
))
|
|
case *Meter:
|
|
m := metric.Snapshot()
|
|
w.Info(fmt.Sprintf(
|
|
"meter %s: count: %d 1-min: %.2f 5-min: %.2f 15-min: %.2f mean: %.2f",
|
|
name,
|
|
m.Count(),
|
|
m.Rate1(),
|
|
m.Rate5(),
|
|
m.Rate15(),
|
|
m.RateMean(),
|
|
))
|
|
case *Timer:
|
|
t := metric.Snapshot()
|
|
ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
|
|
w.Info(fmt.Sprintf(
|
|
"timer %s: count: %d min: %d max: %d mean: %.2f stddev: %.2f median: %.2f 75%%: %.2f 95%%: %.2f 99%%: %.2f 99.9%%: %.2f 1-min: %.2f 5-min: %.2f 15-min: %.2f mean-rate: %.2f",
|
|
name,
|
|
t.Count(),
|
|
t.Min(),
|
|
t.Max(),
|
|
t.Mean(),
|
|
t.StdDev(),
|
|
ps[0],
|
|
ps[1],
|
|
ps[2],
|
|
ps[3],
|
|
ps[4],
|
|
t.Rate1(),
|
|
t.Rate5(),
|
|
t.Rate15(),
|
|
t.RateMean(),
|
|
))
|
|
}
|
|
})
|
|
}
|
|
}
|