metrics-0.24.6/.cargo_vcs_info.json0000644000000001451046102023000126150ustar { "git": { "sha1": "23cc597488f119a2d54b0ffd4a0d7d1a50651b76" }, "path_in_vcs": "metrics" }metrics-0.24.6/.gitignore000064400000000000000000000000361046102023000133520ustar 00000000000000/target **/*.rs.bk Cargo.lock metrics-0.24.6/CHANGELOG.md000064400000000000000000000325471046102023000132070ustar 00000000000000# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] - ReleaseDate ## [0.24.6] - 2026-05-13 ### Added - Support for specifying `description` and `unit` as optional parameters in the `counter!`, `gauge!`, and `histogram!` registration macros, allowing description and creation in a single call. ([#691](https://github.com/metrics-rs/metrics/pull/691)) ### Fixed - Fixed a regression in the deprecated `metrics::KeyHasher` that caused `metrics_util::registry::Registry` (versions 0.19.0 through 0.20.1) to insert a fresh entry on every `get_or_create_counter`/`get_or_create_gauge`/`get_or_create_histogram` call for the same `Key` after the internal HashMap resized. `KeyHasher` was treating the pre-computed hash that `Key::hash` writes via `write_u64` as bytes to be hashed again, so `BuildHasherDefault::hash_one(&key)` (used by hashbrown during resize) disagreed with `Hashable::hashable(&key)` (used by the Registry for lookups). `KeyHasher` now returns the pre-hashed value passed via `write_u64` verbatim, falling back to byte hashing only when arbitrary bytes are written (preserving behavior for `metrics_util::DefaultHashable`). ([#694](https://github.com/metrics-rs/metrics/issues/694)) ## [0.24.5] - 2026-04-29 ### Fixed - Fixed a regression introduced in 0.24.4 where `hash_label` hashed the label key twice instead of hashing the key and value with independent seeds, which could cause label sets with identical names but different values to collide. ([#690](https://github.com/metrics-rs/metrics/pull/690)) ## [0.24.4] - 2026-04-28 ### Added - New `Key::to_retained()` and `KeyName::to_retained()` methods that return a version of the key/name cheap to clone for long-lived retention (allocating only when necessary). ([#688](https://github.com/metrics-rs/metrics/pull/688)) - `Counter::noop()`, `Gauge::noop()`, and `Histogram::noop()` are now `const fn`. ([#654](https://github.com/metrics-rs/metrics/pull/654)) - `KeyName::as_str` and `Key::get_hash` are now `const fn`. `Key` now derives `Clone`. ([#669](https://github.com/metrics-rs/metrics/pull/669)) ### Changed - Internal key hasher swapped from `ahash` to `rapidhash` for faster, allocation-free hashing. ([#651](https://github.com/metrics-rs/metrics/pull/651), [#669](https://github.com/metrics-rs/metrics/pull/669)) - `Key` hash is now computed eagerly at construction time, removing internal atomics from the struct. ([#669](https://github.com/metrics-rs/metrics/pull/669)) ### Deprecated - `metrics::KeyHasher` is deprecated; use `metrics_util::common::KeyHasher` instead. ([#669](https://github.com/metrics-rs/metrics/pull/669)) ## [0.24.3] - 2025-11-28 ### Added - Two new methods (`KeyName::into_inner` and `Key::name_shared`), as well as a `From` implementation to convert `KeyName` to `std::borrow::Cow<'static, str>`, to allow for more ergonomically working with `KeyName` values. ([#640](https://github.com/metrics-rs/metrics/pull/640)) ### Changed - Updated `From` implementation for `metrics::Cow<'a, T>` to allow properly converting `metrics::Cow<'a, str>` to `std::borrow::Cow<'a, str>`. ([#635](https://github.com/metrics-rs/metrics/pull/635)) ## [0.24.2] - 2025-04-20 ### Changed - Remove object lifetime cast in `LocalRecorderGuard<'a>`. ([#564](https://github.com/metrics-rs/metrics/pull/564)) - Update `Key` comparison logic to be independent of the order of any labels. ([#565](https://github.com/metrics-rs/metrics/pull/565)) ## [0.24.1] - 2024-11-26 ### Added - Added a section to the crate-level documentation about `Metadata` and how it's used. - Derived `Copy`, `PartialOrd` and `Ord` for `Metadata` to allow for cheap copies and the ability to compare levels for filtering purposes. - Added `TryFrom<&str>` for `Level` to allow parsing levels from strings. - Updated the documentation for `Metadata` to better explain how it's used. ## [0.24.0] - 2024-10-12 ### Added - Added `Debug` derive to numerous types. ([#504](https://github.com/metrics-rs/metrics/pull/504)) - Blanket implementations of `Recorder` over smart pointer representations (i.e. `Arc where T: Recorder`). ([#512](https://github.com/metrics-rs/metrics/pull/512)) - Added a new method, `record_many`, to `Histogram` and `HistogramFn`, for recording a single value multiple times. This method is backwards compatible as `HistogramFn` provides a default implementation. ([#531](https://github.com/metrics-rs/metrics/pull/531)) ### Changed - Changed `Unit::Gigibytes` to `Gibibytes` to match the proper SI prefix. ([#508](https://github.com/metrics-rs/metrics/pull/508)) - Fixed a number of Clippy lints. ([#510](https://github.com/metrics-rs/metrics/pull/510)) - Updated the documentation for `with_local_recorder` to better explain limitations. - `set_global_recorder` now requires that the recorder is `Sync`. ([#511](https://github.com/metrics-rs/metrics/pull/511)) - Bump MSRV to 1.71.1. ([#530](https://github.com/metrics-rs/metrics/pull/530)) - `with_recorder` is no longer hidden in the docs. ([#532](https://github.com/metrics-rs/metrics/pull/532)) ## [0.23.0] - 2024-05-27 ### Added - Implement `IntoLabels` for `BTreeMap`. ([#470](https://github.com/metrics-rs/metrics/pull/470)) - Implement `From>` for `std::borrow::Cow<'a, T>`. ([#478](https://github.com/metrics-rs/metrics/pull/478)) ### Changed - Bump MSRV to 1.70.0. - `Counter`, `Gauge`, and `Histogram` are now marked with `#[must_use]`. ([#475](https://github.com/metrics-rs/metrics/pull/475)) - Updated crate-level documentation around how histograms work. ([#477](https://github.com/metrics-rs/metrics/pull/477)) - Allow for trailing comma in arguments for all describe macros. ([#483](https://github.com/metrics-rs/metrics/pull/483)) ## [0.22.3] - 2024-03-16 ### Added - Additional implementations of `IntoF64` for standard numerical types (`i8`, `u8`, `i16`, `u16`, `i32`, `u32`, and `f32`). ## [0.22.2] - 2024-03-16 ### Fixed - Bump `ahash` back to `0.8.8` to remove range constraint after an upstream fix was provided to remove the unnecessary MSRV bump. ## [0.22.1] - 2024-02-11 ### Fixed - Lock down the version of `ahash` to avoid unnecessary MSRV bumping. ## [0.22.0] - 2023-12-24 ### Added - Support for using `Arc` with `Cow<'a, T>`. ([#402](https://github.com/metrics-rs/metrics/pull/402)) This will primarily allow using `Arc` for metric names and labels, where previously only `&'static str` or `String` were allowed. There's still work to be done to also support labels in this regard. - Support for local recorders. ([#414](https://github.com/metrics-rs/metrics/pull/414)) This is a large feature, and is documented in [RELEASES.md](RELEASES.md). ### Changed - Make `Unit` methods return `&'static str` (instead of `&str`) where possible. ([#392](https://github.com/metrics-rs/metrics/pull/393)) - Bump MSRV to 1.65.0. - `SetRecorderError` now returns the recorder given to `set_global_recorder` if another global recorder was already installed instead of leaking it. ([#414](https://github.com/metrics-rs/metrics/pull/414)) ## [0.21.1] - 2023-07-02 ### Added - Added a `From` implementation for `KeyName` from `Cow<'static, str>`. ([#378](https://github.com/metrics-rs/metrics/pull/378)) ### Removed - Removed `metrics::set_recorder_racy` as it was intended to be used in `no_std` use cases, but `metrics` is not currently compatible in `no_std` environments, so keeping `set_recorder_racy` around was just API baggage. ## [0.21.0] - 2023-04-16 ### Added - A new module, `atomics`, exposes the atomic integer type that `CounterFn` and `GaugeFn` are implemented for. This will publicly re-export the type for usage by downstream crates. (Credit to [@repi](https://github.com/repi) for the original PR (#347) that did this.) ### Changed - Bump MSRV to 1.61.0. - `portable-atomic` is only used on 32-bit architectures. ### Removed - Removed the `std-atomics` feature flag. ## [0.20.1] - 2022-07-22 ### Changed - Bumped the dependency on `metrics-macros` to correctly use the updated versions that are necessary for handling the recent `&'static str` -> `SharedString` change to `Recorder::describe_*`. We'll also yank 0.20.0 once this is released to avoid the patch version triggering a breaking change jump in transitive dependencies, and so people can't pick up a version of `metrics` that doesn't actually work as it should. ## [0.20.0] - 2022-07-20 ### Changed - Changed `Recorder::describe_*` to take `SharedString` instead of `&'static str` for descriptions. (#312) - Implemented `CounterFn` and `GaugeFn` for `portable_atomic::AtomicU64` (#313) - Moved implementations of `CounterFn` and `GaugeFn` for `std::sync::atomic::AtomicU64` behind a default feature flag. ## [0.19.0] - 2022-05-30 ### Fixed - Small typo in the documentation. ([#286](https://github.com/metrics-rs/metrics/pull/286)) ### Changed - Refactored the global recorder instance, namely around how it gets set and documenting the safety guarantees of methods related to setting and unsetting it. ([#302](https://github.com/metrics-rs/metrics/pull/302)) - Fixed an issue with pointer provenance in `metrics::Cow`. ([#303](https://github.com/metrics-rs/metrics/pull/303)) ## [0.18.1] - 2022-03-10 ### Added - Slices of string key/value tuples can now be passed as the labels expression in macros. ([#277](https://github.com/metrics-rs/metrics/pull/277)) ## [0.18.0] - 2022-01-14 ### Added - A new macro, `absolute_counter!`, for setting the value of a counter to an absolute value. - A new wrapper type, `KeyName`, which encapsulates creating the name portion of a `Key`. Existing methods for building a `Key`, as well as implicit conversion trait implementations, allow this to be a no-op. - Label keys in macros can now be general expressions i.e. constants or variables. Due to limitations in how procedural macros work, and the facilities available in stable Rust for const traits, even `&'static str` constants will cause allocations when used for emitting a metric. ### Changed - Switched to metric handles through the `Recorder` API. ([#240](https://github.com/metrics-rs/metrics/pull/240)). Due to the size of this change, the details are further documented and discussed in [RELEASES.md](RELEASES.md). - `Unit` is now `Copy`. - When describing a metric via the `describe_*` macros, the description is no longer optional. ### Removed - Removed the `std` feature flag, as `metrics` depends too heavily on `std`-based types and as such was not meaningfully usaable when the `std` feature flag was disabled. This will be revisited in the future. ## [0.17.1] - 2021-12-16 ### Changed - Removed unnecessary `proc-macro-hack` dependency. ## [0.17.0] - 2021-07-13 ### Changed - Switched from `t1ha` to `ahash` for the key hasher. ## [0.16.0] - 2021-05-18 ### Removed - `NameParts` has been removed to simplify metric names, again relying on a single string which is still backed by copy-on-write storage. ## [0.15.1] - 2021-05-03 ### Changed - Nothing. Fixed an issue with using the wrong dependency version during a mass release of workspace crates. ## [0.15.0] - 2021-05-03 ### Changed - Switched from `Key` to `&Key` in `Recorder`. - Refactored `KeyData` into `Key`. ### Added - Metric keys are now pre-hashed/memoized where possible, which provides a massive speedup to hashing operations over time. ## [0.14.2] - 2021-02-13 ### Added - Implemented `Ord`/`PartialOrd` for various key-related types. ## [0.14.1] - 2021-02-02 ### Added - Minor documentation test updates for better coverage of owned strings used as metric names. ## [0.14.0] - 2021-02-02 ### Changed - Added support for owned strings as metric names. [#170](https://github.com/metrics-rs/metrics/pull/170) ## [0.13.1] - 2021-01-23 ### Added - Added conversion from `std::borrow::Cow<'static, str>` for `SharedString`. ## [0.13.0] - 2021-01-22 ### Added - New macros for registration: `register_counter!`, `register_gauge!`, `register_histogram!`. - New macros for emission: `histogram!`, `increment_counter!`, `increment_gauge!`, `decrement_gauge!`. - Added unit support to describe the unit of a given metric. ### Removed - Dropped the `timing!` and `value!` macros in favor of `histogram!`. ### Changed - All macros are now procedural macros instead of declarative macros. - Gauges are now `f64` instead of `i64`. - Histograms are now `f64` instead of `u64`. - `Key` now split into `Key` and `KeyData` to better support constant expression metric keys via macro callsites. - Significant overhaul of generated callsites via macros. ## [0.12.1] - 2019-11-21 ### Changed - Cost for macros dropped to almost zero when no recorder is installed. ([#55](https://github.com/metrics-rs/metrics/pull/55)) ## [0.12.0] - 2019-10-18 ### Changed - Improved documentation. (#44, #45, #46) - Renamed `Recorder::record_counter` to `increment_counter` and `Recorder::record_gauge` to `update_gauge`. ([#47](https://github.com/metrics-rs/metrics/pull/47)) ## [0.11.1] - 2019-08-09 ### Changed - Fixed a bug with macros calling inner macros without a fully qualified name. ## [0.11.0] - 2019-07-29 ### Added - Life begins at 0.11.0 for this crate, after being renamed from `metrics-facade` to `metrics` to reflect the duality of `metrics` to the `log` crate. (#27) metrics-0.24.6/Cargo.lock0000644000000415271046102023000106010ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 [[package]] name = "aho-corasick" version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] [[package]] name = "anes" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstyle" version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "autocfg" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "bitflags" version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" [[package]] name = "cast" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "ciborium" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" dependencies = [ "ciborium-io", "ciborium-ll", "serde", ] [[package]] name = "ciborium-io" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" [[package]] name = "ciborium-ll" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" dependencies = [ "ciborium-io", "half", ] [[package]] name = "clap" version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4512b90fa68d3a9932cea5184017c5d200f5921df706d45e853537dea51508f" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0025e98baa12e766c67ba13ff4695a887a1eba19569aad00a472546795bd6730" dependencies = [ "anstyle", "clap_lex", ] [[package]] name = "clap_lex" version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "criterion" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1c047a62b0cc3e145fa84415a3191f628e980b194c2755aa12300a4e6cbd928" dependencies = [ "anes", "cast", "ciborium", "clap", "criterion-plot", "itertools", "num-traits", "oorandom", "regex", "serde", "serde_json", "tinytemplate", "walkdir", ] [[package]] name = "criterion-plot" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b1bcc0dc7dfae599d84ad0b1a55f80cde8af3725da8313b528da95ef783e338" dependencies = [ "cast", "itertools", ] [[package]] name = "crunchy" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "either" version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "equivalent" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "getrandom" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" dependencies = [ "cfg-if", "libc", "r-efi", "wasi", ] [[package]] name = "glob" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "half" version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" dependencies = [ "cfg-if", "crunchy", ] [[package]] name = "hashbrown" version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "indexmap" version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" dependencies = [ "equivalent", "hashbrown", ] [[package]] name = "itertools" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" dependencies = [ "either", ] [[package]] name = "itoa" version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "libc" version = "0.2.171" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" [[package]] name = "log" version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "memchr" version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "metrics" version = "0.24.6" dependencies = [ "criterion", "log", "portable-atomic", "rand", "rapidhash", "trybuild", ] [[package]] name = "num-traits" version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "oorandom" version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" [[package]] name = "portable-atomic" version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" [[package]] name = "ppv-lite86" version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ "zerocopy", ] [[package]] name = "proc-macro2" version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" dependencies = [ "unicode-ident", ] [[package]] name = "quote" version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] [[package]] name = "r-efi" version = "5.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" [[package]] name = "rand" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ "rand_chacha", "rand_core", ] [[package]] name = "rand_chacha" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", "rand_core", ] [[package]] name = "rand_core" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ "getrandom", ] [[package]] name = "rapidhash" version = "4.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e48930979c155e2f33aa36ab3119b5ee81332beb6482199a8ecd6029b80b59" dependencies = [ "rustversion", ] [[package]] name = "regex" version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", "regex-automata", "regex-syntax", ] [[package]] name = "regex-automata" version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", "regex-syntax", ] [[package]] name = "regex-syntax" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rustversion" version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" [[package]] name = "ryu" version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "same-file" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" dependencies = [ "winapi-util", ] [[package]] name = "serde" version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "serde_json" version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "itoa", "memchr", "ryu", "serde", ] [[package]] name = "serde_spanned" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83" dependencies = [ "serde", ] [[package]] name = "syn" version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "target-triple" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ac9aa371f599d22256307c24a9d748c041e548cbf599f35d890f9d365361790" [[package]] name = "termcolor" version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] [[package]] name = "tinytemplate" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" dependencies = [ "serde", "serde_json", ] [[package]] name = "toml" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75129e1dc5000bfbaa9fee9d1b21f974f9fbad9daec557a521ee6e080825f6e8" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", "toml_parser", "toml_writer", "winnow", ] [[package]] name = "toml_datetime" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3" dependencies = [ "serde", ] [[package]] name = "toml_parser" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" dependencies = [ "winnow", ] [[package]] name = "toml_writer" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2" [[package]] name = "trybuild" version = "1.0.112" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d66678374d835fe847e0dc8348fde2ceb5be4a7ec204437d8367f0d8df266a5" dependencies = [ "glob", "serde", "serde_derive", "serde_json", "target-triple", "termcolor", "toml", ] [[package]] name = "unicode-ident" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "walkdir" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", ] [[package]] name = "wasi" version = "0.14.2+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" dependencies = [ "wit-bindgen-rt", ] [[package]] name = "winapi-util" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ "windows-sys", ] [[package]] name = "windows-sys" version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", "windows_i686_gnullvm", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" [[package]] name = "wit-bindgen-rt" version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ "bitflags", ] [[package]] name = "zerocopy" version = "0.8.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" version = "0.8.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" dependencies = [ "proc-macro2", "quote", "syn", ] metrics-0.24.6/Cargo.toml0000644000000034571046102023000106240ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2018" rust-version = "1.71.1" name = "metrics" version = "0.24.6" authors = ["Toby Lawrence "] build = false autolib = false autobins = false autoexamples = false autotests = false autobenches = false description = "A lightweight metrics facade." homepage = "https://github.com/metrics-rs/metrics" documentation = "https://docs.rs/metrics" readme = "README.md" keywords = [ "metrics", "facade", ] categories = ["development-tools::debugging"] license = "MIT" repository = "https://github.com/metrics-rs/metrics" resolver = "2" [lib] name = "metrics" path = "src/lib.rs" bench = false [[example]] name = "basic" path = "examples/basic.rs" [[example]] name = "sizes" path = "examples/sizes.rs" [[test]] name = "macros" path = "tests/macros.rs" [[bench]] name = "macros" path = "benches/macros.rs" harness = false [dependencies.rapidhash] version = "4.4.1" default-features = false [dev-dependencies.criterion] version = "0.7" default-features = false [dev-dependencies.log] version = "0.4" default-features = false [dev-dependencies.rand] version = "0.9" features = ["thread_rng"] default-features = false [dev-dependencies.trybuild] version = "1" default-features = false [target.'cfg(target_pointer_width = "32")'.dependencies.portable-atomic] version = "1" features = ["fallback"] default-features = false metrics-0.24.6/Cargo.toml.orig000064400000000000000000000015151046102023000142540ustar 00000000000000[package] name = "metrics" version = "0.24.6" edition = "2018" rust-version = { workspace = true } description = "A lightweight metrics facade." license = { workspace = true } authors = ["Toby Lawrence "] repository = { workspace = true } homepage = { workspace = true } documentation = "https://docs.rs/metrics" readme = "README.md" categories = ["development-tools::debugging"] keywords = ["metrics", "facade"] [lib] bench = false [[bench]] name = "macros" harness = false [dependencies] rapidhash = { workspace = true } [target.'cfg(target_pointer_width = "32")'.dependencies] portable-atomic = { version = "1", default-features = false, features = [ "fallback", ] } [dev-dependencies] criterion = { workspace = true } log = { workspace = true } rand = { workspace = true } trybuild = { workspace = true } metrics-0.24.6/LICENSE000064400000000000000000000020501046102023000123650ustar 00000000000000Copyright (c) 2021 Metrics Contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. metrics-0.24.6/README.md000064400000000000000000000022011046102023000126350ustar 00000000000000# metrics [![conduct-badge][]][conduct] [![downloads-badge][] ![release-badge][]][crate] [![docs-badge][]][docs] [![license-badge][]](#license) [conduct-badge]: https://img.shields.io/badge/%E2%9D%A4-code%20of%20conduct-blue.svg [downloads-badge]: https://img.shields.io/crates/d/metrics.svg [release-badge]: https://img.shields.io/crates/v/metrics.svg [license-badge]: https://img.shields.io/crates/l/metrics.svg [docs-badge]: https://docs.rs/metrics/badge.svg [conduct]: https://github.com/metrics-rs/metrics/blob/master/CODE_OF_CONDUCT.md [crate]: https://crates.io/crates/metrics [docs]: https://docs.rs/metrics __metrics__ is a lightweight metrics facade. ## code of conduct **NOTE**: All conversations and contributions to this project shall adhere to the [Code of Conduct][conduct]. # what's it all about? __metrics__ provides macros, similar to the [`log`](https://docs.rs/log) crate, that let library and executable authors instrument their code by collecting metrics -- incrementing counters, gauges, and histograms -- about their code, deferring the collecting and export of these metrics to whatever the installed metrics library is. metrics-0.24.6/RELEASES.md000064400000000000000000000352341046102023000131170ustar 00000000000000# Releases Unlike the [CHANGELOG](CHANGELOG.md), this file tracks more complicated changes that required long-form description and would be too verbose for the changelog alone. ## [Unreleased] - ReleaseDate - No notable changes. ## [0.24.6] - 2026-05-13 - No notable changes. ## [0.24.5] - 2026-04-29 - No notable changes. ## [0.24.4] - 2026-04-28 - No notable changes. ## [0.24.3] - 2025-11-28 - No notable changes. ## [0.24.2] - 2025-04-20 - No notable changes. ## [0.24.1] - 2024-11-26 - No notable changes. ## [0.24.0] - 2024-10-12 - No notable changes. ## [0.23.0] - 2024-05-27 - No notable changes. ## [0.22.3] - 2024-03-16 - No notable changes. ## [0.22.2] - 2024-03-16 - No notable changes. ## [0.22.1] - 2024-02-11 - No notable changes. ## [0.22.0] - 2023-12-24 ### Metric metadata Metrics now support collecting a limited set of metadata field, which can be provided to add context on where a metric originates from as well as its verbosity. In the grand vision of the `metrics` crate, where library authors use it to emit metrics from their libraries, and then downstream users get those metrics in their application for free... the biggest problem is that users had no way to actually filter out metrics they didn't want. Metric metadata aims to provide a solution to this problem. A new type `Metadata<'a>` has been added to track all of this information, which includes **module path**, a **target**, and a **level**. These fields map almost directly to [`tracing`](https://docs.rs/tracing) -- the inspiration for adding this metadata support -- and provide the ability to: - group/filter metrics by where they're defined (module path) - group/filter metrics by where they're emitted from (target) - group/filter metrics by their verbosity (level) `Metadata<'a>` is passed into the `Recorder` API when registering a metric so that exporters can capture it and utilize it. #### Examples As an example, users may wish to filter out metrics defined by a particular crate because they don't care about them at all. While they might have previously been able to get lucky and simply filter the metrics by a common prefix, this still allows for changes to the metric names to break the filter configuration. If we instead filtered by module path, where we can simply use the crate name itself, then we'd catch all metrics for that crate regardless of their name and regardless of the crate version. Similarly, as another example, users may wish to only emit common metrics related to operation of their application/service in order to consume less resources, pay less money for the ingest/storage of the metrics, and so on. During an outage, or when debugging an issue, though, they may wish to increase the verbosity of metrics they emit in order to capture more granular detail. Being able to filter by level now provides a mechanism to do so. #### Usage First, it needs to be said that nothing in the core `metrics` crates actually utilizes this metadata yet. We'll add support in the future to existing layers, such as the [filter][filter_layer_docs] layer, in order to take advantage of this support. With that said, actually setting this metadata is very easy! As a refresher, you'd normally emit metrics with something like this: ```rust metrics::increment_counter!("my_counter"); ``` Now, you can specify the additional metadata attributes as fields at the beginning of the macro call. This applies to all of the "emission" macros for counters, gauges, and histograms: ```rust metrics::increment_counter!(target: "myapp", "my_counter"); metrics::increment_gauge!(level: metrics::Level::DEBUG, "my_gauge", 42.2); metrics::histogram!(target: "myapp", level: metrics::Level::DEBUG, "my_histogram", 180.1); ``` These metrics will have the relevant metadata field set, and all of them will get the module path provided automatically, as well. ### Macros overhaul We've reworked the macros to both simplify their implementation and to hopefully provide a more ergonomic experience for users. At a high level, we've: - removed all the various macros that were tied to specific _operations_ (e.g. `increment_counter!` for incrementing a counter) and replaced them with one macro per metric type - removed the standalone registration macros (e.g. `register_counter!`) - exposed the operations as methods on the metric handles themselves - switched from using procedural macros to declarative macros #### Fewer macros, more ergonomic usage Users no longer need to remember the specific macro to use for a given metric operation, such as `increment_gauge!` or `decrement_gauge!`. Instead, if the user knows they're working with a gauge, they simply call `gauge!(...)` to get the handle, and chain on a method call to perform the operation, such as `gauge!(...).increment(42.2)`. Additionally, because we've condensed the registration macros into the new, simplified macros, the same macro is used whether registering the metric to get a handle, or simply performing an operation on the metric all at once. Let's look at a few examples: ```rust // This is the old style of registering a metric and then performing an operation on it. // // We're working with a counter here. let counter_handle = metrics::register_counter!("my_counter"); counter_handle.increment(1); metrics::increment_counter!("my_counter"); // Now let's use the new, simplified macros instead: let counter_handle = metrics::counter!("my_counter"); counter_handle.increment(1); metrics::counter!("my_counter").increment(1); ``` As you can see, users no longer need to know about as many macros, and their usage is consistent whether working with a metric handle that is held long-term, or chaining the method call inline with the macro call. As a benefit, this also means that IDE completion will be better in some situations, as support for autocompletion of method calls is generally well supported, while macro autocompletion is effectively nonexistent. #### Declarative macros As part of this rework, the macros have also been rewritten declaratively. While the macro code itself is slightly more complicated/verbose, it has a major benefit that the `metrics-macros` crate was able to be removed. This is one less dependency that has to be compiled, which should hopefully help with build times, even if only slightly. [filter_layer_docs]: https://docs.rs/metrics-util/latest/metrics_util/layers/struct.FilterLayer.html ### Scoped recorders We've added support for scoped recorders, which should allow both library authors writing exporters, as well as downstream users of `metrics`, test their implementations far more easily. #### Global recorder Prior to this release, the only way to test either exporters or metrics emission was to install a special debug/test recorder as the global recorder. This conceptually works, but quickly runs into a few issues: - it's not thread-safe (the global recorder is, well, global) - it requires the recorder be _implemented_ in a thread-safe way This meant that in order to safely do this type of testing, users would have to use something like [`DebuggingRecorder`](https://docs.rs/metrics-util/latest/metrics_util/debugging/struct.DebuggingRecorder.html) (which is thread-safe and _could_ be used in a per-thread way, mind you) but that they would have to install it for every single test... which could still run into issues with destroying the collected metrics of another concurrently running test that took the same approach. All in all, this was a pretty poor experience that required many compromises and _still_ didn't fully allow testing metrics in a deterministic and repeatable way. #### Scoped recorders Scoped recorders solve this problem by allowing the temporary overriding of what is considered the "global" recorder on the current thread. We've added a new method, [`metrics::with_local_recorder`](https://docs.rs/metrics/latest/metrics/fn.set_boxed_recorder.html), that allows users to pass a reference to a recorder that is used as the "global" recorder for the duration of a closure that the user also passes. Here's a quick example of what the prior approach looked like, and how it's been simplified by adding support for scoped recorders: ```rust // This is the old approach, which mind you, still isn't thread-safe if you have concurrent tests // doing the same thing: let global = DebuggingRecorder::per_thread(); let snapshotter = global.snapshotter(); unsafe { metrics::clear_recorder(); } global.install().expect("global recorder should not be installed"); increment_counter!("my_counter"); let snapshot = snapshotter.snapshot(); assert_eq!(snapshot.into_vec().len(), 1); // Now let's use a scoped recorder instead: let scoped = DebuggingRecorder::new(); let snapshotter = scoped.snappshotter(); metrics::with_local_recorder(&scoped, || { increment_counter!("my_counter") }); let snapshot = snapppshotter.snapshot(); assert_eq!(snapshot.into_vec().len(), 1); ``` There's a lot of boilerplate here, but let's look specifically at what we _don't_ have to do anymore: - unsafely clear the global recorder - install as the global recorder - transfer ownership of the recorder itself This means that recorders can now themselves hold references to other resources, without the need to do the common `Arc>` dance that was previously required. Given the interface of `Recorder`, interior mutability still has to be provided somehow, although now it only requires the use of something as straightforward as `RefCell`. Beyond testing, this also opens up additional functionality that wasn't previously available. For example, this approach could be used to avoid the need for using thread-safe primitives when users don't want to pay that cost (perhaps on an embedded system). ## [0.21.1] - 2023-07-02 - No notable changes. ## [0.21.0] - 2023-04-16 - No notable changes. ## [0.20.1] - 2022-07-22 - No notable changes. ## [0.20.0] - 2022-07-20 - No notable changes. ## [0.19.0] - 2022-05-30 - No notable changes. ## [0.18.1] - 2022-03-10 - No notable changes. ## [0.18.0] - 2022-01-14 ### Switch to metric handles `metrics` has now switched to "metric handles." This requires a small amount of backstory. #### Evolution of data storage in `metrics` Originally, [`metrics`][metrics] started its life as [`metrics-runtime`][metrics-runtime], which represented a batteries-included implementation of metrics storage, with both a user-accessible API that allowed directly interacting with the metrics as well as a mode for being installed as the global recorder for [`metrics`]. The user-accessible API was most commonly accessed via a helper type called `Sink`, which could both create metric type-specific handles -- such as `Counter` or `Gauge` -- and could also perform operations directly, such as `increment_counter`. However, users still needed to both create the machinery supplied by `metrics-runtime` to handle metrics storage, as well as the actual exporters to access those metrics, or send them to the downstream system of choice. We ultimately made the decision to bundle the metrics storage capabilities into exporters directly by moving much of [`metrics-runtime`][metrics-runtime] to [`metrics-util`][metrics-util] as a set of reusable components. In doing so, though, we lost the ability to access metrics directly, as the [`metrics`][metrics] facade became the only way to register or emit metrics, and this could only happen through the opaque macros, going through the opaque `Recorder` trait, and so on. This made it easy for all users to simply interact with the macros, but made it harder to optimize the performance of recording metrics. With this update, we've switched back to a handle-based model that also works seamlessly with the macros. #### Handle-based design The `metrics` crate now provides concrete handle types for all metrics. The `Recorder` API has also been updated to return these handles when registering a metric. Thus, for macros, instead of simply calling the operation directly on the global recorder, they now register the metric first and call the operation on the handle. If the metric has already been registered, similar to as before, a copy of the handle is simply returned and can be operated as normally. On the flipside, though, users can use directly acquire these handles using the `register_*` macros. The macros for adding descriptive information have been renamed to `describe_*`. Thus, when there is an opportunity to register metrics and store their handles somewhere for later reuse, users can use the `register_*` macros to do so. #### Implementation of handles In order to provide an mechanism that allows enough flexibility for exporter authors, the design of the handle types was considered in depth. Simply put, handles represent an incredibly thin layer over compatible implementations of each metric type. There are now three traits, one for each metric type, that must be implemented to satisfy being wrapped in the corresponding handle type. Internally, this is wrapped in an [`Arc`][arc] to make it usable in multi-threaded scenarios. Implementations of `Counter` and `Gauge` based on atomic integers can be found in [`metrics`][metrics], and an example of `Histogram` can be found in [`metrics-util`][metrics-util]. #### Limitations of handles In most cases, the new handle-based design will be effectively invisible, with no visible changes to behavior. There is one scenario where changes could be encountered, though: use of [layers][layers]. Layers work on a per-metric basis, which means that when a handle is acquired and used directly, any layers that were used no longer have a way to intercept the calls made to handles. When the macros are used, however, a call is always made to "register" the metric, which provides a chance for the layers to intercept and modify things as necessary. As a concrete example, the [`metrics-tracing-context`][mtc] layer exists to annotate a metric's set of labels with fields from the `tracing::Span` that is currently entered when the metric is updated. Naturally, a given metric could be emitted while in a various number of different spans, but if a metric is first registered in a particular span, and then the handle is used from that point on... only the original span fields will be attached to the metric. This is an inherent trade-off between providing a way to reduce the overhead of updating a metric to the bare minimum, and providing extensibility via layers. [metrics]: https://docs.rs/metrics/latest/metrics/ [metrics-runtime]: https://docs.rs/metrics-runtime/latest/metrics_runtime/ [metrics-util]: https://docs.rs/metrics-util/latest/metrics-util/ [arc]: https://doc.rust-lang.org/stable/std/sync/struct.Arc.html [layers]: https://docs.rs/metrics-util/latest/metrics_util/layers/index.html [mtc]: https://docs.rs/metrics-tracing-context/latest/metrics_tracing_context/ metrics-0.24.6/benches/macros.rs000064400000000000000000000057731046102023000146400ustar 00000000000000#[macro_use] extern crate criterion; use criterion::Criterion; use metrics::{ counter, Counter, Gauge, Histogram, Key, KeyName, Metadata, Recorder, SharedString, Unit, }; #[derive(Debug)] struct TestRecorder; impl Recorder for TestRecorder { fn describe_counter(&self, _: KeyName, _: Option, _: SharedString) {} fn describe_gauge(&self, _: KeyName, _: Option, _: SharedString) {} fn describe_histogram(&self, _: KeyName, _: Option, _: SharedString) {} fn register_counter(&self, _: &Key, _: &Metadata<'_>) -> Counter { Counter::noop() } fn register_gauge(&self, _: &Key, _: &Metadata<'_>) -> Gauge { Gauge::noop() } fn register_histogram(&self, _: &Key, _: &Metadata<'_>) -> Histogram { Histogram::noop() } } fn macro_benchmark(c: &mut Criterion) { let mut group = c.benchmark_group("macros"); group.bench_function("uninitialized/no_labels", |b| { b.iter(|| { counter!("counter_bench").increment(42); }) }); group.bench_function("uninitialized/with_static_labels", |b| { b.iter(|| { counter!("counter_bench", "request" => "http", "svc" => "admin").increment(42); }) }); group.bench_function("global_initialized/no_labels", |b| { let _ = metrics::set_global_recorder(TestRecorder); b.iter(|| { counter!("counter_bench").increment(42); }); }); group.bench_function("global_initialized/with_static_labels", |b| { let _ = metrics::set_global_recorder(TestRecorder); b.iter(|| { counter!("counter_bench", "request" => "http", "svc" => "admin").increment(42); }); }); group.bench_function("global_initialized/with_dynamic_labels", |b| { let _ = metrics::set_global_recorder(TestRecorder); let label_val = rand::random::().to_string(); b.iter(move || { counter!("counter_bench", "request" => "http", "uid" => label_val.clone()) .increment(42); }); }); group.bench_function("local_initialized/no_labels", |b| { metrics::with_local_recorder(&TestRecorder, || { b.iter(|| { counter!("counter_bench").increment(42); }); }); }); group.bench_function("local_initialized/with_static_labels", |b| { metrics::with_local_recorder(&TestRecorder, || { b.iter(|| { counter!("counter_bench", "request" => "http", "svc" => "admin").increment(42); }); }); }); group.bench_function("local_initialized/with_dynamic_labels", |b| { metrics::with_local_recorder(&TestRecorder, || { let label_val = rand::random::().to_string(); b.iter(move || { counter!("counter_bench", "request" => "http", "uid" => label_val.clone()) .increment(42); }); }); }); group.finish(); } criterion_group!(benches, macro_benchmark); criterion_main!(benches); metrics-0.24.6/examples/basic.rs000064400000000000000000000145011046102023000146310ustar 00000000000000//! This example is part unit test and part demonstration. //! //! We show all of the registration macros, as well as all of the "emission" macros, the ones you //! would actually call to update a metric. //! //! We demonstrate the various permutations of values that can be passed in the macro calls, all of //! which are documented in detail for the respective macro. use std::sync::Arc; use metrics::{ counter, describe_counter, describe_gauge, describe_histogram, gauge, histogram, KeyName, Metadata, SharedString, }; use metrics::{Counter, CounterFn, Gauge, GaugeFn, Histogram, HistogramFn, Key, Recorder, Unit}; #[derive(Clone, Debug)] struct PrintHandle(Key); impl CounterFn for PrintHandle { fn increment(&self, value: u64) { println!("counter increment for '{}': {}", self.0, value); } fn absolute(&self, value: u64) { println!("counter absolute for '{}': {}", self.0, value); } } impl GaugeFn for PrintHandle { fn increment(&self, value: f64) { println!("gauge increment for '{}': {}", self.0, value); } fn decrement(&self, value: f64) { println!("gauge decrement for '{}': {}", self.0, value); } fn set(&self, value: f64) { println!("gauge set for '{}': {}", self.0, value); } } impl HistogramFn for PrintHandle { fn record(&self, value: f64) { println!("histogram record for '{}': {}", self.0, value); } } #[derive(Debug)] struct PrintRecorder; impl Recorder for PrintRecorder { fn describe_counter(&self, key_name: KeyName, unit: Option, description: SharedString) { println!( "(counter) registered key {} with unit {:?} and description {:?}", key_name.as_str(), unit, description ); } fn describe_gauge(&self, key_name: KeyName, unit: Option, description: SharedString) { println!( "(gauge) registered key {} with unit {:?} and description {:?}", key_name.as_str(), unit, description ); } fn describe_histogram(&self, key_name: KeyName, unit: Option, description: SharedString) { println!( "(histogram) registered key {} with unit {:?} and description {:?}", key_name.as_str(), unit, description ); } fn register_counter(&self, key: &Key, _metadata: &Metadata<'_>) -> Counter { Counter::from_arc(Arc::new(PrintHandle(key.clone()))) } fn register_gauge(&self, key: &Key, _metadata: &Metadata<'_>) -> Gauge { Gauge::from_arc(Arc::new(PrintHandle(key.clone()))) } fn register_histogram(&self, key: &Key, _metadata: &Metadata<'_>) -> Histogram { Histogram::from_arc(Arc::new(PrintHandle(key.clone()))) } } fn init_print_logger() { metrics::set_global_recorder(PrintRecorder).unwrap() } fn main() { let server_name = "web03".to_string(); init_print_logger(); let common_labels = &[("listener", "frontend")]; // Go through describing the metrics: describe_counter!("requests_processed", "number of requests processed"); describe_counter!("bytes_sent", Unit::Bytes, "total number of bytes sent"); describe_gauge!("connection_count", "current number of client connections"); describe_histogram!( "svc.execution_time", Unit::Milliseconds, "execution time of request handler" ); describe_gauge!("unused_gauge", "some gauge we'll never use in this program"); describe_histogram!( "unused_histogram", Unit::Seconds, "some histogram we'll also never use in this program" ); // And registering them: let counter1 = counter!("test_counter"); counter1.increment(1); let counter2 = counter!("test_counter", "type" => "absolute"); counter2.absolute(42); let gauge1 = gauge!("test_gauge"); gauge1.increment(1.0); let gauge2 = gauge!("test_gauge", "type" => "decrement"); gauge2.decrement(1.0); let gauge3 = gauge!("test_gauge", "type" => "set"); gauge3.set(3.1459); let histogram1 = histogram!("test_histogram"); histogram1.record(0.57721); // All the supported permutations of `counter!` and its increment/absolute versions: counter!("bytes_sent").increment(64); counter!("bytes_sent", "listener" => "frontend").increment(64); counter!("bytes_sent", "listener" => "frontend", "server" => server_name.clone()).increment(64); counter!("bytes_sent", common_labels).increment(64); counter!("requests_processed").increment(1); counter!("requests_processed", "request_type" => "admin").increment(1); counter!("requests_processed", "request_type" => "admin", "server" => server_name.clone()) .increment(1); counter!("requests_processed", common_labels).increment(1); counter!("bytes_sent").absolute(64); counter!("bytes_sent", "listener" => "frontend").absolute(64); counter!("bytes_sent", "listener" => "frontend", "server" => server_name.clone()).absolute(64); counter!("bytes_sent", common_labels).absolute(64); // All the supported permutations of `gauge!` and its increment/decrement versions: gauge!("connection_count").set(300.0); gauge!("connection_count", "listener" => "frontend").set(300.0); gauge!("connection_count", "listener" => "frontend", "server" => server_name.clone()) .set(300.0); gauge!("connection_count", common_labels).set(300.0); gauge!("connection_count").increment(300.0); gauge!("connection_count", "listener" => "frontend").increment(300.0); gauge!("connection_count", "listener" => "frontend", "server" => server_name.clone()) .increment(300.0); gauge!("connection_count", common_labels).increment(300.0); gauge!("connection_count").decrement(300.0); gauge!("connection_count", "listener" => "frontend").decrement(300.0); gauge!("connection_count", "listener" => "frontend", "server" => server_name.clone()) .decrement(300.0); gauge!("connection_count", common_labels).decrement(300.0); // All the supported permutations of `histogram!`: histogram!("svc.execution_time").record(70.0); histogram!("svc.execution_time", "type" => "users").record(70.0); histogram!("svc.execution_time", "type" => "users", "server" => server_name.clone()) .record(70.0); histogram!("svc.execution_time", common_labels).record(70.0); } metrics-0.24.6/examples/sizes.rs000064400000000000000000000010471046102023000147060ustar 00000000000000//! This example is purely for development. use metrics::{Key, Label, SharedString}; use std::borrow::Cow; fn main() { println!("Key: {} bytes", std::mem::size_of::()); println!("Label: {} bytes", std::mem::size_of::