[][src]Crate metrics_facade

A lightweight metrics facade.

The metrics-facade 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.


The basic use of the facade crate is through the four metrics macros: counter!, gauge!, timing!, and value!. These macros correspond to updating a counter, updating a gauge, updating a histogram based on a start/end, and updating a histogram with a single value.

Both timing! and value! are effectively identical in so far as that they both translate to recording a single value to an underlying histogram, but timing! is provided for contextual consistency: if you're recording a measurement of the time passed during an operation, the end result is a single value, but it's more of a "timing" value than just a "value". The timing! macro also has a branch to accept the start and end values which allows for a potentially clearer invocation.

In libraries

Libraries should link only to the metrics-facade crate, and use the provided macros to record whatever metrics will be useful to downstream consumers.


extern crate metrics_facade;

pub fn process(query: &str) -> u64 {
    let start = Instant::now();
    let row_count = run_query(query);
    let end = Instant::now();

    timing!("process.query_time", start, end);
    counter!("process.query_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-facade crate to record metrics well.


The metrics system may only be initialized once.

Available metrics implementations

Currently, the only available metrics implementation is metrics.

Implementing a Recorder

Recorders implement the Recorder trait. Here's a basic example which writes the metrics in text form via the log crate.

extern crate log;
extern crate metrics_facade;
extern crate metrics_core;

use metrics_facade::Recorder;
use metrics_core::Key;

struct LogRecorder;

impl Recorder for LogRecorder {
    fn record_counter(&self, key: Key, value: u64) {
        info!("counter '{}' -> {}", key, value);

    fn record_gauge(&self, key: Key, value: i64) {
        info!("gauge '{}' -> {}", key, value);

    fn record_histogram(&self, key: Key, value: u64) {
        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_facade::SetRecorderError;

static RECORDER: SimpleRecorder = SimpleRecorder;

pub fn init() -> Result<(), SetRecorderError> {

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_facade::SetRecorderError;

pub fn init() -> Result<(), SetRecorderError> {



Records a counter.


Records a gauge.


Records a timing.


Records a value.



The type returned by set_recorder if set_recorder has already been called.



A value that records metrics behind the facade.



Returns a reference to the recorder.


Sets the global recorder to a Box<Recorder>.


Sets the global recorder to a &'static Recorder.


A thread-unsafe version of set_recorder.