metrics-lib 1.0.0 is the API freeze. This document defines exactly what
the crate commits to and what it does not, so consumers can decide
confidently how to depend on it.
The crate follows Semantic Versioning with the strict cargo interpretation:
1.x.yreleases never break the documented public surface. Adding new variants, methods, types, modules, or feature flags is always allowed and shipped as a minor (1.X.0) bump. Removing, renaming, or changing the signature of anything listed in § Frozen surface requires a major (2.0.0) bump.- MSRV (Minimum Supported Rust Version) is
1.70at 1.0.0. MSRV bumps within1.xare treated as minor changes (advertised in the CHANGELOG) but not as breaking — consumers on older toolchains should pinmetrics-lib = "=1.M.P"if they need a fixed MSRV. - The
[features]set is part of the public API. Renaming or removing a feature flag is a2.0change. Adding new feature flags is additive (minor).
Every item below is committed at 1.0.0. The list is exhaustive — if
something is not listed here and is reachable from metrics_lib::*, it
is not part of the stability promise.
metrics_lib::METRICS: OnceLock<MetricsCore>metrics_lib::init() -> &'static MetricsCoremetrics_lib::metrics() -> &'static MetricsCoremetrics_lib::Result<T>(alias forstd::result::Result<T, MetricsError>)metrics_lib::MetricsError(enum + every variant currently exposed)metrics_lib::MetricsCore(struct + everypub fnshown bycargo doc --no-deps)
Counter,CounterStats(gated oncount)Gauge,GaugeStats,gauge_specialized::PercentageGauge,gauge_specialized::CpuGauge,gauge_specialized::MemoryGauge(gated ongauge)Timer,RunningTimer<'a>,TimerStats, thetime_block!andtime_fn!macros,metrics_lib::utils::*timing helpers (gated ontimer)RateMeter,RateStats,rate_meter_specialized::ApiRateLimiter,rate_meter_specialized::ThroughputMeter(gated onmeter)Histogram,HistogramSnapshot,HistogramBucket,DEFAULT_SECONDS_BUCKETS(gated onhistogram)
Label(type alias),LabelSetMetricKind,MetricMetadata,Unit(includingUnit::Custom)
Registry,ScopedRegistry<'a>,DEFAULT_CARDINALITY_CAP
SystemHealth,SystemSnapshot,ProcessStats,HealthStatus,HealthConfig,Step
TokenBucket
AsyncTimerExt,AsyncTimerGuard<'a>,AsyncMetricBatch,AsyncMetricsBatcher
AdaptiveSampler,SamplingStrategy,MetricCircuitBreaker,BackpressureController
metrics_lib::tracing_ext::time_in_spanmetrics_lib::tracing_ext::time_global
metrics_lib::exporters::prometheus::{render, render_into}(always available)metrics_lib::exporters::openmetrics::{render, render_into}(always available)metrics_lib::exporters::json::{snapshot, render, render_pretty}+ theRegistrySnapshot/CounterSeries/GaugeSeries/TimerSeries/RateSeries/HistogramSeries/CardinalitySnapshotvalue types (gated onserde)metrics_lib::exporters::statsd::StatsdSink(gated onstatsd)metrics_lib::exporters::otlp::{render, render_pretty, build, ExportMetricsServiceRequest, ResourceMetrics, ScopeMetrics, Resource, InstrumentationScope, Metric, MetricData, NumberData, NumberDataPoint, NumberValue, HistogramData, HistogramDataPoint, KeyValue, AnyValue}(gated onotlp)
metrics_lib::prelude::*— seedocs/API.md#preludefor the exact list. The prelude itself is part of the frozen surface; its contents are versioned so that re-exporting new items from it counts as a minor bump.
The feature set is frozen at 1.0.0:
count, gauge, timer, meter, sample, histogram, bench-tests,
async, serde, statsd, otlp, tracing, exporters-all, all,
full, default, minimal.
- Anything inside a
#[doc(hidden)]module, item, or method. - The
#[cfg(test)]and#[cfg(all(test, feature = "bench-tests", …))]modules. - Internal performance characteristics. The Criterion benchmarks track
per-version trends, but
Counter::incdoes not commit to a specific ns/op number across hardware. Don't depend on relative ordering between, say,metrics().counter(name)andmetrics().counter_with(name, &labels)beyond "the cached-handle path is at least as fast." - The exact text of error display messages (
MetricsError::Display). The variants and their discriminants are stable; the human-readable format is not. - The dependency tree below the top-level dependency declarations in
Cargo.toml. Patch / minor bumps of transitive dependencies happen as a normal part of1.xdevelopment. - The
MSRVfor newly added feature flags. A new feature introduced in1.M.0may require a newer toolchain than the rest of the crate; this is announced in the CHANGELOG.
These are the corner-of-the-spec behaviours that consumers may rely on:
Counteris monotonic acrossinc/add/fetch_add/add_and_get.resetandsetexist and are the only ways to decrease the value.try_inc/try_add/try_fetch_add/try_inc_and_getreturnErr(MetricsError::Overflow)iff the arithmetic would overflowu64::MAX; the counter is unchanged on overflow.Gaugetry_*methods reject non-finite inputs (f64::NAN,f64::INFINITY,f64::NEG_INFINITY) withErr(MetricsError::InvalidValue { reason })and do not mutate the gauge. The non-trymethods silently ignore non-finite inputs.Timer::record_batchsaturates internally on overflow (no panic);try_record_batchreturnsErr(MetricsError::Overflow).RateMeter::tick_if_under_limithas documented TOCTOU semantics — it may briefly overshoot the limit by up tonum_threads − 1events per window. UseTokenBucket::try_acquirewhen strict admission is required.TokenBucket::try_acquirenever exceeds the configured capacity, proven by an in-tree property test (tests/proptests.rs::token_bucket_no_overshoot_no_refill).Registry::scoped(prefix)is name-rewriting only — the sameArc<Counter>(etc.) backsscoped("p.").counter("x")andcounter("p.x").SystemHealthreaders are atomic-load-only — no mutex, no syscall, no async-runtime stall, regardless of platform. A background sampler thread (or explicitupdate()calls inmanual()mode) is the only writer.- Cardinality cap defaults to
DEFAULT_CARDINALITY_CAP = 10_000unique(name, labels)tuples across all labeled metric types.try_*_withmethods returnErr(MetricsError::CardinalityExceeded)when full; non-try*_withmethods route to a process-global per-type overflow sink (never exported, never panicking).
The roadmap that follows 1.0 is intentionally undocumented at the
SemVer level. Plausible breaking changes that would justify a 2.0:
- Migrating
criterionto0.5+and removing theRUSTSEC-2024-0375(attyunmaintained) ignore fromdeny.toml. - Switching the registry's labeled-lookup composite key to a more efficient encoding (e.g. interned strings) — would affect public storage types if they're exposed.
- Generalising the histogram percentile path (HDR-histogram, t-digest) in a way that changes return types.
Any of these will be announced via a 2.0-pre cycle on main first.