go-metrics
A Go port of Coda Hale's Metrics library for counters, gauges, histograms, meters, and timers.
Repository Health
Technical Analysis
go-metrics is a Go port of Coda Hale’s Java Metrics library, providing a small set of primitives — counters, gauges, histograms, meters, and timers — for instrumenting application code with runtime metrics. A central Registry tracks named metrics and exposes them for periodic reporting, while a global UseNilMetrics switch lets you swap in no-op stubs to measure the observer effect of instrumentation itself.
Beyond the core primitives, the library ships optional reporters for Graphite, syslog, StatHat, and (historically) Librato, plus a /debug/metrics HTTP handler modeled on Go’s expvar package. The project has been archived since April 2025, with its authors pointing users toward the OpenTelemetry Go SDK or the Prometheus client library for new instrumentation work — but go-metrics remains widely vendored inside older Go services and libraries that adopted it during the pre-Prometheus era.
What You Get
- Five core metric types — Counter, Gauge, GaugeFloat64, Histogram, Meter, and Timer — each defined as an interface with a standard implementation.
- A thread-safe StandardRegistry for registering, looking up, and iterating over named metrics from anywhere in your code.
- Built-in reporters for Graphite, syslog, and StatHat, plus an expvar-style HTTP handler for exposing metrics at /debug/metrics.
- An exponentially-decaying sample implementation (based on Cormode et al’s forward-decay paper) for statistically representative histogram sampling on high-throughput counters.
Common Use Cases
- Tracking request counts and latencies in a Go HTTP service via Counter and Timer metrics registered against a shared Registry.
- Exporting periodic snapshots of application metrics to Graphite or StatHat for dashboarding in older, pre-Prometheus infrastructure.
- Instrumenting background workers with Meter metrics to track throughput rates (marks-per-second) alongside EWMA-smoothed averages.
- Maintaining legacy Go services that were built against go-metrics before the ecosystem standardized on OpenTelemetry or Prometheus.
Under The Hood
Architecture
The library is organized around a small set of metric interfaces (Counter, Gauge, GaugeFloat64, Histogram, Meter, Timer, Sample, Healthcheck) each with a Standard* implementation and, in most cases, a no-op Nil* variant and a read-only *Snapshot type — a consistent three-way split that lets callers swap real, disabled, or frozen views of the same metric without changing call sites. A Registry interface (implemented by StandardRegistry, a sync.RWMutex-protected map in registry.go) is the sole coordination point: metrics are created via constructors like NewCounter() and attached to a registry with Register/GetOrRegister, and reporters (graphite.go, syslog.go, log.go, exp/exp.go) consume the registry through its Each method, so adding a new export backend never touches the metric types themselves. The global UseNilMetrics switch in metrics.go is a deliberate escape hatch — every constructor checks it first — letting the whole library become inert for profiling the observer effect.
Tech Stack
Written in pre-modules Go (no go.mod; installed via go get) using only the standard library — sync/sync/atomic for concurrency, math/sort/math/rand for the sampling algorithms, reflect for registry duplicate-type checks, and net/log/syslog for the bundled reporters. Optional integrations (Graphite, syslog, StatHat, the retired Librato client, and an expvar-compatible HTTP handler) are split into their own files or subpackages so they pull in extra stdlib packages (like net/http or encoding/json) only when used. CI, per .travis.yml, ran on Travis CI, which has since been retired along with the repository itself.
Code Quality
Test coverage is extensive relative to the codebase’s size — 16 _test.go files against roughly 23 non-test source files, using only the standard testing package with no external assertion library. Concurrency-sensitive types (StandardCounter, StandardGauge) rely on sync/atomic rather than ad-hoc locking, and the registry uses sync.RWMutex correctly for read-heavy access. Error handling is minimal but explicit where it matters (DuplicateMetric as a typed error from Register), naming is consistent and idiomatic Go, and every exported identifier carries a doc comment. The absence of a go.mod file and reliance on Travis CI reflect the project’s pre-2018 origins rather than a quality gap.
What Makes It Unique
go-metrics’ most distinctive piece is its ExpDecaySample, an implementation of forward-decaying priority-reservoir sampling drawn directly from an academic streaming-systems paper, giving histograms a statistically principled way to weight recent values over old ones without unbounded memory growth. As a direct, faithful port of Coda Hale’s original Java Metrics library, it also standardized vocabulary (meters, timers, EWMA-based rate smoothing) that later shaped how Go services thought about instrumentation — even though the project’s own README now points adopters toward OpenTelemetry and Prometheus as its successors.
Used by 3 apps in this directory
CubeSandbox
Developer Tools · Security · AI Agents
Instant, concurrent, hardware-isolated MicroVM sandboxes for AI agents — E2B-API compatible, sub-60ms cold starts, and a built-in zero-trust egress proxy, all self-hostable at scale.
MinIO
File Storage
High-performance, S3-compatible object storage built for AI/ML and analytics workloads — run it anywhere from a laptop to a petabyte-scale cluster.
OpenMeter
Invoicing Finance · Developer Tools
Open-source metering and billing engine for AI, agentic, and DevTool monetization — ingest usage events in real time and turn them into accurate invoices automatically.