Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: better docs on async usage; fancy warning formatting, etc #769

Merged
merged 9 commits into from
Jun 29, 2020
54 changes: 34 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,20 @@ idiomatic `tracing`.)

In order to record trace events, executables have to use a `Subscriber`
implementation compatible with `tracing`. A `Subscriber` implements a way of
collecting trace data, such as by logging it to standard output. [`tracing_subscriber`](https://docs.rs/tracing-subscriber/)'s
[`fmt` module](https://docs.rs/tracing-subscriber/0.2.6/tracing_subscriber/fmt/index.html) provides reasonable defaults.
Additionally, `tracing-subscriber` is able to consume messages emitted by `log`-instrumented libraries and modules.
collecting trace data, such as by logging it to standard output.
[`tracing_subscriber`]'s [`fmt` module][fmt] provides a subscriber for logging
traces with reasonable defaults. Additionally, `tracing-subscriber` is able to
consume messages emitted by `log`-instrumented libraries and modules.

The simplest way to use a subscriber is to call the `set_global_default` function.
To use `tracing-subscriber`, add the following to your `Cargo.toml`:

```toml
[dependencies]
tracing = "0.1"
tracing-subscriber = "0.2"
```

To set a global subscriber for the entire program, use the `set_global_default` function:

```rust
use tracing::{info, Level};
Expand All @@ -57,8 +66,11 @@ fn main() {
// all spans/events with a level higher than TRACE (e.g, debug, info, warn, etc.)
// will be written to stdout.
.with_max_level(Level::TRACE)
// completes the builder and sets the constructed `Subscriber` as the default.
.init();
// completes the builder
.finish();
// and sets the constructed `Subscriber` as the default.
tracing::subscriber::set_global_default(subscriber)
.expect("no global subscriber has been set")

let number_of_yaks = 3;
// this creates a new event, outside of any spans.
Expand All @@ -72,11 +84,9 @@ fn main() {
}
```

```toml
[dependencies]
tracing = "0.1"
tracing-subscriber = "0.2.6"
```
[`tracing-subscriber`]: https://docs.rs/tracing-subscriber/
[fmt]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/fmt/index.html
[`set_global_default`]: https://docs.rs/tracing/latest/tracing/subscriber/fn.set_global_default.html

This subscriber will be used as the default in all threads for the remainder of the duration
of the program, similar to how loggers work in the `log` crate.
Expand Down Expand Up @@ -186,10 +196,9 @@ conflicts when executables try to set the default later.
### In Asynchronous Code

If you are instrumenting code that make use of
[`std::future::Future`](https://doc.rust-lang.org/stable/std/future/trait.Future.html)
or async/await, be sure to use the
[`tracing-futures`](https://docs.rs/tracing-futures) crate. This is needed
because the following example _will not_ work:
[`std::future::Future`][std-future] or async/await, be sure to use the
[`tracing-futures`] crate. This is needed because the following example _will
not_ work:

```rust
async {
Expand All @@ -202,10 +211,10 @@ The span guard `_s` will not exit until the future generated by the `async` bloc
Since futures and spans can be entered and exited _multiple_ times without them completing,
the span remains entered for as long as the future exists, rather than being entered only when
it is polled, leading to very confusing and incorrect output.
For more details, see [the documentation on closing spans](https://tracing.rs/tracing/span/index.html#closing-spans).
For more details, see [the documentation on closing spans][closing].

There are two ways to instrument asynchronous code. The first is through the
[`Future::instrument`](https://docs.rs/tracing-futures/0.2.1/tracing_futures/trait.Instrument.html#method.instrument) combinator:
[`Future::instrument`] combinator:

```rust
use tracing_futures::Instrument;
Expand All @@ -222,9 +231,7 @@ my_future
`Future::instrument` attaches a span to the future, ensuring that the span's lifetime
is as long as the future's.

The second, and preferred, option is through the
[`#[instrument]`](https://docs.rs/tracing/0.1.11/tracing/attr.instrument.html)
attribute:
The second, and preferred, option is through the [`#[instrument]`] attribute:

```rust
use tracing::{info, instrument};
Expand All @@ -242,6 +249,13 @@ async fn write(stream: &mut TcpStream) -> io::Result<usize> {
Under the hood, the `#[instrument]` macro performs same the explicit span
attachment that `Future::instrument` does.

[std-future]: https://doc.rust-lang.org/stable/std/future/trait.Future.html
[`tracing-futures`]: https://docs.rs/tracing-futures
[closing]: https://docs.rs/tracing/latest/span/index.html#closing-spans
[`Future::instrument`]: https://docs.rs/tracing-futures/latest/tracing_futures/trait.Instrument.html#method.instrument
[`#[instrument]`]: https://docs.rs/tracing/0.1.11/tracing/attr.instrument.html


## Getting Help

First, see if the answer to your question can be found in the API documentation.
Expand Down
53 changes: 43 additions & 10 deletions tracing-core/src/dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,16 @@
//! // `my_subscriber` is now the default
//! ```
//!
//! **Note**: the thread-local scoped dispatcher (`with_default`) requires the
//! Rust standard library. `no_std` users should use [`set_global_default`]
//! <div class="information">
//! <div class="tooltip ignore" style="">ⓘ<span class="tooltiptext">Note</span></div>
//! </div>
//! <div class="example-wrap" style="display:inline-block">
//! <pre class="ignore" style="white-space:normal;font:inherit;">
//! <strong>Note</strong>:the thread-local scoped dispatcher <code>with_default</code>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the newline after this is showing up in the preview

Screenshot from 2020-06-29 11-56-29

//! requires the Rust standard library. <code>no_std</code> users should use
//! <a href="#fn.set_global_default"><code>set_global_default</code></a>
//! instead.
//! </pre></div>
//!
//! Finally, `tokio` users should note that versions of `tokio` >= 0.1.22
//! support an `experimental-tracing` feature flag. When this flag is enabled,
Expand Down Expand Up @@ -204,8 +211,15 @@ pub struct DefaultGuard(Option<Dispatch>);
/// The default dispatcher is used when creating a new [span] or
/// [`Event`].
///
/// **Note**: This function requires the Rust standard library. `no_std` users
/// should use [`set_global_default`] instead.
/// <div class="information">
/// <div class="tooltip ignore" style="">ⓘ<span class="tooltiptext">Note</span></div>
/// </div>
/// <div class="example-wrap" style="display:inline-block">
/// <pre class="ignore" style="white-space:normal;font:inherit;">
/// <strong>Note</strong>: This function required the Rust standard library.
/// <code>no_std</code> users should use <a href="../fn.set_global_default.html">
/// <code>set_global_default</code></a> instead.
/// </pre></div>
///
/// [span]: ../span/index.html
/// [`Subscriber`]: ../subscriber/trait.Subscriber.html
Expand All @@ -225,8 +239,15 @@ pub fn with_default<T>(dispatcher: &Dispatch, f: impl FnOnce() -> T) -> T {
/// Sets the dispatch as the default dispatch for the duration of the lifetime
/// of the returned DefaultGuard
///
/// **Note**: This function required the Rust standard library. `no_std` users
/// should use [`set_global_default`] instead.
/// <div class="information">
/// <div class="tooltip ignore" style="">ⓘ<span class="tooltiptext">Note</span></div>
/// </div>
/// <div class="example-wrap" style="display:inline-block">
/// <pre class="ignore" style="white-space:normal;font:inherit;">
/// <strong>Note</strong>: This function required the Rust standard library.
/// <code>no_std</code> users should use <a href="../fn.set_global_default.html">
/// <code>set_global_default</code></a> instead.
/// </pre></div>
///
/// [`set_global_default`]: ../fn.set_global_default.html
#[cfg(feature = "std")]
Expand All @@ -246,8 +267,14 @@ pub fn set_default(dispatcher: &Dispatch) -> DefaultGuard {
/// Can only be set once; subsequent attempts to set the global default will fail.
/// Returns `Err` if the global default has already been set.
///
/// Note: Libraries should *NOT* call `set_global_default()`! That will cause conflicts when
/// executables try to set them later.
///
/// <div class="information">
/// <div class="tooltip compile_fail" style="">&#x26a0; &#xfe0f;<span class="tooltiptext">Warning</span></div>
/// </div><div class="example-wrap" style="display:inline-block"><pre class="compile_fail" style="white-space:normal;font:inherit;">
/// <strong>Warning</strong>: In general, libraries should <em>not</em> call
/// <code>set_global_default()</code>! Doing so will cause conflicts when
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the ! here reads a little oddly

Screenshot from 2020-06-29 11-58-38

Copy link
Member Author

@hawkw hawkw Jun 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not specific to the new HTML formatting, I'm pretty sure rustdoc would look the same for any instance of

`some text`!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I figured as much, in this one case I was just saying I thought it looked funny rather than it looks broken.

/// executables that depend on the library try to set the default later.
/// </pre></div>
///
/// [span]: ../span/index.html
/// [`Subscriber`]: ../subscriber/trait.Subscriber.html
Expand Down Expand Up @@ -525,8 +552,14 @@ impl Dispatch {
/// This calls the [`drop_span`] function on the [`Subscriber`] that this
/// `Dispatch` forwards to.
///
/// **Note:** the [`try_close`] function is functionally identical, but
/// returns `true` if the span is now closed.
/// <div class="information">
/// <div class="tooltip compile_fail" style="">&#x26a0; &#xfe0f;<span class="tooltiptext">Warning</span></div>
/// </div>
/// <div class="example-wrap" style="display:inline-block"><pre class="compile_fail" style="white-space:normal;font:inherit;">
/// <strong>Deprecated</strong>: The <a href="#method.try_close"><code>try_close</code></a>
/// method is functionally identical, but returns <code>true</code> if the span is now closed.
/// It should be used instead of this method.
/// </pre>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CSS after this entry gets messed up somehow

Screenshot from 2020-06-29 11-59-24

///
/// [span ID]: ../span/struct.Id.html
/// [`Subscriber`]: ../subscriber/trait.Subscriber.html
Expand Down
37 changes: 30 additions & 7 deletions tracing-core/src/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,15 @@ pub struct Iter {
/// `examples/counters.rs`, which demonstrates a very simple metrics system
/// implemented using `tracing`.
///
/// **Note:** the `record_error` trait method is only available when the Rust
/// standard library is present, as it requires the `std::error::Error` trait.
/// <div class="information">
/// <div class="tooltip ignore" style="">ⓘ<span class="tooltiptext">Note</span></div>
/// </div>
/// <div class="example-wrap" style="display:inline-block">
/// <pre class="ignore" style="white-space:normal;font:inherit;">
/// <strong>Note</strong>: The <code>record_error</code> trait method is only
/// available when the Rust standard library is present, as it requires the `
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra backtick

Suggested change
/// available when the Rust standard library is present, as it requires the `
/// available when the Rust standard library is present, as it requires the

Screenshot from 2020-06-29 12-00-31

/// <code>std::error::Error</code> trait.
/// </pre></div>
///
/// [`Value`]: trait.Value.html
/// [recorded]: trait.Value.html#method.record
Expand Down Expand Up @@ -202,8 +209,15 @@ pub trait Visit {

/// Records a type implementing `Error`.
///
/// **Note**: this is only enabled when the Rust standard library is
/// <div class="information">
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

something fucky is going on here...

Screenshot from 2020-06-29 12-01-32

/// <div class="tooltip ignore" style="">ⓘ<span class="tooltiptext">Note</span></div>
/// </div>
/// <div class="example-wrap" style="display:inline-block">
/// <div class="example-wrap" style="display:inline-block">
/// <pre class="ignore" style="white-space:normal;font:inherit;">
/// <strong>Note</strong>: This is only enabled when the Rust standard library is
/// present.
/// </pre>
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
fn record_error(&mut self, field: &Field, value: &(dyn std::error::Error + 'static)) {
Expand Down Expand Up @@ -604,11 +618,20 @@ impl FieldSet {

/// Returns `true` if `self` contains the given `field`.
///
/// **Note**: If `field` shares a name with a field in this `FieldSet`, but
/// was created by a `FieldSet` with a different callsite, this `FieldSet`
/// does _not_ contain it. This is so that if two separate span callsites
/// define a field named "foo", the `Field` corresponding to "foo" for each
/// <div class="information">
/// <div class="tooltip ignore" style="">ⓘ<span class="tooltiptext">Note</span></div>
/// </div>
/// <div class="example-wrap" style="display:inline-block">
/// <div class="example-wrap" style="display:inline-block">
/// <pre class="ignore" style="white-space:normal;font:inherit;">
/// <strong>Note</strong>: If <code>field</code> shares a name with a field
/// in this <code>FieldSet</code>, but was created by a <code>FieldSet</code>
/// with a different callsite, this <code>FieldSet</code> does <em>not</em>
/// contain it. This is so that if two separate span callsites define a field
/// named "foo", the <code>Field</code> corresponding to "foo" for each
/// of those callsites are not equivalent.
/// </pre>
/// </div>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

similar formatting bleedthrough

Screenshot from 2020-06-29 12-02-22

pub fn contains(&self, field: &Field) -> bool {
field.callsite() == self.callsite() && field.i <= self.len()
}
Expand Down
15 changes: 11 additions & 4 deletions tracing-core/src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,18 @@ use crate::stdlib::{fmt, str::FromStr};
/// _significantly_ lower than that of creating the actual span. Therefore,
/// filtering is based on metadata, rather than on the constructed span.
///
/// **Note**: Although instances of `Metadata` cannot be compared directly, they
/// provide a method [`id`] which returns an opaque [callsite identifier]
/// which uniquely identifies the callsite where the metadata originated.
/// This can be used for determining if two Metadata correspond to
/// <div class="information">
/// <div class="tooltip ignore" style="">ⓘ<span class="tooltiptext">Note</span></div>
/// </div>
/// <div class="example-wrap" style="display:inline-block">
/// <pre class="ignore" style="white-space:normal;font:inherit;">
/// <strong>Note</strong>: Although instances of <code>Metadata</code> cannot
/// be compared directly, they provide a method <a href="struct.Metadata.html#method.id">
/// <code>id</code></a>, returning an opaque <a href="../callsite/struct.Identifier.html">
/// callsite identifier</a> which uniquely identifies the callsite where the metadata
/// originated. This can be used to determine if two <code>Metadata</code> correspond to
/// the same callsite.
/// </pre></div>
///
/// [span]: ../span/index.html
/// [event]: ../event/index.html
Expand Down
8 changes: 7 additions & 1 deletion tracing-core/src/span.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,13 @@ enum CurrentInner {
impl Id {
/// Constructs a new span ID from the given `u64`.
///
/// **Note**: Span IDs must be greater than zero.
/// <div class="information">
/// <div class="tooltip ignore" style="">ⓘ<span class="tooltiptext">Note</span></div>
/// </div>
/// <div class="example-wrap" style="display:inline-block">
/// <div class="example-wrap" style="display:inline-block">
/// <pre class="ignore" style="white-space:normal;font:inherit;">
/// <strong>Note</strong>: Span IDs must be greater than zero.</pre></div>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

formatting effects need to be scoped here as well

Screenshot from 2020-06-29 12-04-17

///
/// # Panics
/// - If the provided `u64` is 0
Expand Down