ari_subscriber/lib.rs
1//! The *Async Runtime Instrumentation Subscriber* is a [`tracing-subscriber`] optimized for
2//! visually debugging Tokio tracing instrumentation.
3//!
4//! This crate provides a [`Layer`] which writes [`tracing`] information to `stdout`. It colorizes
5//! the traces that result from the tracing instrumentation in Tokio to make identifying them
6//! easier.
7//!
8//! # Usage
9//!
10//! This example will set up a formatting [`tracing_subscriber::Layer`] which is then added to the
11//! registry. The output from the task spawned afterwards will be seen in `stdout`.
12//!
13//! ```rust
14//! use tracing_subscriber::prelude::*;
15//!
16//! #[tokio::main]
17//! async fn main() {
18//! let layer = ari_subscriber::layer();
19//!
20//! tracing_subscriber::registry().with(layer).init();
21//!
22//! tokio::spawn(async {
23//! tokio::time::sleep(std::time::Duration::from_millis(100)).await;
24//! })
25//! .await
26//! .unwrap();
27//! }
28//! ````
29//!
30//! A common use case is to use `ari_subscriber` together with the [`console-subscriber`], which
31//! aggregates the same Tokio tracing instrumentation to be visualized in Tokio Console.
32//!
33//! ```rust
34//! use tracing_subscriber::prelude::*;
35//!
36//! #[tokio::main]
37//! async fn main() {
38//! let fmt_layer = ari_subscriber::layer();
39//! let console_layer = console_subscriber::spawn();
40//!
41//! tracing_subscriber::registry()
42//! .with(fmt_layer)
43//! .with(console_layer)
44//! .init();
45//!
46//! tokio::spawn(async {
47//! tokio::time::sleep(std::time::Duration::from_millis(100)).await;
48//! })
49//! .await
50//! .unwrap();
51//! }
52//! ````
53//!
54//! ## Example output
55//!
56//! The beginning of the output of the above program would be:
57//!
58//! <pre style="background-color: #000; color: #fff">
59//! <span style='opacity:0.67'><b><span style='color:#aaa'>2023-11-28</span></b></span><span style='opacity:0.67'>T<b><span style='color:#aaa'>10:06:44</span></b></span><span style='opacity:0.67'>.746508Z</span> <span style='color:#9d4edd'>TRACE</span> <span style='color:#489e6c'>runtime.spawn[<b><span style='color:#5aba84'>1</span></b></span><span style='color:#489e6c'>]{kind=task, task.name=, task.id=18, loc.file="examples/tokio-task.rs", loc.line=14, loc.col=5}</span> <b><u><span style='color:#5aba84'>new</span></u></b>
60//! <span style='opacity:0.67'><b><span style='color:#aaa'>2023-11-28</span></b></span><span style='opacity:0.67'>T<b><span style='color:#aaa'>10:06:44</span></b></span><span style='opacity:0.67'>.747110Z</span> <span style='color:#9d4edd'>TRACE</span> <span style='color:#489e6c'>runtime.spawn[<b><span style='color:#5aba84'>1</span></b></span><span style='color:#489e6c'>]{kind=task, task.name=, task.id=18, loc.file="examples/tokio-task.rs", loc.line=14, loc.col=5}</span> <b><u><span style='color:#5aba84'>enter</span></u></b>
61//! <span style='opacity:0.67'><b><span style='color:#aaa'>2023-11-28</span></b></span><span style='opacity:0.67'>T<b><span style='color:#aaa'>10:06:44</span></b></span><span style='opacity:0.67'>.747340Z</span> <span style='color:#9d4edd'>TRACE</span> <span style='color:#489e6c'>runtime.spawn[<b><span style='color:#5aba84'>1</span></b></span><span style='color:#489e6c'>]{kind=task, task.name=, task.id=18, loc.file="examples/tokio-task.rs", loc.line=14, loc.col=5}</span> <span style='color:#ba5a57'>runtime.resource[<b><span style='color:#df5853'>274877906945</span></b></span><span style='color:#ba5a57'>]{concrete_type="Sleep", kind="timer", loc.file="examples/tokio-task.rs", loc.line=15, loc.col=9}</span> <b><u><span style='color:#df5853'>new</span></u></b>
62//! <span style='opacity:0.67'><b><span style='color:#aaa'>2023-11-28</span></b></span><span style='opacity:0.67'>T<b><span style='color:#aaa'>10:06:44</span></b></span><span style='opacity:0.67'>.747539Z</span> <span style='color:#9d4edd'>TRACE</span> <span style='color:#489e6c'>runtime.spawn[<b><span style='color:#5aba84'>1</span></b></span><span style='color:#489e6c'>]{kind=task, task.name=, task.id=18, loc.file="examples/tokio-task.rs", loc.line=14, loc.col=5}</span> <span style='color:#ba5a57'>runtime.resource[<b><span style='color:#df5853'>274877906945</span></b></span><span style='color:#ba5a57'>]{concrete_type="Sleep", kind="timer", loc.file="examples/tokio-task.rs", loc.line=15, loc.col=9}</span> <b><u><span style='color:#df5853'>enter</span></u></b>
63//! <span style='opacity:0.67'><b><span style='color:#aaa'>2023-11-28</span></b></span><span style='opacity:0.67'>T<b><span style='color:#aaa'>10:06:44</span></b></span><span style='opacity:0.67'>.747683Z</span> <span style='color:#9d4edd'>TRACE</span> <span style='color:#489e6c'>runtime.spawn[<b><span style='color:#5aba84'>1</span></b></span><span style='color:#489e6c'>]{kind=task, task.name=, task.id=18, loc.file="examples/tokio-task.rs", loc.line=14, loc.col=5}</span> <span style='color:#ba5a57'>runtime.resource[<b><span style='color:#df5853'>274877906945</span></b></span><span style='color:#ba5a57'>]{concrete_type="Sleep", kind="timer", loc.file="examples/tokio-task.rs", loc.line=15, loc.col=9}</span> <b><span style='color:#ff4d6d'>runtime::resource::state_update</span></b>: <span style='color:#c9184a'>duration=101, duration.unit="ms", duration.op="override"</span>
64//! <span style='opacity:0.67'><b><span style='color:#aaa'>2023-11-28</span></b></span><span style='opacity:0.67'>T<b><span style='color:#aaa'>10:06:44</span></b></span><span style='opacity:0.67'>.747854Z</span> <span style='color:#9d4edd'>TRACE</span> <span style='color:#489e6c'>runtime.spawn[<b><span style='color:#5aba84'>1</span></b></span><span style='color:#489e6c'>]{kind=task, task.name=, task.id=18, loc.file="examples/tokio-task.rs", loc.line=14, loc.col=5}</span> <span style='color:#ba5a57'>runtime.resource[<b><span style='color:#df5853'>274877906945</span></b></span><span style='color:#ba5a57'>]{concrete_type="Sleep", kind="timer", loc.file="examples/tokio-task.rs", loc.line=15, loc.col=9}</span> <span style='color:#5c8dce'>runtime.resource.async_op[<b><span style='color:#508ee3'>274877906946</span></b></span><span style='color:#5c8dce'>]{source="Sleep::new_timeout"}</span> <b><u><span style='color:#508ee3'>new</span></u></b>
65//! <span style='opacity:0.67'><b><span style='color:#aaa'>2023-11-28</span></b></span><span style='opacity:0.67'>T<b><span style='color:#aaa'>10:06:44</span></b></span><span style='opacity:0.67'>.747991Z</span> <span style='color:#9d4edd'>TRACE</span> <span style='color:#489e6c'>runtime.spawn[<b><span style='color:#5aba84'>1</span></b></span><span style='color:#489e6c'>]{kind=task, task.name=, task.id=18, loc.file="examples/tokio-task.rs", loc.line=14, loc.col=5}</span> <span style='color:#ba5a57'>runtime.resource[<b><span style='color:#df5853'>274877906945</span></b></span><span style='color:#ba5a57'>]{concrete_type="Sleep", kind="timer", loc.file="examples/tokio-task.rs", loc.line=15, loc.col=9}</span> <b><u><span style='color:#df5853'>exit</span></u></b>
66//! <span style='opacity:0.67'><b><span style='color:#aaa'>2023-11-28</span></b></span><span style='opacity:0.67'>T<b><span style='color:#aaa'>10:06:44</span></b></span><span style='opacity:0.67'>.748118Z</span> <span style='color:#9d4edd'>TRACE</span> <span style='color:#489e6c'>runtime.spawn[<b><span style='color:#5aba84'>1</span></b></span><span style='color:#489e6c'>]{kind=task, task.name=, task.id=18, loc.file="examples/tokio-task.rs", loc.line=14, loc.col=5}</span> <span style='color:#ba5a57'>runtime.resource[<b><span style='color:#df5853'>274877906945</span></b></span><span style='color:#ba5a57'>]{concrete_type="Sleep", kind="timer", loc.file="examples/tokio-task.rs", loc.line=15, loc.col=9}</span> <span style='color:#5c8dce'>runtime.resource.async_op[<b><span style='color:#508ee3'>274877906946</span></b></span><span style='color:#5c8dce'>]{source="Sleep::new_timeout"}</span> <b><u><span style='color:#508ee3'>enter</span></u></b>
67//! <span style='opacity:0.67'><b><span style='color:#aaa'>2023-11-28</span></b></span><span style='opacity:0.67'>T<b><span style='color:#aaa'>10:06:44</span></b></span><span style='opacity:0.67'>.748196Z</span> <span style='color:#9d4edd'>TRACE</span> <span style='color:#489e6c'>runtime.spawn[<b><span style='color:#5aba84'>1</span></b></span><span style='color:#489e6c'>]{kind=task, task.name=, task.id=18, loc.file="examples/tokio-task.rs", loc.line=14, loc.col=5}</span> <span style='color:#ba5a57'>runtime.resource[<b><span style='color:#df5853'>274877906945</span></b></span><span style='color:#ba5a57'>]{concrete_type="Sleep", kind="timer", loc.file="examples/tokio-task.rs", loc.line=15, loc.col=9}</span> <span style='color:#5c8dce'>runtime.resource.async_op[<b><span style='color:#508ee3'>274877906946</span></b></span><span style='color:#5c8dce'>]{source="Sleep::new_timeout"}</span> <span style='color:#e5e44d'>runtime.resource.async_op.poll[<b><span style='color:#f5f466'>274877906947</span></b></span><span style='color:#e5e44d'>]{}</span> <b><u><span style='color:#f5f466'>new</span></u></b>
68//! </pre>
69//!
70//! ## Comparison with `tracing-subscriber`
71//!
72//! `ari_subscriber` is built on top of `tracing-subscriber` and uses its registry (as do the
73//! majority of `tracing` subscribers). It offers an alternative to the [`fmt::Subscriber`] and
74//! underlying [`fmt::Layer`] in that crate.
75//!
76//! If you are in doubt about which format subscriber to use, pick the one from
77//! `tracing-subscriber`. It is more flexible and without a doubt, much more performant.
78//!
79//! You would only use the `ari_subscriber` format [`Layer`] if you have a specific need to
80//! visualize the tracing instrumentation built into Tokio.
81//!
82//! ## Supported Rust Versions
83//!
84//! `ari_subscriber` is built against the latest stable release. The minimum supported version is
85//! 1.64. The current version of `ari_subscriber` is not guaranteed to build on Rust versions
86//! earlier than the minimum supported version.
87//!
88//! ## License
89//!
90//! This project is licensed under the [MIT license].
91//!
92//! [MIT license]: https://github.com/hds/ari_subscriber/blob/main/LICENSE
93//!
94//! ### Contribution
95//!
96//! Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion
97//! in `ari_subscriber` by you, shall be licensed as MIT, without any additional terms or
98//! conditions.
99//!
100//! [`console-subscriber`]: https://docs.rs/console-subscriber/latest/console_subscriber/
101//! [`tracing-subscriber`]: tracing_subscriber
102//! [`fmt::Layer`]: struct@tracing_subscriber::fmt::Layer
103//! [`fmt::Subscriber`]: struct@tracing_subscriber::fmt::Subscriber
104#![deny(rustdoc::missing_crate_level_docs, missing_docs)]
105
106pub(crate) mod fmt;
107mod layer;
108
109pub use layer::{layer, Layer};