Commit graph

133 commits

Author SHA1 Message Date
Daniel Liu
b71279d442
feat(metrics): allow changing influxdb interval #33767 (#2118) 2026-03-06 11:24:00 +05:30
Daniel Liu
11471fd4b0
fix(metrics): add missing GaugeInfo case in GetAll() #33748 (#2041)
GetAll did not return GaugeInfo metrics, which affects "chain/info" and "geth/info".

Co-authored-by: vickkkkkyy <vickyaviles847@gmail.com>
2026-02-28 16:53:35 +04:00
Daniel Liu
7fce11d1f1
fix(metrics): add missing ResettingTimer case in GetAll() #33749 (#2038)
Follow-up to https://github.com/ethereum/go-ethereum/pull/33748

Same issue - ResettingTimer can be registered via loadOrRegister() but
GetAll() silently drops it during JSON export. The prometheus exporter
handles it fine (collector.go:70), so this is just an oversight in the
JSON path.

Note: ResettingTimer.Snapshot() resets the timer by design, which is
consistent with how the prometheus exporter uses it.

Co-authored-by: vickkkkkyy <vickyaviles847@gmail.com>
2026-02-28 16:52:33 +04:00
Daniel Liu
6d11ab7bee
perf(metrics): reduce allocations for metrics #33699 (#2037)
Co-authored-by: Marius van der Wijden <m.vanderwijden@live.de>
2026-02-28 16:52:03 +04:00
Daniel Liu
640d448491
cmd/XDC, metrics/prometheus: fix staticcheck QF1012 (#1713) 2025-12-07 16:03:06 +05:30
Daniel Liu
eaaeea0cad
all: use slices.Sort() to sort strings (#1712) 2025-12-07 15:49:13 +05:30
Daniel Liu
ec08863ba0
all: use WaigGroup.Go() to simplify code (#1699) 2025-11-29 17:17:08 +05:30
Daniel Liu
eef5242fa3
all: pre-allocate memory for slices and maps, close XFN-148 (#1714) 2025-11-14 20:13:36 +05:30
wit liu
6a1fa08d02
all: refactor to use builtin max/min #32694 (#1596) 2025-10-08 12:52:22 +08:00
Daniel Liu
a9c1861708
metrics: add tinygo build flag for CPU time #32454 (#1566)
Co-authored-by: kevaundray <kevtheappdev@gmail.com>
2025-09-24 07:55:37 +08:00
Daniel Liu
6c2315f9a5
metrics: use atomic.Pointer in runtimeHistogram #32361 (#1564)
Co-authored-by: cui <cuiweixie@gmail.com>
Co-authored-by: Felix Lange <fjl@twurst.com>
2025-09-24 07:53:29 +08:00
Daniel Liu
71626cff76
metrics: remove use of reflect in metrics registration code #31962 (#1561)
Co-authored-by: Ömer Faruk Irmak <omerfirmak@gmail.com>
Co-authored-by: Marius van der Wijden <m.vanderwijden@live.de>
2025-09-24 07:51:36 +08:00
Daniel Liu
057d840380
metrics: disable CPU metrics on tinygo #31953 (#1559)
Co-authored-by: Ömer Faruk Irmak <omerfirmak@gmail.com>
2025-09-24 07:50:35 +08:00
Daniel Liu
27c4be76fd
metrics: spin up meter ticker routine when enabling metric system #31400 (#1558)
Addresses https://github.com/ethereum/go-ethereum/issues/31244

Co-authored-by: Mike Weyandt <mike@mikeweyandt.com>
2025-09-24 07:50:03 +08:00
Daniel Liu
13d64fb5b5
metrics: fix some typos in comments and names #31023 (#1557) 2025-09-22 20:44:29 +08:00
Ryan Tinianov
76a5008ec7 all: add build tags for wasip1 (#31090) 2025-03-19 18:02:46 +08:00
Daniel Liu
6beee27886 metrics, cmd/XDC: 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-13 14:00:14 +08:00
Daniel Liu
7d82f27894 metrics: fix issues with benchmarks (#30667) 2024-12-13 14:00:14 +08:00
Daniel Liu
ea355e824b metrics: fix function comment (#29843) 2024-12-13 14:00:14 +08:00
Daniel Liu
7e784f1d70 metrics: add test for SampleSnapshot.Sum (#29831) 2024-12-13 14:00:14 +08:00
Daniel Liu
fb6a268763 metrics: fix flaky test TestExpDecaySampleNanosecondRegression (#29832) 2024-12-13 14:00:14 +08:00
Daniel Liu
a9cbcde778 metrics: fix out of range error message (#29821) 2024-12-13 14:00:14 +08:00
Daniel Liu
cf90a7aa76 metrics: remove librato (#29624) 2024-12-13 14:00:14 +08:00
Daniel Liu
988465cafa metrics: fix mismatched names in comments (#29348) 2024-12-13 14:00:14 +08:00
Daniel Liu
c7565af9b8 metrics: remove dependency on golang.org/exp (#29314) 2024-12-13 14:00:14 +08:00
Daniel Liu
99f605ffab metrics/influxdb: skip float64-precision-dependent tests on arm64 (#29047)
metrics/influxdb: fix failed cases caused by float64 precision on arm64
2024-12-13 14:00:14 +08:00
Daniel Liu
fd8782b2d0 metrics: use min from go1.21 (#29307) 2024-12-13 14:00:14 +08:00
Daniel Liu
7f37ee2e63 metrics: fix docstrings (#29279) 2024-12-13 14:00:14 +08:00
Daniel Liu
2220156b9a cmd, core, metrics: always report expensive metrics (#29191)
* cmd, core, metrics: always report expensive metrics

* core, metrics: report block processing metrics as resetting timer

* metrics: update reporter tests
2024-12-13 14:00:13 +08:00
Daniel Liu
6f67b357de metrics: fix docstring names (#28923) 2024-12-13 14:00:13 +08:00
Daniel Liu
49b5886150 rpc: fix ns/µs mismatch in metrics (#28649)
The rpc/duration/all meter was in nanoseconds, the individual meter in microseconds.
This PR changes it so both of them use nanoseconds.
2024-12-13 14:00:13 +08:00
Daniel Liu
2f36a79f67 metrics: add support for enabling metrics from env vars (#28118) 2024-12-13 14:00:13 +08:00
Daniel Liu
cc4ea7a685 metrics: refactor metrics (#28035)
This change includes a lot of things, listed below.

The interfaces have been split up into one write-interface and one read-interface, with `Snapshot` being the gateway from write to read. This simplifies the semantics _a lot_.

Example of splitting up an interface into one readonly 'snapshot' part, and one updatable writeonly part:

```golang
type MeterSnapshot interface {
	Count() int64
	Rate1() float64
	Rate5() float64
	Rate15() float64
	RateMean() float64
}

// Meters count events to produce exponentially-weighted moving average rates
// at one-, five-, and fifteen-minutes and a mean rate.
type Meter interface {
	Mark(int64)
	Snapshot() MeterSnapshot
	Stop()
}
```

This PR makes the concurrency model clearer. We have actual meters and snapshot of meters. The `meter` is the thing which can be accessed from the registry, and updates can be made to it.

- For all `meters`, (`Gauge`, `Timer` etc), it is assumed that they are accessed by different threads, making updates. Therefore, all `meters` update-methods (`Inc`, `Add`, `Update`, `Clear` etc) need to be concurrency-safe.
- All `meters` have a `Snapshot()` method. This method is _usually_ called from one thread, a backend-exporter. But it's fully possible to have several exporters simultaneously: therefore this method should also be concurrency-safe.

TLDR: `meter`s are accessible via registry, all their methods must be concurrency-safe.

For all `Snapshot`s, it is assumed that an individual exporter-thread has obtained a `meter` from the registry, and called the `Snapshot` method to obtain a readonly snapshot. This snapshot is _not_ guaranteed to be concurrency-safe. There's no need for a snapshot to be concurrency-safe, since exporters should not share snapshots.

Note, though: that by happenstance a lot of the snapshots _are_ concurrency-safe, being unmutable minimal representations of a value. Only the more complex ones are _not_ threadsafe, those that lazily calculate things like `Variance()`, `Mean()`.

Example of how a background exporter typically works, obtaining the snapshot and sequentially accessing the non-threadsafe methods in it:
```golang
		ms := metric.Snapshot()
                ...
		fields := map[string]interface{}{
			"count":    ms.Count(),
			"max":      ms.Max(),
			"mean":     ms.Mean(),
			"min":      ms.Min(),
			"stddev":   ms.StdDev(),
			"variance": ms.Variance(),
```

TLDR: `snapshots` are not guaranteed to be concurrency-safe (but often are).

I also changed the `Sample` type: previously, it iterated the samples fully every time `Mean()`,`Sum()`, `Min()` or `Max()` was invoked. Since we now have readonly base data, we can just iterate it once, in the constructor, and set all four values at once.

The same thing has been done for runtimehistogram.

Back when ResettingTImer was implemented, as part of https://github.com/ethereum/go-ethereum/pull/15910, Anton implemented a `Percentiles` on the new type. However, the method did not conform to the other existing types which also had a `Percentiles`.

1. The existing ones, on input, took `0.5` to mean `50%`. Anton used `50` to mean `50%`.
2. The existing ones returned `float64` outputs, thus interpolating between values. A value-set of `0, 10`, at `50%` would return `5`, whereas Anton's would return either `0` or `10`.

This PR removes the 'new' version, and uses only the 'legacy' percentiles, also for the ResettingTimer type.

The resetting timer snapshot was also defined so that it would expose the internal values. This has been removed, and getters for `Max, Min, Mean` have been added instead.

A lot of types were exported, but do not need to be. This PR unexports quite a lot of them.

metrics: refactor metrics (28035)
2024-12-13 14:00:13 +08:00
Daniel Liu
1fe46b8d3f metrics/librato: rename receiver re to rep 2024-12-13 14:00:13 +08:00
Daniel Liu
35380508fc metrics, cmd/geth: informational metrics (prometheus, influxdb, opentsb) (#24877)
This chang creates a GaugeInfo metrics type for registering informational (textual) metrics, e.g. geth version number. It also improves the testing for backend-exporters, and uses a shared subpackage in 'internal' to provide sample datasets and ordered registry.

Implements #21783

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2024-12-13 14:00:13 +08:00
Daniel Liu
d43f6c0cb0 metrics: NilResettingTimer.Time should execute the timed function (#27724) 2024-12-13 14:00:13 +08:00
Daniel Liu
51e49a869d metrics: NilTimer should still run the function to be timed (#27723) 2024-12-13 14:00:13 +08:00
Daniel Liu
e524043a3b metrics: use slices package for sorting (#27493 #27909)
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-12-13 14:00:13 +08:00
Daniel Liu
7d40ca6f35 metrics: use sync.map in registry (#27159) 2024-12-13 14:00:13 +08:00
Daniel Liu
7015a9e1cc metrics: use atomic type (#27121) 2024-12-13 14:00:13 +08:00
Daniel Liu
aa5e3e2c08 metrics: make gauge_float64 and counter_float64 lock free (#27025)
Makes the float-gauges lock-free

name                      old time/op  new time/op  delta
CounterFloat64Parallel-8  1.45µs ±10%  0.85µs ± 6%  -41.65%  (p=0.008 n=5+5)

---------

Co-authored-by: Exca-DK <dev@DESKTOP-RI45P4J.localdomain>
Co-authored-by: Martin Holst Swende <martin@swende.se>
2024-12-13 14:00:13 +08:00
Daniel Liu
54570300cc all: ensure resp.body closed (#26969) 2024-12-13 14:00:13 +08:00
Daniel Liu
6e055a601d metrics/influxdb: reuse code between v1 and v2 reporters (#26963) 2024-12-13 14:00:13 +08:00
Daniel Liu
9eae1243cd metrics: add cpu counters (#26796)
This PR adds counter metrics for the CPU system and the Geth process.
Currently the only metrics available for these items are gauges. Gauges are
fine when the consumer scrapes metrics data at the same interval as Geth
produces new values (every 3 seconds), but it is likely that most consumers
will not scrape that often. Intervals of 10, 15, or maybe even 30 seconds
are probably more common.

So the problem is, how does the consumer estimate what the CPU was doing in
between scrapes. With a counter, it's easy ... you just subtract two
successive values and divide by the time to get a nice, accurate average.
But with a gauge, you can't do that. A gauge reading is an instantaneous
picture of what was happening at that moment, but it gives you no idea
about what was going on between scrapes. Taking an average of values is
meaningless.
2024-12-13 14:00:13 +08:00
Daniel Liu
c616077fb5 metrics: improve accuracy of CPU gauges (#26793)
This PR changes metrics collection to actually measure the time interval between collections, rather
than assume 3 seconds. I did some ad hoc profiling, and on slower hardware (eg, my Raspberry Pi 4)
I routinely saw intervals between 3.3 - 3.5 seconds, with some being as high as 4.5 seconds. This
will generally cause the CPU gauge readings to be too high, and in some cases can cause impossibly
large values for the CPU load metrics (eg. greater than 400 for a 4 core CPU).

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
2024-12-13 14:00:13 +08:00
Daniel Liu
6199c84050 metrics: remove deprecated uses of math.rand (#26710) 2024-12-13 14:00:13 +08:00
Daniel Liu
76320b4b98 metrics/librato: use http package to replace http method names (#26535) 2024-12-13 14:00:13 +08:00
Daniel Liu
40f47a641b metrics/influxdb: fix time ticker leaks (#26507) 2024-12-13 14:00:13 +08:00
Daniel Liu
dddd6c57cd metrics: improve reading Go runtime metrics (#25886)
This changes how we read performance metrics from the Go runtime. Instead
of using runtime.ReadMemStats, we now rely on the API provided by package
runtime/metrics.

runtime/metrics provides more accurate information. For example, the new
interface has better reporting of memory use. In my testing, the reported
value of held memory more accurately reflects the usage reported by the OS.

The semantics of metrics system/memory/allocs and system/memory/frees have
changed to report amounts in bytes. ReadMemStats only reported the count of
allocations in number-of-objects. This is imprecise: 'tiny objects' are not
counted because the runtime allocates them in batches; and certain
improvements in allocation behavior, such as struct size optimizations,
will be less visible when the number of allocs doesn't change.

Changing allocation reports to be in bytes makes it appear in graphs that
lots more is being allocated. I don't think that's a problem because this
metric is primarily interesting for geth developers.

The metric system/memory/pauses has been changed to report statistical
values from the histogram provided by the runtime. Its name in influxdb has
changed from geth.system/memory/pauses.meter to
geth.system/memory/pauses.histogram.

We also have a new histogram metric, system/cpu/schedlatency, reporting the
Go scheduler latency.
2024-12-13 14:00:13 +08:00
Daniel Liu
e8452c94a7 metrics: fix some typos (#25551) 2024-12-13 14:00:12 +08:00