Struct metrics_prometheus::Recorder
source · pub struct Recorder<FailureStrategy = PanicInDebugNoOpInRelease> { /* private fields */ }
Expand description
metrics::Recorder
registering metrics in a prometheus::Registry
and
powered by a metrics::Registry
built on top of a storage::Mutable
.
This Recorder
is capable of registering metrics in its
prometheus::Registry
on the fly. By default, the
prometheus::default_registry()
is used.
Example
let recorder = metrics_prometheus::install();
// Either use `metrics` crate interfaces.
metrics::counter!(
"count", "whose" => "mine", "kind" => "owned",
).increment(1);
metrics::counter!(
"count", "whose" => "mine", "kind" => "ref",
).increment(1);
metrics::counter!(
"count", "kind" => "owned", "whose" => "dummy",
).increment(1);
// Or construct and provide `prometheus` metrics directly.
recorder.register_metric(prometheus::Gauge::new("value", "help")?);
let report = prometheus::TextEncoder::new()
.encode_to_string(&prometheus::default_registry().gather())?;
assert_eq!(
report.trim(),
r#"
# HELP count count
# TYPE count counter
count{kind="owned",whose="dummy"} 1
count{kind="owned",whose="mine"} 1
count{kind="ref",whose="mine"} 1
# HELP value help
# TYPE value gauge
value 0
"#
.trim(),
);
// Metrics can be described anytime after being registered in
// `prometheus::Registry`.
metrics::describe_counter!("count", "Example of counter.");
metrics::describe_gauge!("value", "Example of gauge.");
let report = prometheus::TextEncoder::new()
.encode_to_string(&recorder.registry().gather())?;
assert_eq!(
report.trim(),
r#"
# HELP count Example of counter.
# TYPE count counter
count{kind="owned",whose="dummy"} 1
count{kind="owned",whose="mine"} 1
count{kind="ref",whose="mine"} 1
# HELP value Example of gauge.
# TYPE value gauge
value 0
"#
.trim(),
);
// Description can be changed multiple times and anytime:
metrics::describe_counter!("count", "Another description.");
// Even before a metric is registered in `prometheus::Registry`.
metrics::describe_counter!("another", "Yet another counter.");
metrics::counter!("another").increment(1);
let report = prometheus::TextEncoder::new()
.encode_to_string(&recorder.registry().gather())?;
assert_eq!(
report.trim(),
r#"
# HELP another Yet another counter.
# TYPE another counter
another 1
# HELP count Another description.
# TYPE count counter
count{kind="owned",whose="dummy"} 1
count{kind="owned",whose="mine"} 1
count{kind="ref",whose="mine"} 1
# HELP value Example of gauge.
# TYPE value gauge
value 0
"#
.trim(),
);
Performance
This Recorder
provides the same overhead of accessing an already
registered metric as a metrics::Registry
does: read
-lock on a
sharded HashMap
plus Arc
cloning.
Errors
prometheus::Registry
has far more stricter semantics than the ones
implied by a metrics::Recorder
. That’s why incorrect usage of
prometheus
metrics via metrics
crate will inevitably lead to a
prometheus::Registry
returning a prometheus::Error
instead of
registering the metric. The returned prometheus::Error
can be either
turned into a panic, or just silently ignored, making this Recorder
to
return a no-op metric instead (see metrics::Counter::noop()
for
example).
The desired behavior can be specified with a failure::Strategy
implementation of this Recorder
. By default a
PanicInDebugNoOpInRelease
failure::Strategy
is used. See
failure::strategy
module for other available failure::Strategy
s, or
provide your own one by implementing the failure::Strategy
trait.
use metrics_prometheus::failure::strategy;
metrics_prometheus::Recorder::builder()
.with_failure_strategy(strategy::Panic)
.build_and_install();
metrics::counter!("count", "kind" => "owned").increment(1);
// This panics, as such labeling is not allowed by `prometheus` crate.
metrics::counter!("count", "whose" => "mine").increment(1);
Implementations§
source§impl Recorder
impl Recorder
sourcepub fn builder() -> Builder
pub fn builder() -> Builder
Starts building a new Recorder
on top of the
prometheus::default_registry()
.
source§impl<S> Recorder<S>
impl<S> Recorder<S>
sourcepub const fn registry(&self) -> &Registry
pub const fn registry(&self) -> &Registry
Returns the underlying prometheus::Registry
backing this
Recorder
.
Warning
Any prometheus
metrics, registered directly in the returned
prometheus::Registry
, cannot be used via this metrics::Recorder
(and, so, metrics
crate interfaces), and trying to use them will
inevitably cause a prometheus::Error
being emitted.
use metrics_prometheus::failure::strategy;
let recorder = metrics_prometheus::Recorder::builder()
.with_failure_strategy(strategy::Panic)
.build_and_install();
let counter = prometheus::IntCounter::new("value", "help")?;
recorder.registry().register(Box::new(counter))?;
// panics: Duplicate metrics collector registration attempted
metrics::counter!("value").increment(1);
sourcepub fn try_register_metric<M>(&self, metric: M) -> Result<()>
pub fn try_register_metric<M>(&self, metric: M) -> Result<()>
Tries to register the provided prometheus
metric
in the underlying
prometheus::Registry
in the way making it usable via this
Recorder
(and, so, metrics
crate interfaces).
Accepts only the following prometheus
metrics:
prometheus::IntCounter
,prometheus::IntCounterVec
prometheus::Gauge
,prometheus::GaugeVec
prometheus::Histogram
,prometheus::HistogramVec
Errors
If the underlying prometheus::Registry
fails to register the
provided metric
.
Example
let recorder = metrics_prometheus::install();
let counter = prometheus::IntCounterVec::new(
prometheus::opts!("value", "help"),
&["whose", "kind"],
)?;
recorder.try_register_metric(counter.clone())?;
counter.with_label_values(&["mine", "owned"]).inc();
counter.with_label_values(&["foreign", "ref"]).inc_by(2);
counter.with_label_values(&["foreign", "owned"]).inc_by(3);
let report = prometheus::TextEncoder::new()
.encode_to_string(&prometheus::default_registry().gather())?;
assert_eq!(
report.trim(),
r#"
# HELP value help
# TYPE value counter
value{kind="owned",whose="foreign"} 3
value{kind="owned",whose="mine"} 1
value{kind="ref",whose="foreign"} 2
"#
.trim(),
);
metrics::counter!(
"value", "whose" => "mine", "kind" => "owned",
).increment(1);
metrics::counter!(
"value", "whose" => "mine", "kind" => "ref",
).increment(1);
metrics::counter!(
"value", "kind" => "owned", "whose" => "foreign",
).increment(1);
let report = prometheus::TextEncoder::new()
.encode_to_string(&recorder.registry().gather())?;
assert_eq!(
report.trim(),
r#"
# HELP value help
# TYPE value counter
value{kind="owned",whose="foreign"} 4
value{kind="owned",whose="mine"} 2
value{kind="ref",whose="foreign"} 2
value{kind="ref",whose="mine"} 1
"#
.trim(),
);
sourcepub fn register_metric<M>(&self, metric: M)
pub fn register_metric<M>(&self, metric: M)
Registers the provided prometheus
metric
in the underlying
prometheus::Registry
in the way making it usable via this
Recorder
(and, so, metrics
crate interfaces).
Accepts only the following prometheus
metrics:
prometheus::IntCounter
,prometheus::IntCounterVec
prometheus::Gauge
,prometheus::GaugeVec
prometheus::Histogram
,prometheus::HistogramVec
Panics
If the underlying prometheus::Registry
fails to register the
provided metric
.
Example
let recorder = metrics_prometheus::install();
let gauge = prometheus::GaugeVec::new(
prometheus::opts!("value", "help"),
&["whose", "kind"],
)?;
recorder.register_metric(gauge.clone());
gauge.with_label_values(&["mine", "owned"]).inc();
gauge.with_label_values(&["foreign", "ref"]).set(2.0);
gauge.with_label_values(&["foreign", "owned"]).set(3.0);
let report = prometheus::TextEncoder::new()
.encode_to_string(&prometheus::default_registry().gather())?;
assert_eq!(
report.trim(),
r#"
# HELP value help
# TYPE value gauge
value{kind="owned",whose="foreign"} 3
value{kind="owned",whose="mine"} 1
value{kind="ref",whose="foreign"} 2
"#
.trim(),
);
metrics::gauge!(
"value", "whose" => "mine", "kind" => "owned",
).increment(2.0);
metrics::gauge!(
"value", "whose" => "mine", "kind" => "ref",
).decrement(2.0);
metrics::gauge!(
"value", "kind" => "owned", "whose" => "foreign",
).increment(2.0);
let report = prometheus::TextEncoder::new()
.encode_to_string(&prometheus::default_registry().gather())?;
assert_eq!(
report.trim(),
r#"
# HELP value help
# TYPE value gauge
value{kind="owned",whose="foreign"} 5
value{kind="owned",whose="mine"} 3
value{kind="ref",whose="foreign"} 2
value{kind="ref",whose="mine"} -2
"#
.trim(),
);