tokio_metrics/lib.rs
1#![warn(
2 clippy::arithmetic_side_effects,
3 missing_debug_implementations,
4 missing_docs,
5 rust_2018_idioms,
6 unreachable_pub
7)]
8#![cfg_attr(docsrs, feature(doc_cfg))]
9#![cfg_attr(docsrs, allow(unused_attributes))]
10
11//! Monitor key metrics of tokio tasks and runtimes.
12//!
13//! ### Monitoring task metrics
14//! [Monitor][TaskMonitor] key [metrics][TaskMetrics] of tokio tasks.
15//!
16//! In the below example, a [`TaskMonitor`] is [constructed][TaskMonitor::new] and used to
17//! [instrument][TaskMonitor::instrument] three worker tasks; meanwhile, a fourth task
18//! prints [metrics][TaskMetrics] in 500ms [intervals][TaskMonitor::intervals]:
19//! ```
20//! use std::time::Duration;
21//!
22//! #[tokio::main]
23//! async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
24//! // construct a metrics taskmonitor
25//! let metrics_monitor = tokio_metrics::TaskMonitor::new();
26//!
27//! // print task metrics every 500ms
28//! {
29//! let metrics_monitor = metrics_monitor.clone();
30//! tokio::spawn(async move {
31//! for interval in metrics_monitor.intervals() {
32//! // pretty-print the metric interval
33//! println!("{:?}", interval);
34//! // wait 500ms
35//! tokio::time::sleep(Duration::from_millis(500)).await;
36//! }
37//! });
38//! }
39//!
40//! // instrument some tasks and await them
41//! // note that the same taskmonitor can be used for multiple tasks
42//! tokio::join![
43//! metrics_monitor.instrument(do_work()),
44//! metrics_monitor.instrument(do_work()),
45//! metrics_monitor.instrument(do_work())
46//! ];
47//!
48//! Ok(())
49//! }
50//!
51//! async fn do_work() {
52//! for _ in 0..25 {
53//! tokio::task::yield_now().await;
54//! tokio::time::sleep(Duration::from_millis(100)).await;
55//! }
56//! }
57//! ```
58
59#![cfg_attr(
60 feature = "rt",
61 doc = r##"
62### Monitoring runtime metrics
63[Monitor][RuntimeMonitor] key [metrics][RuntimeMetrics] of a tokio runtime.
64**This functionality requires crate feature `rt` and some metrics require `tokio_unstable`.**
65
66In the below example, a [`RuntimeMonitor`] is [constructed][RuntimeMonitor::new] and
67three tasks are spawned and awaited; meanwhile, a fourth task prints [metrics][RuntimeMetrics]
68in 500ms [intervals][RuntimeMonitor::intervals]:
69```
70use std::time::Duration;
71
72#[tokio::main]
73async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
74 let handle = tokio::runtime::Handle::current();
75 // construct the runtime metrics monitor
76 let runtime_monitor = tokio_metrics::RuntimeMonitor::new(&handle);
77
78 // print runtime metrics every 500ms
79 {
80 tokio::spawn(async move {
81 for interval in runtime_monitor.intervals() {
82 // pretty-print the metric interval
83 println!("{:?}", interval);
84 // wait 500ms
85 tokio::time::sleep(Duration::from_millis(500)).await;
86 }
87 });
88 }
89
90 // await some tasks
91 tokio::join![
92 do_work(),
93 do_work(),
94 do_work(),
95 ];
96
97 Ok(())
98}
99
100async fn do_work() {
101 for _ in 0..25 {
102 tokio::task::yield_now().await;
103 tokio::time::sleep(Duration::from_millis(100)).await;
104 }
105}
106```
107"##
108)]
109
110//! ### Monitoring and publishing metrics
111//!
112//! If the `metrics-rs-integration` feature is additionally enabled, this crate allows
113//! publishing metrics externally via [metrics-rs](metrics) exporters.
114//!
115//! For example, you can use [metrics_exporter_prometheus] to make metrics visible
116//! to [Prometheus]. You can see the [metrics_exporter_prometheus] and [metrics-rs](metrics)
117//! docs for guidance on configuring exporters.
118//!
119//! The published metrics are the same as the fields and methods of
120#![cfg_attr(feature = "rt", doc = "[RuntimeMetrics] and")]
121//! [TaskMetrics], but with a "tokio_" prefix added, for example
122#![cfg_attr(feature = "rt", doc = "`tokio_workers_count` and")]
123//! `tokio_instrumented_count`.
124//!
125//! [metrics_exporter_prometheus]: https://docs.rs/metrics_exporter_prometheus
126#![cfg_attr(feature = "rt", doc = "[RuntimeMetrics]: crate::RuntimeMetrics")]
127//! [Prometheus]: https://prometheus.io
128//! [TaskMetrics]: crate::TaskMetrics
129//!
130//! This example exports [Prometheus] metrics by listening on a local Unix socket
131//! called `prometheus.sock`, which you can access for debugging by
132//! `curl --unix-socket prometheus.sock localhost`.
133//!
134//! ```
135//! use std::time::Duration;
136//!
137//! #[tokio::main]
138//! async fn main() {
139//! metrics_exporter_prometheus::PrometheusBuilder::new()
140//! .with_http_uds_listener("prometheus.sock")
141//! .install()
142//! .unwrap();
143#![cfg_attr(
144 all(feature = "rt", feature = "metrics-rs-integration"),
145 doc = r##"
146 // This line launches the runtime reporter that monitors the Tokio runtime and exports the metrics.
147 tokio::task::spawn(
148 tokio_metrics::RuntimeMetricsReporterBuilder::default().describe_and_run(),
149 );
150"##
151)]
152//! let monitor = tokio_metrics::TaskMonitor::new();
153#![cfg_attr(
154 all(feature = "rt", feature = "metrics-rs-integration"),
155 doc = r##"
156 use metrics::Key;
157 // This line launches the task reporter that monitors Tokio tasks and exports the metrics.
158 tokio::task::spawn(
159 tokio_metrics::TaskMetricsReporterBuilder::new(|name| {
160 let name = name.replacen("tokio_", "my_task_", 1);
161 Key::from_parts(name, &[("application", "my_app")])
162 })
163 .describe_and_run(monitor.clone()),
164 );
165"##
166)]
167//! // Run some code.
168//! tokio::task::spawn(monitor.instrument(async move {
169//! for _ in 0..1000 {
170//! tokio::time::sleep(Duration::from_millis(10)).await;
171//! }
172//! }))
173//! .await
174//! .unwrap();
175//! }
176//! ```
177
178macro_rules! cfg_rt {
179 ($($item:item)*) => {
180 $(
181 #[cfg(feature = "rt")]
182 #[cfg_attr(docsrs, doc(cfg(feature = "rt")))]
183 $item
184 )*
185 };
186}
187
188cfg_rt! {
189 mod runtime;
190 pub use runtime::{
191 RuntimeIntervals,
192 RuntimeMetrics,
193 RuntimeMonitor,
194 };
195}
196
197#[cfg(all(feature = "rt", feature = "metrics-rs-integration"))]
198#[cfg_attr(
199 docsrs,
200 doc(cfg(all(feature = "rt", feature = "metrics-rs-integration")))
201)]
202pub use runtime::metrics_rs_integration::{RuntimeMetricsReporter, RuntimeMetricsReporterBuilder};
203
204mod derived_metrics;
205#[cfg(feature = "metrics-rs-integration")]
206mod metrics_rs;
207mod task;
208
209#[cfg(feature = "metrics-rs-integration")]
210#[cfg_attr(docsrs, doc(cfg(feature = "metrics-rs-integration")))]
211pub use task::metrics_rs_integration::{TaskMetricsReporter, TaskMetricsReporterBuilder};
212pub use task::{
213 Instrumented, TaskIntervals, TaskMetrics, TaskMonitor, TaskMonitorCore, TaskMonitorCoreBuilder,
214};