diff options
author | Eliza Weisman <eliza@buoyant.io> | 2019-06-24 17:22:05 -0700 |
---|---|---|
committer | David Barsky <me@davidbarsky.com> | 2019-06-24 19:22:05 -0500 |
commit | 448302c3d460f489db67874bf9817dc4d0f021c7 (patch) | |
tree | 1f8a801a6d20d2d48bd391c1e6a9e2a6758cc9cc | |
parent | 06c473e62842d257ed275497ce906710ea3f8e19 (diff) |
trace: Improve documentation (#1148)
-rw-r--r-- | tokio-trace/src/lib.rs | 159 | ||||
-rw-r--r-- | tokio-trace/src/macros.rs | 216 | ||||
-rw-r--r-- | tokio-trace/src/span.rs | 203 | ||||
-rw-r--r-- | tokio-trace/tokio-trace-core/src/metadata.rs | 41 |
4 files changed, 404 insertions, 215 deletions
diff --git a/tokio-trace/src/lib.rs b/tokio-trace/src/lib.rs index 82badd31..29c281d8 100644 --- a/tokio-trace/src/lib.rs +++ b/tokio-trace/src/lib.rs @@ -24,12 +24,12 @@ //! //! # Core Concepts //! -//! The core of `tokio-trace`'s API is composed of `Event`s, `Span`s, and -//! `Subscriber`s. We'll cover these in turn. +//! The core of `tokio-trace`'s API is composed of _spans_, _events_ and +//! _subscribers_. We'll cover these in turn. //! -//! ## `Span`s +//! ## Spans //! -//! A [`Span`] represents a _period of time_ during which a program was executing +//! A [`span`] represents a _period of time_ during which a program was executing //! in some context. A thread of execution is said to _enter_ a span when it //! begins executing in that context, and to _exit_ the span when switching to //! another context. The span in which a thread is currently executing is @@ -49,153 +49,7 @@ //! # } //!``` //! -//! The [`in_scope`] method may be used to execute a closure inside a -//! span: -//! -//! ``` -//! # #[macro_use] extern crate tokio_trace; -//! # use tokio_trace::Level; -//! # fn main() { -//! # let span = span!(Level::TRACE, "my_span"); -//! span.in_scope(|| { -//! // perform some more work in the context of `my_span`... -//! }); -//! # } -//!``` -//! -//! Spans form a tree structure — unless it is a root span, all spans have a -//! _parent_, and may have one or more _children_. When a new span is created, -//! the current span becomes the new span's parent. The total execution time of -//! a span consists of the time spent in that span and in the entire subtree -//! represented by its children. Thus, a parent span always lasts for at least -//! as long as the longest-executing span in its subtree. -//! -//! ``` -//! # #[macro_use] extern crate tokio_trace; -//! # use tokio_trace::Level; -//! # fn main() { -//! // this span is considered the "root" of a new trace tree: -//! span!(Level::INFO, "root").in_scope(|| { -//! // since we are now inside "root", this span is considered a child -//! // of "root": -//! span!(Level::DEBUG, "outer_child").in_scope(|| { -//! // this span is a child of "outer_child", which is in turn a -//! // child of "root": -//! span!(Level::TRACE, "inner_child").in_scope(|| { -//! // and so on... -//! }); -//! }); -//! }); -//! # } -//!``` -//! -//! In addition, data may be associated with spans. A span may have _fields_ — -//! a set of key-value pairs describing the state of the program during that -//! span; an optional name, and metadata describing the source code location -//! where the span was originally entered. -//! ``` -//! # #[macro_use] extern crate tokio_trace; -//! # use tokio_trace::Level; -//! # fn main() { -//! // construct a new span with three fields: -//! // - "foo", with a value of 42, -//! // - "bar", with the value "false" -//! // - "baz", with no initial value -//! let my_span = span!(Level::INFO, "my_span", foo = 42, bar = false); -//! -// TODO(#1138): determine a new syntax for uninitialized span fields, and -// re-enable this. -// //! // record a value for the field "baz" declared above: -// //! my_span.record("baz", &"hello world"); -//! # } -//!``` -//! -//! As shorthand, local variables may be used as field values without an -//! assignment, similar to [struct initializers]. For example: -//! ``` -//! # #[macro_use] -//! # extern crate tokio_trace; -//! # use tokio_trace::Level; -//! # fn main() { -//! let user = "ferris"; -//! -//! span!(Level::TRACE, "login", user); -//! // is equivalent to: -//! span!(Level::TRACE, "login", user = user); -//! # } -//!``` -//! -//! The [`field::display`] and [`field::debug`] functions are used to record -//! fields on spans or events using their `fmt::Display` and `fmt::Debug` -//! implementations (rather than as typed data). This may be used in lieu of -//! custom `Value` implementations for complex or user-defined types. -//! -//! In addition, the span and event macros permit the use of the `%` and `?` -//! sigils as shorthand for `field::display` and `field::debug`, respectively. -//! For example: -//! -//! ``` -//! # #[macro_use] -//! # extern crate tokio_trace; -//! # use tokio_trace::{Level, field}; -//! # fn main() { -//! #[derive(Debug)] -//! struct MyStruct { -//! my_field: &'static str, -//! } -//! -//! let my_struct = MyStruct { -//! my_field: "Hello world!" -//! }; -//! -//! span!(Level::TRACE,"my_span", ?my_struct, %my_struct.my_field); -//! // is equivalent to: -//! span!(Level::TRACE, "my_span", my_struct = field::debug(&my_struct), my_struct.my_field = field::display(&my_struct.my_field)); -//! # } -//!``` -//! -//! ### When to use spans -//! -//! As a rule of thumb, spans should be used to represent discrete units of work -//! (e.g., a given request's lifetime in a server) or periods of time spent in a -//! given context (e.g., time spent interacting with an instance of an external -//! system, such as a database). -//! -//! Which scopes in a program correspond to new spans depend somewhat on user -//! intent. For example, consider the case of a loop in a program. Should we -//! construct one span and perform the entire loop inside of that span, like: -//! ```rust -//! # #[macro_use] extern crate tokio_trace; -//! # use tokio_trace::Level; -//! # fn main() { -//! # let n = 1; -//! let span = span!(Level::TRACE, "my_loop"); -//! let _enter = span.enter(); -//! for i in 0..n { -//! # let _ = i; -//! // ... -//! } -//! # } -//! ``` -//! Or, should we create a new span for each iteration of the loop, as in: -//! ```rust -//! # #[macro_use] extern crate tokio_trace; -//! # use tokio_trace::Level; -//! # fn main() { -//! # let n = 1u64; -//! for i in 0..n { -//! let span = span!(Level::TRACE, "my_loop", iteration = i); -//! let _enter = span.enter(); -//! // ... -//! } -//! # } -//! ``` -//! -//! Depending on the circumstances, we might want to do either, or both. For -//! example, if we want to know how long was spent in the loop overall, we would -//! create a single span around the entire loop; whereas if we wanted to know how -//! much time was spent in each individual iteration, we would enter a new span -//! on every iteration. +//! The [`span` module]'s documentation provides further details on how to use spans. //! //! ## Events //! @@ -462,7 +316,8 @@ //! ``` //! //! [`log`]: https://docs.rs/log/0.4.6/log/ -//! [`Span`]: span/struct.Span.html +//! [`span`]: span/index.html +//! [`span` module]: span/index.html //! [`in_scope`]: span/struct.Span.html#method.in_scope //! [`Event`]: struct.Event.html //! [`Subscriber`]: subscriber/trait.Subscriber.html diff --git a/tokio-trace/src/macros.rs b/tokio-trace/src/macros.rs index 80bacc24..44914280 100644 --- a/tokio-trace/src/macros.rs +++ b/tokio-trace/src/macros.rs @@ -2,43 +2,31 @@ /// /// # Examples /// -/// Creating a new span with no fields: +/// Creating a new span: /// ``` -/// # #[macro_use] -/// # extern crate tokio_trace; -/// # use tokio_trace::Level; +/// #[macro_use] +/// extern crate tokio_trace; +/// use tokio_trace::Level; /// # fn main() { /// let span = span!(Level::TRACE, "my span"); -/// span.in_scope(|| { -/// // do work inside the span... -/// }); +/// let _enter = span.enter(); +/// // do work inside the span... /// # } /// ``` /// -/// Creating a span with custom target: -/// ``` -/// # #[macro_use] -/// # extern crate tokio_trace; -/// # use tokio_trace::Level; -/// # fn main() { -/// span!(Level::TRACE, target: "app_span", "my span"); -/// # } -/// ``` -/// -/// # Fields +/// ## Recording Fields /// -/// Creating a span with fields: +/// Span fields are written using the syntax `key = value`. /// ``` -/// # #[macro_use] -/// # extern crate tokio_trace; +/// # #[macro_use] extern crate tokio_trace; /// # use tokio_trace::Level; /// # fn main() { -/// span!(Level::TRACE, "my span", foo = 2, bar = "a string").in_scope(|| { -/// // do work inside the span... -/// }); +/// // construct a new span with two fields: +/// // - "foo", with a value of 42, +/// // - "bar", with the value "false" +/// let my_span = span!(Level::INFO, "my_span", foo = 42, bar = false); /// # } /// ``` -/// /// Note that a trailing comma on the final field is valid: /// ``` /// # #[macro_use] @@ -46,10 +34,10 @@ /// # use tokio_trace::Level; /// # fn main() { /// span!( -/// Level::TRACE, -/// "my span", -/// foo = 2, -/// bar = "a string", +/// Level::INFO, +/// "my_span", +/// foo = 42, +/// bar = false, /// ); /// # } /// ``` @@ -69,7 +57,7 @@ /// # } ///``` /// -/// Field names can include dots: +/// Field names can include dots, but should not be terminated by them: /// ``` /// # #[macro_use] /// # extern crate tokio_trace; @@ -116,7 +104,7 @@ // /// # } // /// ``` // /// -/// The `?` sigil is shorthand for `field::debug`: +/// The `?` sigil is shorthand for [`field::debug`]: /// ``` /// # #[macro_use] /// # extern crate tokio_trace; @@ -132,11 +120,13 @@ /// }; /// /// // `my_struct` will be recorded using its `fmt::Debug` implementation. -/// let my_span = span!(Level::TRACE, "my span", foo = ?my_struct); +/// span!(Level::TRACE, "my span", foo = ?my_struct); +/// // is equivalent to: +/// span!(Level::TRACE, "my span", foo = tokio_trace::field::debug(&my_struct)); /// # } /// ``` /// -/// The `%` character is shorthand for `field::display`: +/// The `%` character is shorthand for [`field::display`]: /// ``` /// # #[macro_use] /// # extern crate tokio_trace; @@ -151,11 +141,13 @@ /// # field: "Hello world!" /// # }; /// // `my_struct.field` will be recorded using its `fmt::Display` implementation. -/// let my_span = span!(Level::TRACE, "my span", foo = %my_struct.field); +/// span!(Level::TRACE, "my span", foo = %my_struct.field); +/// // is equivalent to: +/// span!(Level::TRACE, "my span", foo = tokio_trace::field::display(&my_struct.field)); /// # } /// ``` /// -/// The `display` and `debug` sigils may also be used with local variable shorthand: +/// The `%` and `?` sigils may also be used with local variable shorthand: /// ``` /// # #[macro_use] /// # extern crate tokio_trace; @@ -190,7 +182,76 @@ /// ); /// # } /// ``` +/// +/// ## Setting Span Attributes +/// +/// In addition to the level and name of the span, which are required, the +/// [target] and [parent span] may be overridden. For example: +/// +/// Creating a span with custom target: +/// ``` +/// # #[macro_use] +/// # extern crate tokio_trace; +/// # use tokio_trace::Level; +/// # fn main() { +/// span!(Level::TRACE, target: "app_span", "my span"); +/// # } +/// ``` +/// +/// Creating a span with an explicit parent: +/// ```rust +/// # #[macro_use] extern crate tokio_trace; +/// # use tokio_trace::Level; +/// # fn main() { +/// // Create, but do not enter, a span called "foo". +/// let foo = span!(Level::INFO, "foo"); +/// +/// // Create and enter a span called "bar". +/// let bar = span!(Level::INFO, "bar"); +/// let _enter = bar.enter(); +/// +/// // Although we have currently entered "bar", "baz"'s parent span +/// // will be "foo". +/// let baz = span!(Level::INFO, parent: &foo, "baz"); +/// # } +/// ``` +/// +/// Creating a span _without_ a parent: +/// +///```rust +/// # #[macro_use] extern crate tokio_trace; +/// # use tokio_trace::Level; +/// # fn main() { +/// let foo = span!(Level::INFO, "foo"); +/// let _enter = foo.enter(); +/// +/// // Although we have currently entered "foo", "bar" will be created +/// // as the root of its own trace tree: +/// let bar = span!(Level::INFO, parent: None, "bar"); +/// # } +/// ``` +/// +/// Both the parent and target may be overridden simultaenously: +/// +///```rust +/// # #[macro_use] extern crate tokio_trace; +/// # use tokio_trace::Level; +/// # fn main() { +/// let foo = span!(Level::INFO, "foo"); +// +/// let bar = span!(Level::INFO, target: "bar_events", parent: &foo, "bar"); +/// # } +/// ``` +/// +/// By default, the module path to the current Rust module will be used +/// as the target, and the parent will be [determined contextually]. +/// /// [struct initializers]: https://doc.rust-lang.org/book/ch05-01-defining-structs.html#using-the-field-init-shorthand-when-variables-and-fields-have-the-same-name +/// [target]: struct.Metadata.html#method.target +/// [parent span]: span/struct.Attributes.html#method.parent +/// [determined contextually]: span/struct.Attributes.html#method.is_contextual +/// [`field::debug`]: field/fn.display.html +/// [`field::display`]: field/fn.display.html #[macro_export(local_inner_macros)] macro_rules! span { ($lvl:expr, target: $target:expr, parent: $parent:expr, $name:expr) => { @@ -300,9 +361,26 @@ macro_rules! span { /// Constructs a span at the trace level. /// +/// [Fields] and [attributes] are set using the same syntax as the [`span!`] +/// macro. +/// +/// [attributes]: macro.span.html#setting-span-attributes +/// [Fields]: macro.span.html#recording-fields +/// [`span!`]: macro.span.html +/// /// # Examples /// /// ```rust +/// # #[macro_use] extern crate tokio_trace; +/// # use tokio_trace::Level; +/// # fn main() { +/// trace_span!("my_span"); +/// // is equivalent to: +/// span!(Level::TRACE, "my_span"); +/// # } +/// ``` +/// +/// ```rust /// # #[macro_use] /// # extern crate tokio_trace; /// # fn main() { @@ -362,9 +440,26 @@ macro_rules! trace_span { /// Constructs a span at the debug level. /// +/// [Fields] and [attributes] are set using the same syntax as the [`span!`] +/// macro. +/// +/// [attributes]: macro.span.html#setting-span-attributes +/// [Fields]: macro.span.html#recording-fields +/// [`span!`]: macro.span.html +/// /// # Examples /// /// ```rust +/// # #[macro_use] extern crate tokio_trace; +/// # use tokio_trace::Level; +/// # fn main() { +/// debug_span!("my_span"); +/// // is equivalent to: +/// span!(Level::DEBUG, "my_span"); +/// # } +/// ``` +/// +/// ```rust /// # #[macro_use] /// # extern crate tokio_trace; /// # fn main() { @@ -424,9 +519,26 @@ macro_rules! debug_span { /// Constructs a span at the info level. /// +/// [Fields] and [attributes] are set using the same syntax as the [`span!`] +/// macro. +/// +/// [attributes]: macro.span.html#setting-span-attributes +/// [Fields]: macro.span.html#recording-fields +/// [`span!`]: macro.span.html +/// /// # Examples /// /// ```rust +/// # #[macro_use] extern crate tokio_trace; +/// # use tokio_trace::Level; +/// # fn main() { +/// info_span!("my_span"); +/// // is equivalent to: +/// span!(Level::INFO, "my_span"); +/// # } +/// ``` +/// +/// ```rust /// # #[macro_use] /// # extern crate tokio_trace; /// # fn main() { @@ -486,9 +598,26 @@ macro_rules! info_span { /// Constructs a span at the warn level. /// +/// [Fields] and [attributes] are set using the same syntax as the [`span!`] +/// macro. +/// +/// [attributes]: macro.span.html#setting-span-attributes +/// [Fields]: macro.span.html#recording-fields +/// [`span!`]: macro.span.html +/// /// # Examples /// /// ```rust +/// # #[macro_use] extern crate tokio_trace; +/// # use tokio_trace::Level; +/// # fn main() { +/// info_span!("my_span"); +/// // is equivalent to: +/// span!(Level::INFO, "my_span"); +/// # } +/// ``` +/// +/// ```rust /// # #[macro_use] /// # extern crate tokio_trace; /// # fn main() { @@ -547,9 +676,26 @@ macro_rules! warn_span { } /// Constructs a span at the error level. /// +/// [Fields] and [attributes] are set using the same syntax as the [`span!`] +/// macro. +/// +/// [attributes]: macro.span.html#setting-span-attributes +/// [Fields]: macro.span.html#recording-fields +/// [`span!`]: macro.span.html +/// /// # Examples /// /// ```rust +/// # #[macro_use] extern crate tokio_trace; +/// # use tokio_trace::Level; +/// # fn main() { +/// error_span!("my_span"); +/// // is equivalent to: +/// span!(Level::ERROR, "my_span"); +/// # } +/// ``` +/// +/// ```rust /// # #[macro_use] /// # extern crate tokio_trace; /// # fn main() { diff --git a/tokio-trace/src/span.rs b/tokio-trace/src/span.rs index d1a1e64c..242d30ab 100644 --- a/tokio-trace/src/span.rs +++ b/tokio-trace/src/span.rs @@ -1,6 +1,51 @@ -//! Spans represent periods of time in the execution of a program. +//! Spans represent periods of time in which a program was executing in a +//! particular context. //! -//! # Entering a Span +//! A span consists of [fields], user-defined key-value pairs of arbitrary data +//! that describe the context the span represents, and [metadata], a fixed set +//! of attributes that describe all `tokio-trace` spans and events. Each span is +//! assigned an [`Id` ] by the subscriber that uniquely identifies it in relation +//! to other spans. +//! +//! # Creating Spans +//! +//! Spans are created using the [`span!`] macro. This macro is invoked with a +//! [verbosity level], followed by a set of attributes whose default values +//! the user whishes to override, a string literal providing the span's name, +//! and finally, between zero and 32 fields. +//! +//! For example: +//! ```rust +//! #[macro_use] +//! extern crate tokio_trace; +//! use tokio_trace::Level; +//! +//! # fn main() { +//! /// Construct a new span at the `INFO` level named "my_span", with a single +//! /// field named answer , with the value `42`. +//! let my_span = span!(Level::INFO, "my_span", answer = 42); +//! # } +//! ``` +//! +//! The documentation for the [`span!`] macro provides additional examples of +//! the various options that exist when creating spans. +//! +//! The [`trace_span!`], [`debug_span!`], [`info_span!`], [`warn_span!`], and +//! [`error_span!`] exist as shorthand for constructing spans at various +//! verbosity levels. +//! +//! ## Recording Span Creation +//! +//! The [`Attributes`] type contains data associated with a span, and is +//! provided to the [`Subscriber`] when a new span is created. It contains +//! the span's metadata, the ID of the span's parent if one was explicitly set, +//! and any fields whose values were recorded when the span was constructed. +//! The subscriber may then choose to cache the data for future use, record +//! it in some manner, or discard it completely. +//! +//! # The Span Lifecycle +//! +//! ## Entering a Span //! //! A thread of execution is said to _enter_ a span when it begins executing, //! and _exit_ the span when it switches to another context. Spans may be @@ -13,13 +58,15 @@ //! # use tokio_trace::Level; //! # fn main() { //! let my_var: u64 = 5; -//! let my_span = span!(Level::TRACE, "my_span", my_var = &my_var); +//! let my_span = span!(Level::TRACE, "my_span", my_var); //! //! // `my_span` exists but has not been entered. //! +//! // Enter `my_span`... //! let _enter = my_span.enter(); //! //! // Perform some work inside of the context of `my_span`... +//! // Dropping the `_enter` guard will exit the span. //! # } //!``` //! @@ -44,11 +91,86 @@ //! # } //! ``` //! +//! **Note:** Since entering a span takes `&self`, and `Span`s are `Clone`, +//! `Send`, and `Sync`, it is entirely valid for multiple threads to enter the +//! same span concurrently. //! -//! # The Span Lifecycle +//! ## Span Relationships +//! +//! Spans form a tree structure — unless it is a root span, all spans have a +//! _parent_, and may have one or more _children_. When a new span is created, +//! the current span becomes the new span's parent. The total execution time of +//! a span consists of the time spent in that span and in the entire subtree +//! represented by its children. Thus, a parent span always lasts for at least +//! as long as the longest-executing span in its subtree. +//! +//! ``` +//! # #[macro_use] extern crate tokio_trace; +//! # use tokio_trace::Level; +//! # fn main() { +//! // this span is considered the "root" of a new trace tree: +//! span!(Level::INFO, "root").in_scope(|| { +//! // since we are now inside "root", this span is considered a child +//! // of "root": +//! span!(Level::DEBUG, "outer_child").in_scope(|| { +//! // this span is a child of "outer_child", which is in turn a +//! // child of "root": +//! span!(Level::TRACE, "inner_child").in_scope(|| { +//! // and so on... +//! }); +//! }); +//! // another span created here would also be a child of "root". +//! }); +//! # } +//!``` //! -//! Execution may enter and exit a span multiple times before that -//! span is _closed_. Consider, for example, a future which has an associated +//! In addition, the parent of a span may be explicitly specified in +//! the `span!` macro. For example: +//! +//! ```rust +//! # #[macro_use] extern crate tokio_trace; +//! # use tokio_trace::Level; +//! # fn main() { +//! // Create, but do not enter, a span called "foo". +//! let foo = span!(Level::INFO, "foo"); +//! +//! // Create and enter a span called "bar". +//! let bar = span!(Level::INFO, "bar"); +//! let _enter = bar.enter(); +//! +//! // Although we have currently entered "bar", "baz"'s parent span +//! // will be "foo". +//! let baz = span!(Level::INFO, parent: &foo, "baz"); +//! # } +//! ``` +//! +//! A child span should typically be considered _part_ of its parent. For +//! example, if a subscriber is recording the length of time spent in various +//! spans, it should generally include the time spent in a span's children as +//! part of that span's duration. +//! +//! In addition to having zero or one parent, a span may also _follow from_ any +//! number of other spans. This indicates a causal relationship between the span +//! and the spans that it follows from, but a follower is *not* typically +//! considered part of the duration of the span it follows. Unlike the parent, a +//! span may record that it follows from another span after it is created, using +//! the [`follows_from`] method. +//! +//! As an example, consider a listener task in a server. As the listener accepts +//! incoming connections, it spawns new tasks that handle those connections. We +//! might want to have a span representing the listener, and instrument each +//! spawned handler task with its own span. We would want our instrumentation to +//! record that the handler tasks were spawned as a result of the listener task. +//! However, we might not consider the handler tasks to be _part_ of the time +//! spent in the listener task, so we would not consider those spans children of +//! the listener span. Instead, we would record that the handler tasks follow +//! from the listener, recording the causal relationship but treating the spans +//! as separate durations. +//! +//! ## Closing Spans +//! +//! Execution may enter and exit a span multiple times before that span is +//! _closed_. Consider, for example, a future which has an associated //! span and enters that span every time it is polled: //! ```rust //! # extern crate tokio_trace; @@ -64,10 +186,9 @@ //! type Error = (); //! //! fn poll(&mut self) -> Poll<Self::Item, Self::Error> { -//! self.span.in_scope(|| { -//! // Do actual future work +//! let _enter = self.span.enter(); +//! // Do actual future work... //! # Ok(Async::Ready(())) -//! }) //! } //! } //! ``` @@ -90,7 +211,7 @@ //! this to determine whether or not the span will be entered again. //! //! If there is only a single handle with the capacity to exit a span, dropping -//! that handle "close" the span, since the capacity to enter it no longer +//! that handle "closes" the span, since the capacity to enter it no longer //! exists. For example: //! ``` //! # #[macro_use] extern crate tokio_trace; @@ -117,15 +238,60 @@ //! given ID, then no more handles to the span with that ID exist. The //! subscriber may then treat it as closed. //! -//! # Accessing a Span's Attributes +//! # When to use spans +//! +//! As a rule of thumb, spans should be used to represent discrete units of work +//! (e.g., a given request's lifetime in a server) or periods of time spent in a +//! given context (e.g., time spent interacting with an instance of an external +//! system, such as a database). +//! +//! Which scopes in a program correspond to new spans depend somewhat on user +//! intent. For example, consider the case of a loop in a program. Should we +//! construct one span and perform the entire loop inside of that span, like: +//! +//! ```rust +//! # #[macro_use] extern crate tokio_trace; +//! # use tokio_trace::Level; +//! # fn main() { +//! # let n = 1; +//! let span = span!(Level::TRACE, "my_loop"); +//! let _enter = span.enter(); +//! for i in 0..n { +//! # let _ = i; +//! // ... +//! } +//! # } +//! ``` +//! Or, should we create a new span for each iteration of the loop, as in: +//! ```rust +//! # #[macro_use] extern crate tokio_trace; +//! # use tokio_trace::Level; +//! # fn main() { +//! # let n = 1u64; +//! for i in 0..n { +//! let span = span!(Level::TRACE, "my_loop", iteration = i); +//! let _enter = span.enter(); +//! // ... +//! } +//! # } +//! ``` //! -//! The [`Attributes`] type represents a *non-entering* reference to a `Span`'s data -//! — a set of key-value pairs (known as _fields_), a creation timestamp, -//! a reference to the span's parent in the trace tree, and metadata describing -//! the source code location where the span was created. This data is provided -//! to the [`Subscriber`] when the span is created; it may then choose to cache -//! the data for future use, record it in some manner, or discard it completely. +//! Depending on the circumstances, we might want to do either, or both. For +//! example, if we want to know how long was spent in the loop overall, we would +//! create a single span around the entire loop; whereas if we wanted to know how +//! much time was spent in each individual iteration, we would enter a new span +//! on every iteration. //! +//! [fields]: ../field/index.html +//! [metadata]: ../struct.Metadata.html +//! [`Id`]: struct.Id.html +//! [verbosity level]: ../struct.Level.html +//! [`span!`]: ../macro.span.html +//! [`trace_span!`]: ../macro.trace_span.html +//! [`debug_span!`]: ../macro.debug_span.html +//! [`info_span!`]: ../macro.info_span.html +//! [`warn_span!`]: ../macro.warn_span.html +//! [`error_span!`]: ../macro.error_span.html //! [`clone_span`]: ../subscriber/trait.Subscriber.html#method.clone_span //! [`drop_span`]: ../subscriber/trait.Subscriber.html#method.drop_span //! [`exit`]: ../subscriber/trait.Subscriber.html#tymethod.exit @@ -133,7 +299,8 @@ //! [`Attributes`]: struct.Attributes.html //! [`enter`]: struct.Span.html#method.enter //! [`in_scope`]: struct.Span.html#method.in_scope -//! [`guard`]: struct.Entered.html +//! [`follows_from`]: struct.Span.html#method.follows_from +//! [guard]: struct.Entered.html pub use tokio_trace_core::span::{Attributes, Id, Record}; use std::{ diff --git a/tokio-trace/tokio-trace-core/src/metadata.rs b/tokio-trace/tokio-trace-core/src/metadata.rs index 1c546a7c..545920b1 100644 --- a/tokio-trace/tokio-trace-core/src/metadata.rs +++ b/tokio-trace/tokio-trace-core/src/metadata.rs @@ -7,8 +7,21 @@ use std::fmt; /// Metadata describing a [span] or [event]. /// -/// This includes the source code location where the span occurred, the names of -/// its fields, et cetera. +/// All spans and events have the following metadata: +/// - A [name], represented as a static string. +/// - A [target], a string that categorizes part of the system where the span +/// or event occurred. The `tokio_trace` macros default to using the module +/// path where the span or event originated as the target, but it may be +/// overridden. +/// - A [verbosity level]. +/// - The names of the [fields] defined by the span or event. +/// - Whether the metadata corresponds to a span or event. +/// +/// In addition, the following optional metadata describing the source code +/// location where the span or event originated _may_ be provided: +/// - The [file name] +/// - The [line number] +/// - The [module path] /// /// Metadata is used by [`Subscriber`]s when filtering spans and events, and it /// may also be used as part of their data payload. @@ -20,14 +33,22 @@ use std::fmt; /// filtering is based on metadata, rather than on the constructed span. /// /// **Note**: Although instances of `Metadata` cannot be compared directly, they -/// provide a method [`Metadata::id()`] which returns an an opaque [callsite -/// identifier] which uniquely identifies the callsite where the metadata -/// originated. This can be used for determining if two Metadata correspond to +/// provide a method [`id`] which returns an an opaque [callsite identifier] +/// which uniquely identifies the callsite where the metadata originated. +/// This can be used for determining if two Metadata correspond to /// the same callsite. /// -/// [span]: ../span +/// [span]: ../span/index.html +/// [event]: ../event/index.html +/// [name]: #method.name +/// [target]: #method.target +/// [fields]: #method.fields +/// [verbosity level]: #method.level +/// [file name]: #method.file +/// [line number]: #method.line +/// [module path]: #method.module /// [`Subscriber`]: ../subscriber/trait.Subscriber.html -/// [`Metadata::id()`]: struct.Metadata.html#method.id +/// [`id`]: struct.Metadata.html#method.id /// [callsite identifier]: ../callsite/struct.Identifier.html // TODO: When `const fn` is stable, make this type's fields private. pub struct Metadata<'a> { @@ -136,7 +157,7 @@ pub struct Metadata<'a> { pub kind: Kind, } -/// Indicate whether the callsite is a span or event. +/// Indicates whether the callsite is a span or event. #[derive(Clone, Debug, Eq, PartialEq)] pub struct Kind(KindInner); @@ -175,12 +196,12 @@ impl<'a> Metadata<'a> { } } - /// Returns the set of fields on the described span. + /// Returns the names of the fields on the described span or event. pub fn fields(&self) -> &field::FieldSet { &self.fields } - /// Returns the level of verbosity of the described span. + /// Returns the level of verbosity of the described span or event. pub fn level(&self) -> &Level { &self.level } |