summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEliza Weisman <eliza@buoyant.io>2019-06-24 17:22:05 -0700
committerDavid Barsky <me@davidbarsky.com>2019-06-24 19:22:05 -0500
commit448302c3d460f489db67874bf9817dc4d0f021c7 (patch)
tree1f8a801a6d20d2d48bd391c1e6a9e2a6758cc9cc
parent06c473e62842d257ed275497ce906710ea3f8e19 (diff)
trace: Improve documentation (#1148)
-rw-r--r--tokio-trace/src/lib.rs159
-rw-r--r--tokio-trace/src/macros.rs216
-rw-r--r--tokio-trace/src/span.rs203
-rw-r--r--tokio-trace/tokio-trace-core/src/metadata.rs41
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
}