-
Notifications
You must be signed in to change notification settings - Fork 791
Improve README for first time users #825
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,10 +33,6 @@ Tokio project, but does _not_ require the `tokio` runtime to be used. | |
|
||
## Usage | ||
|
||
(The examples below are borrowed from the `log` crate's yak-shaving | ||
[example](https://docs.rs/log/0.4.10/log/index.html#examples), modified to | ||
idiomatic `tracing`.) | ||
|
||
### In Applications | ||
|
||
In order to record trace events, executables have to use a `Subscriber` | ||
|
@@ -55,23 +51,15 @@ tracing = "0.1" | |
tracing-subscriber = "0.2" | ||
``` | ||
|
||
To set a global subscriber for the entire program, use the `set_global_default` function: | ||
Then create and install a `Subscriber`, for example using [`init()`]: | ||
|
||
```rust | ||
use tracing::{info, Level}; | ||
use tracing::info; | ||
use tracing_subscriber; | ||
|
||
fn main() { | ||
// a builder for `FmtSubscriber`. | ||
let subscriber = tracing_subscriber::fmt() | ||
// 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 | ||
.finish(); | ||
// and sets the constructed `Subscriber` as the default. | ||
tracing::subscriber::set_global_default(subscriber) | ||
.expect("no global subscriber has been set") | ||
// install global subscriber configured based on RUST_LOG envvar. | ||
tracing_subscriber::init() | ||
|
||
let number_of_yaks = 3; | ||
// this creates a new event, outside of any spans. | ||
|
@@ -85,25 +73,27 @@ fn main() { | |
} | ||
``` | ||
|
||
Using `init()` calls [`set_global_default()`] so 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. | ||
|
||
[tracing-subscriber-docs]: 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. | ||
|
||
In addition, you can locally override the default subscriber. For example: | ||
For more control, a subscriber can be built in stages and not set globally, | ||
but instead used to locally override the default subscriber. For example: | ||
|
||
```rust | ||
use tracing::{info, Level}; | ||
use tracing_subscriber; | ||
|
||
fn main() { | ||
let subscriber = tracing_subscriber::fmt() | ||
// all spans/events with a level higher than TRACE (e.g, debug, info, warn, etc.) | ||
// will be written to stdout. | ||
// filter spans/events with level TRACE or higher. | ||
.with_max_level(Level::TRACE) | ||
// builds the subscriber. | ||
// build but do not install the subscriber. | ||
.finish(); | ||
|
||
tracing::subscriber::with_default(subscriber, || { | ||
|
@@ -122,6 +112,11 @@ currently executing thread; other threads will not see the change from with_defa | |
Once a subscriber has been set, instrumentation points may be added to the | ||
executable using the `tracing` crate's macros. | ||
|
||
[`tracing-subscriber`]: https://docs.rs/tracing-subscriber/ | ||
[fmt]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/fmt/index.html | ||
[`init()`]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/fmt/fn.init.html | ||
[`set_global_default()`]: https://docs.rs/tracing/latest/tracing/subscriber/fn.set_global_default.html | ||
|
||
### In Libraries | ||
|
||
Libraries should only rely on the `tracing` crate and use the provided macros | ||
|
@@ -191,14 +186,32 @@ pub fn shave_all(yaks: usize) -> usize { | |
tracing = "0.1" | ||
``` | ||
|
||
Note: Libraries should *NOT* call `set_global_default()`, as this will cause | ||
conflicts when executables try to set the default later. | ||
Note: Libraries should *NOT* install a subscriber by using a method than calls | ||
[`set_global_default()`], as this will cause conflicts when executables try to | ||
set the default later. | ||
|
||
### In Asynchronous Code | ||
|
||
If you are instrumenting code that make use of | ||
[`std::future::Future`][std-future] or async/await, be sure to use the | ||
[tracing-futures][tracing-futures-docs] crate. This is needed because the | ||
To trace `async fn`s, the preferred method is using the [`#[instrument]`] attribute: | ||
|
||
```rust | ||
use tracing::{info, instrument}; | ||
use tokio::{io::AsyncWriteExt, net::TcpStream}; | ||
use std::io; | ||
|
||
#[instrument] | ||
async fn write(stream: &mut TcpStream) -> io::Result<usize> { | ||
let result = stream.write(b"hello world\n").await; | ||
info!("wrote to stream; success={:?}", result.is_ok()); | ||
result | ||
} | ||
``` | ||
|
||
The [`tracing-futures`] crate must be specified as a dependency to enable | ||
`async` support. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And then maybe put the example with the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was an awkward join between the examples still. I've reworked the language here but left the motivation in the middle, as it helps understand the combinator (though you can arrive here without really having taken in what a span is yet). |
||
Special handling is needed for the general case of code using | ||
[`std::future::Future`][std-future] or blocks with `async`/`await`, as the | ||
following example _will not_ work: | ||
|
||
```rust | ||
|
@@ -214,8 +227,7 @@ the span remains entered for as long as the future exists, rather than being ent | |
it is polled, leading to very confusing and incorrect output. | ||
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`] combinator: | ||
This problem can be solved using the [`Future::instrument`] combinator: | ||
|
||
```rust | ||
use tracing_futures::Instrument; | ||
|
@@ -232,21 +244,6 @@ 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]`][instrument] attribute: | ||
|
||
```rust | ||
use tracing::{info, instrument}; | ||
use tokio::{io::AsyncWriteExt, net::TcpStream}; | ||
use std::io; | ||
|
||
#[instrument] | ||
async fn write(stream: &mut TcpStream) -> io::Result<usize> { | ||
let result = stream.write(b"hello world\n").await; | ||
info!("wrote to stream; success={:?}", result.is_ok()); | ||
result | ||
} | ||
``` | ||
|
||
Under the hood, the `#[instrument]` macro performs same the explicit span | ||
attachment that `Future::instrument` does. | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.