1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(docsrs, allow(unused_attributes))]

//! Monitor key metrics of tokio tasks and runtimes.
//!
//! ### Monitoring task metrics
//! [Monitor][TaskMonitor] key [metrics][TaskMetrics] of tokio tasks.
//!
//! In the below example, a [`TaskMonitor`] is [constructed][TaskMonitor::new] and used to
//! [instrument][TaskMonitor::instrument] three worker tasks; meanwhile, a fourth task
//! prints [metrics][TaskMetrics] in 500ms [intervals][TaskMonitor::intervals]:
//! ```
//! use std::time::Duration;
//!
//! #[tokio::main]
//! async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
//!     // construct a metrics taskmonitor
//!     let metrics_monitor = tokio_metrics::TaskMonitor::new();
//!
//!     // print task metrics every 500ms
//!     {
//!         let metrics_monitor = metrics_monitor.clone();
//!         tokio::spawn(async move {
//!             for interval in metrics_monitor.intervals() {
//!                 // pretty-print the metric interval
//!                 println!("{:?}", interval);
//!                 // wait 500ms
//!                 tokio::time::sleep(Duration::from_millis(500)).await;
//!             }
//!         });
//!     }
//!
//!     // instrument some tasks and await them
//!     // note that the same taskmonitor can be used for multiple tasks
//!     tokio::join![
//!         metrics_monitor.instrument(do_work()),
//!         metrics_monitor.instrument(do_work()),
//!         metrics_monitor.instrument(do_work())
//!     ];
//!
//!     Ok(())
//! }
//!
//! async fn do_work() {
//!     for _ in 0..25 {
//!         tokio::task::yield_now().await;
//!         tokio::time::sleep(Duration::from_millis(100)).await;
//!     }
//! }
//! ```

#![cfg_attr(
    all(tokio_unstable, feature = "rt"),
    doc = r##"
### Monitoring runtime metrics (unstable)
[Monitor][RuntimeMonitor] key [metrics][RuntimeMetrics] of a tokio runtime.
**This functionality requires `tokio_unstable` and the crate feature `rt`.**

In the below example, a [`RuntimeMonitor`] is [constructed][RuntimeMonitor::new] and
three tasks are spawned and awaited; meanwhile, a fourth task prints [metrics][RuntimeMetrics]
in 500ms [intervals][RuntimeMonitor::intervals]:
```
use std::time::Duration;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    let handle = tokio::runtime::Handle::current();
    // construct the runtime metrics monitor
    let runtime_monitor = tokio_metrics::RuntimeMonitor::new(&handle);

    // print runtime metrics every 500ms
    {
        tokio::spawn(async move {
            for interval in runtime_monitor.intervals() {
                // pretty-print the metric interval
                println!("{:?}", interval);
                // wait 500ms
                tokio::time::sleep(Duration::from_millis(500)).await;
            }
        });
    }

    // await some tasks
    tokio::join![
        do_work(),
        do_work(),
        do_work(),
    ];

    Ok(())
}

async fn do_work() {
    for _ in 0..25 {
        tokio::task::yield_now().await;
        tokio::time::sleep(Duration::from_millis(100)).await;
    }
}
```"##
)]

macro_rules! cfg_rt {
    ($($item:item)*) => {
        $(
            #[cfg(all(tokio_unstable, feature = "rt"))]
            #[cfg_attr(docsrs, doc(cfg(all(tokio_unstable, feature = "rt"))))]
            $item
        )*
    };
}

cfg_rt! {
    mod runtime;
    pub use runtime::{
        RuntimeMetrics,
        RuntimeMonitor,
    };
}

mod task;
pub use task::{Instrumented, TaskMetrics, TaskMonitor};