[−][src]Crate metrics
A lightweight metrics facade.
The metrics
crate provides a single metrics API that abstracts over the actual metrics
implementation. Libraries can use the metrics API provided by this crate, and the consumer of
those libraries can choose the metrics implementation that is most suitable for its use case.
If no metrics implementation is selected, the facade falls back to a "noop" implementation that ignores all metrics. The overhead in this case is very small - an atomic load and comparison.
Use
The basic use of the facade crate is through the three metrics macros: counter!
, gauge!
,
and histogram!
. These macros correspond to updating a counter, updating a gauge,
and updating a histogram.
In libraries
Libraries should link only to the metrics
crate, and use the provided macros to record
whatever metrics will be useful to downstream consumers.
Examples
use metrics::{histogram, counter}; pub fn process(query: &str) -> u64 { let start = Instant::now(); let row_count = run_query(query); let delta = Instant::now() - start; histogram!("process.query_time", delta); counter!("process.query_row_count", row_count); row_count }
In executables
Executables should choose a metrics implementation and initialize it early in the runtime of the program. Metrics implementations will typically include a function to do this. Any metrics recordered before the implementation is initialized will be ignored.
The executable itself may use the metrics
crate to record metrics well.
Warning
The metrics system may only be initialized once.
Available metrics implementations
Native recorder:
- metrics-exporter-tcp - outputs metrics to clients over TCP
- metrics-exporter-prometheus - serves a Prometheus scrape endpoint
Implementing a Recorder
Recorders implement the Recorder
trait. Here's a basic example which writes the
metrics in text form via the log
crate.
use log::info; use metrics::{Identifier, Key, Recorder}; struct LogRecorder { id: AtomicUsize, keys: Mutex<HashMap<Identifier, Key>>, } impl LogRecorder { fn register(&self, key: Key) -> Identifier { let uid = self.id.fetch_add(1, Ordering::AcqRel); let id = uid.into(); let mut keys = self.keys.lock().expect("failed to lock keys"); keys.insert(id, key); id } fn get_key(&self, id: Identifier) -> Key { let keys = self.keys.lock().expect("failed to lock keys"); keys.get(&id).expect("invalid identifier").clone() } } impl Recorder for LogRecorder { fn register_counter(&self, key: Key, _description: Option<&'static str>) -> Identifier { self.register(key) } fn register_gauge(&self, key: Key, _description: Option<&'static str>) -> Identifier { self.register(key) } fn register_histogram(&self, key: Key, _description: Option<&'static str>) -> Identifier { self.register(key) } fn increment_counter(&self, id: Identifier, value: u64) { let key = self.get_key(id); info!("counter '{}' -> {}", key, value); } fn update_gauge(&self, id: Identifier, value: f64) { let key = self.get_key(id); info!("gauge '{}' -> {}", key, value); } fn record_histogram(&self, id: Identifier, value: u64) { let key = self.get_key(id); info!("histogram '{}' -> {}", key, value); } }
Recorders are installed by calling the set_recorder
function. Recorders should provide a
function that wraps the creation and installation of the recorder:
use metrics::SetRecorderError; static RECORDER: LogRecorder = LogRecorder; pub fn init() -> Result<(), SetRecorderError> { metrics::set_recorder(&RECORDER) }
Use with std
set_recorder
requires you to provide a &'static Recorder
, which can be hard to
obtain if your recorder depends on some runtime configuration. The set_boxed_recorder
function is available with the std
Cargo feature. It is identical to set_recorder
except
that it takes a Box<Recorder>
rather than a &'static Recorder
:
use metrics::SetRecorderError; pub fn init() -> Result<(), SetRecorderError> { metrics::set_boxed_recorder(Box::new(LogRecorder)) }
Macros
counter | Increments a counter. |
gauge | Updates a gauge. |
histogram | Records a histogram. |
increment | Increments a counter. |
register_counter | Registers a counter. |
register_gauge | Registers a gauge. |
register_histogram | Records a histogram. |
Structs
Identifier | Opaque identifier for a metric. |
Key | A metric key. |
Label | A key/value pair used to further describe a metric. |
OnceIdentifier | Atomically-guarded identifier initialization. |
SetRecorderError | The type returned by |
Traits
IntoU64 | An object which can be converted into a |
Recorder | A value that records metrics behind the facade. |
Functions
recorder | Returns a reference to the recorder. |
set_boxed_recorder | Sets the global recorder to a |
set_recorder | Sets the global recorder to a |
set_recorder_racy⚠ | A thread-unsafe version of |
try_recorder | Returns a reference to the recorder. |
Type Definitions
ScopedString | An allocation-optimized string. |