metrics

A lightweight, protocol-agnostic metrics facade for Rust, decoupling instrumentation from whatever exporter you plug in.

Library
Cargo
v0.24.6
1,479stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
53/100Fair
Development Activity40
Maintenance4
Community68
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
78/100Good
Architecture85
Code Quality78
Innovation72
Learning Curve75

metrics is a facade crate for the Rust ecosystem, modeled directly on the log crate: it gives library and application authors a single, stable set of macros — counter!, gauge!, and histogram! — for emitting counters, gauges, and histograms without tying the calling code to any particular backend. A global Recorder trait is installed once, at the application’s entry point, and every instrumented crate in the dependency tree starts reporting through it automatically, with zero extra configuration on the library author’s side.

The project anchors a small ecosystem of companion crates published from the same repository — metrics-util for helper types, metrics-exporter-prometheus and metrics-exporter-tcp for shipping data out, and metrics-tracing-context for bridging tracing span fields into metric labels — plus a wide set of community-maintained exporters for StatsD, New Relic, Sentry, and more. The core crate itself stays intentionally minimal: it defines the metric primitives, the key/label model, and the recorder trait, and leaves everything about collection and export to whichever exporter a consumer chooses to install.

What You Get

  • Three macro-driven metric primitives — counter!, gauge!, and histogram! — plus matching describe_*! macros for attaching units and descriptions
  • A global Recorder trait with install-once semantics, so every crate in the dependency tree reports through the same backend automatically
  • A thread-local recorder override for scoped instrumentation (useful in tests or multi-tenant contexts) alongside the global one
  • An allocation-optimized SharedString/Cow type for metric keys and labels that supports zero-cost static construction as well as owned and Arc-shared values
  • A NoopRecorder default so instrumented code compiles and runs safely even before any exporter is installed
  • A companion crate ecosystem (metrics-util, metrics-exporter-prometheus, metrics-exporter-tcp, metrics-tracing-context) covering the rest of the export pipeline

Common Use Cases

  • Instrumenting a Rust web service or backend to expose request counts, latencies, and error rates to Prometheus via metrics-exporter-prometheus
  • Adding library-level metrics to a crate you publish, so downstream applications get insight into it for free once they install any recorder
  • Bridging tracing spans into metric labels with metrics-tracing-context to correlate structured logs with counters and histograms
  • Recording histogram data for operation latencies or payload sizes to understand distribution shape, not just averages
  • Swapping exporters (Prometheus, StatsD, TCP, Sentry) without touching any instrumentation call sites, since all of them implement the same Recorder trait

Under The Hood

Architecture The crate is organized around a small set of composable primitives rather than a monolithic client: key.rs and label.rs define the Key/Label model used to identify a metric plus its dimensions, handles.rs defines the Counter/Gauge/Histogram handle types and the CounterFn/GaugeFn/HistogramFn traits a backend implements, and recorder/mod.rs defines the central Recorder trait plus a RecorderOnceCell (in recorder/cell.rs) that enforces install-once semantics for a 'static global recorder, backed by a NoopRecorder (recorder/noop.rs) fallback and a thread-local override for scoped use. The public macros in macros.rs are thin, expanding at compile time into static Key/Metadata construction plus a lookup against the currently installed recorder — the core abstraction that would break the most if changed is the Recorder trait itself, since every exporter crate in the ecosystem implements it directly.

Tech Stack This is a no_std-adjacent, dependency-light std crate targeting Rust edition 2018 with an MSRV of 1.71.1, enforced by CI. Its only runtime dependency is rapidhash for key hashing, with a portable-atomic fallback pulled in on 32-bit targets that lack native 64-bit atomics; dev-dependencies (criterion, trybuild, log, rand) are used purely for benchmarking and macro-expansion testing. It ships as one crate within a Cargo workspace alongside its own exporters (metrics-exporter-prometheus, metrics-exporter-tcp, metrics-exporter-dogstatsd), metrics-util, and metrics-tracing-context, with docs.rs as the documentation target and crates.io as the sole distribution channel.

Code Quality Unit tests live alongside the modules they cover (key.rs, cow.rs, label.rs, metadata.rs, common.rs) using Rust’s built-in #[test] harness, with trybuild additionally used to assert compile-time failure messages for macro misuse. Error handling favors explicit, typed results (SetRecorderError) over panics for the one fallible global-install operation, and the crate is #![deny(missing_docs)]-style thorough in its public API documentation. CI (ci.yml) enforces the MSRV and runs the workspace’s clippy lints per clippy.toml.

What Makes It Unique The crate’s distinguishing choice is committing fully to a facade pattern for metrics the way log did for logging: it ships zero opinions about aggregation, storage, or transport, and instead standardizes only the emission-time API and the trait boundary a recorder must satisfy. This lets an entire ecosystem of independently-versioned exporter crates interoperate with any instrumented library without coordination, and the copy-on-write SharedString design specifically optimizes for the hot path of macro-invoked, mostly-static metric names and labels.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search