metrics_fn/
lib.rs

1//! # Function Metrics
2//!
3//! Collects execution metrics for the annotated function.
4//!
5//! The following metrics are collected:
6//! - Execution time.
7//! - Success (if function returns a `core::result::Result`-like type.
8//!
9//! ## Usage
10//!
11//! Include the dependency and enable the desired recorders.
12//!
13//! For example, the Prometheus recorder can be enabled like the following:
14//!
15//! ```toml
16//! metrics-fn = { version = "0.1", features = [ "record-prometheus" ] }
17//! ```
18//!
19//! After that, just annotate the desired functions with `#[measure]`.
20//!
21//! ```
22//! use std::thread::sleep;
23//! use std::time::Duration;
24//!
25//! use metrics_fn_codegen::measure;
26//!
27//! #[measure]
28//! pub fn super_slow_function(a: u64, b: u64) {
29//! 	sleep(Duration::from_millis(a * b));
30//! }
31//! ```
32//!
33//! Notice that there is a performance impact due to the metric collection on **every** call to the function. Thus it is
34//! advised to use the annotation on functions where the performance impact is negligible, like on function that makes
35//! calls to external services or database queries.
36//!
37//! ## Recorders
38//!
39//! The metrics are collected and sent to _recorders_, which can integrate with metrics systems like Prometheus.
40//!
41//! In order to keep dependencies to a minimum, for each recorder there is an accompanying feature. These features are
42//! composed by `record-` and metrics system it enables.  **By default, all recorders are disabled**.
43//!
44//! The following metrics systems are currently supported:
45//! - Log (`record-log`): simply log the collected metrics, using `log::info!`; not really a metric collection system.
46//! - Prometheus (`record-prometheus`): collect metrics to the default Prometheus metric registry, using the [Prometheus
47//!   crate](https://crates.io/crates/prometheus).
48//!
49//! ### Log Recorder (`record-log`)
50//!
51//! The log recorder is not really useful: it was created to help with development.
52//!
53//! It simply logs the metrics using `log::info!` or `log::error!`.
54//!
55//! ### Prometheus Recorder (`record-prometheus`)
56//!
57//! The Prometheus recorder collects metrics about the functions annotated with `#[measure]` to the
58//! `application_method_timings` histogram metric.
59//!
60//! This metric has the following labels:
61//!
62//! - `mod`: module name.
63//! - `fn`: function name.
64//! - `res`: result (`Ok` or `Err` if the annotated function result is named `Result`; always `Ok` otherwise).
65//!
66//! The following buckets are used: 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0.
67//!
68//! In order to expose the collected metrics, a web application framework like [Rocket](https://rocket.rs) or [Actix Web](https://actix.rs/) must be manually included and configured.
69//!
70//! See [metrics-fn-example-prometheus](../metrics-fn-example-prometheus) for an example.
71//!
72//! ## Versioning
73//!
74//! [Semantic Versioning](https://semver.org/) is used. Changes to the collected metrics are also considered in the versioning.
75//!
76//! ## To-Do List
77//!
78//! The following are planned features, by priority:
79//!
80//! **This list is not a commitment: items might be added or removed of the list.**
81//!
82//! - **[MEDIUM]** Record type name associated with `impl`.
83//! - **[LOW]** Configurable Prometheus metrics names and buckets.
84
85mod log;
86mod prometheus;
87
88pub use metrics_fn_codegen::measure;
89
90pub fn record(module: &str, fn_name: &str, result: Result<(), ()>, elapsed_s: f64) {
91	log::record(module, fn_name, &result, elapsed_s);
92	prometheus::record(module, fn_name, &result, elapsed_s);
93}