mattrobenolt/go-metrics
Extremely fast and lightweight package for recording and exporting metrics in Prometheus exposition format.
metrics
Extremely fast and lightweight package for recording and exporting metrics in Prometheus exposition format.
Heavily inspired and based on VictoriaMetrics/metrics.
import "go.withmatt.com/metrics"Features
- Very fast, very few allocations. Really.
- Optional expiring of unobserved metrics (TTL support)
- HTTP exporter
- Built-in runtime metrics collectors
- Easy Prometheus-like API
- No dependencies
Behavior Notes
Duplicate Registration: Registering the same metric name twice will panic. This is intentional to catch programming errors early during development.
TTL/Expiration: Metrics created through SetVec with a TTL will automatically expire if not accessed. See TTL example.
Quick Start
import (
"net/http"
"go.withmatt.com/metrics"
"go.withmatt.com/metrics/promhttp"
)
func main() {
// exposes Go and process runtime metrics
metrics.RegisterDefaultCollectors()
// create a new uint64 counter "foo" with the tag a=b
// This will emit:
// foo{a="b"} 1
c := metrics.NewUint64("foo", "a", "b")
c.Inc()
mux := http.NewServeMux()
mux.Handle("/metrics", promhttp.Handler())
panic(http.ListenAndServe("127.0.0.1:9091", mux))
}Metric Types
- Counters (uint64/int64/float64) - Monotonically increasing values (e.g., request count, bytes sent)
- Gauges (uint64/int64/float64) - Values that can increase or decrease (e.g., memory usage, active connections)
- Histograms
- Prometheus-like (
lelabel style) - VictoriaMetrics-like (
vmrangelabel style)
- Prometheus-like (
Note
Summary type has not been implemented.
Counter vs Gauge
While this library allows both counter and gauge types to increment/decrement, you should follow Prometheus semantics:
- Use Counters for values that only increase (resets to 0 on restart). Prometheus queries use
rate()andincrease()functions. - Use Gauges for current measurements that can go up or down. Despite the naming,
Uint64/Int64/Float64types can be used as gauges.
Performance
mattware= this libraryvm=github.com/VictoriaMetrics/metricsprom=github.com/prometheus/client_golang/prometheus
Updating metrics
Note
Updating metrics happen very typically within extremely hot paths, and
nanoseconds matter.
Increment a counter through UintVec.WithLabelValue API
| package | sec/op | vs base | allocs/op |
|---|---|---|---|
| mattware | 27.54n | +0% | 0 |
| vm * | 95.75n | +247.76% | 1 |
| prom | 47.36n | +72.02 | 0 |
- VM/metrics doesn't support this API natively, and their pattern for this is highly discouraged.
Update Prometheus-like histogram (le label style)
| package | sec/op | vs base | allocs/op |
|---|---|---|---|
| mattware | 8.127n | +0% | 0 |
| vm * | - | - | - |
| prom | 10.035n | +23.48% | 0 |
- VM/metrics does not support this.
Update VictoriaMetrics-like histogram (vmrange label style)
| package | sec/op | vs base | allocs/op |
|---|---|---|---|
| mattware | 15.91n | +0% | 0 |
| vm | 16.98n | +6.72% | 0 |
| prom * | - | - | - |
- Prom client does not support this.
Exporting metrics
Note
Exporting happens by Prometheus compatible scrapers typically.
Exporting 10,000 counters
| package | sec/op | vs base | allocs/op | B/s |
|---|---|---|---|---|
| mattware | 704.2µ | +0% | 1 | 689.13Mi |
| vm | 1033.3µ | +46.72% | 10018 | 478.91Mi |
| prom | 10068.0µ | +1329.60% | 41422 | 48.23Mi |
Exporting 100 Prometheus-like histograms, with 100,000 observations each
| package | sec/op | vs base | allocs/op | B/s |
|---|---|---|---|---|
| mattware | 108.2µ | +0% | 1 | 811.6Mi |
| prom | 437.4µ | +304.36% | 5434 | 200.6Mi |
Exporting 100 VictoriaMetrics-like histograms, with 100,000 observations each
| package | sec/op | vs base | allocs/op | B/s |
|---|---|---|---|---|
| mattware | 462.8µ | +0% | 1 | 1069.8Mi |
| vm | 2373.2µ | +412.83% | 41422 | 208.6Mi |