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