Module metrics_util::layers[][src]

Expand description

Layers are composable helpers that can be “layered” on top of an existing Recorder to enhance or alter its behavior as desired, without having to change the recorder implementation itself.

As well, Stack can be used to easily compose multiple layers together and provides a convenience method for installing it as the global recorder, providing a smooth transition from working directly with installing exporters to installing stacks.

Here’s an example of a layer that filters out all metrics that start with a specific string:

// A simple layer that denies any metrics that have "stairway" or "heaven" in their name.
#[derive(Default)]
pub struct StairwayDeny<R>(pub(crate) R);

impl<R> StairwayDeny<R> {
    fn is_invalid_key(&self, key: &Key) -> bool {
        key.name().contains("stairway") || key.name().contains("heaven")
    }
}

impl<R: Recorder> Recorder for StairwayDeny<R> {
   fn register_counter(&self, key: &Key, unit: Option<Unit>, description: Option<&'static str>) {
       if self.is_invalid_key(&key) {
           return;
       }
       self.0.register_counter(key, unit, description)
   }

   fn register_gauge(&self, key: &Key, unit: Option<Unit>, description: Option<&'static str>) {
       if self.is_invalid_key(&key) {
           return;
       }
       self.0.register_gauge(key, unit, description)
   }

   fn register_histogram(&self, key: &Key, unit: Option<Unit>, description: Option<&'static str>) {
       if self.is_invalid_key(&key) {
           return;
       }
       self.0.register_histogram(key, unit, description)
   }

   fn increment_counter(&self, key: &Key, value: u64) {
       if self.is_invalid_key(&key) {
           return;
       }
       self.0.increment_counter(key, value);
   }

   fn update_gauge(&self, key: &Key, value: GaugeValue) {
       if self.is_invalid_key(&key) {
           return;
       }
       self.0.update_gauge(key, value);
   }

   fn record_histogram(&self, key: &Key, value: f64) {
       if self.is_invalid_key(&key) {
           return;
       }
       self.0.record_histogram(key, value);
   }
}

#[derive(Default)]
pub struct StairwayDenyLayer;

impl<R> Layer<R> for StairwayDenyLayer {
    type Output = StairwayDeny<R>;

    fn layer(&self, inner: R) -> Self::Output {
        StairwayDeny(inner)
    }
}

// Now you can construct an instance of it to use it.  The layer will be wrapped around
// our base recorder, which is a debugging recorder also supplied by `metrics_util`.
let recorder = DebuggingRecorder::new();
let layer = StairwayDenyLayer::default();
let layered = layer.layer(recorder);
metrics::set_boxed_recorder(Box::new(layered)).expect("failed to install recorder");


// Working with layers directly is a bit cumbersome, though, so let's use a `Stack`.
let stack = Stack::new(DebuggingRecorder::new());
stack.push(StairwayDenyLayer::default())
    .install()
    .expect("failed to install stack");


// `Stack` makes it easy to chain layers together, as well.
let stack = Stack::new(DebuggingRecorder::new());
stack.push(PrefixLayer::new("app_name"))
    .push(StairwayDenyLayer::default())
    .install()
    .expect("failed to install stack");

Structs

Absolute

Converts absolute counter values into incremental values.

AbsoluteLayer

A layer for converting absolute counter values into incremental values.

Fanout

Fans out metrics to multiple recorders.

FanoutBuilder

A layer for fanning out metrics to multiple recorders.

Filter

Filters and discards metrics matching certain name patterns.

FilterLayer

A layer for filtering and discarding metrics matching certain name patterns.

Prefix

Applies a prefix to every metric key.

PrefixLayer

A layer for applying a prefix to every metric key.

Router

Routes metrics to specific target recorders.

RouterBuilder

Routes metrics to specific target recorders.

Stack

Builder for composing layers together in a top-down/inside-out order.

Traits

Layer

Decorates an object by wrapping it within another type.