Skip to content

Commit

Permalink
attributes: improve docs; tests for using Levels in #[instrument] (#…
Browse files Browse the repository at this point in the history
…2350)

This branch adds documentation and tests noting that the `#[instrument]`
macro accepts `tracing::Level` directly. Using `tracing::Level` directly
allows for IDE autocomplete and earlier detection of typos.

The documentation for tracing-attributes was also rewritten to remove
the usage of the second-person perspective, making it more consistent
with the rest of tracing's documentation.

Co-authored-by: David Barsky <[email protected]>
; Conflicts:
;	tracing-attributes/Cargo.toml
;	tracing-attributes/src/lib.rs
  • Loading branch information
jsgf authored and hawkw committed Apr 21, 2023
1 parent 89d0ca8 commit b38122d
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 57 deletions.
2 changes: 1 addition & 1 deletion tracing-attributes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ quote = "1"
tracing = { path = "../tracing", version = "0.1.35" }
tracing-mock = { path = "../tracing-mock", features = ["tokio-test"] }
tracing-subscriber = { path = "../tracing-subscriber", version = "0.3.0", features = ["env-filter"] }
tokio-test = { version = "0.3.0" }
tokio-test = "0.4.2"
tracing-core = { path = "../tracing-core", version = "0.1.28"}
async-trait = "0.1.56"
trybuild = "1.0.64"
Expand Down
65 changes: 24 additions & 41 deletions tracing-attributes/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
//!
//! ## Usage
//!
//! First, add this to your `Cargo.toml`:
//! In the `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
Expand All @@ -24,7 +24,7 @@
//! called. For example:
//!
//! ```
//! use tracing_attributes::instrument;
//! use tracing::instrument;
//!
//! #[instrument]
//! pub fn my_function(my_arg: usize) {
Expand Down Expand Up @@ -204,16 +204,17 @@ mod expand;
///
/// # Adding Fields
///
/// Additional fields (key-value pairs with arbitrary data) may be added to the
/// generated span using the `fields` argument on the `#[instrument]` macro. Any
/// Additional fields (key-value pairs with arbitrary data) can be passed to
/// to the generated span through the `fields` argument on the
/// `#[instrument]` macro. Strings, integers or boolean literals are accepted values
/// for each field. The name of the field must be a single valid Rust
/// identifier, nested (dotted) field names are not supported. Any
/// Rust expression can be used as a field value in this manner. These
/// expressions will be evaluated at the beginning of the function's body, so
/// arguments to the function may be used in these expressions. Field names may
/// also be specified *without* values. Doing so will result in an [empty field]
/// whose value may be recorded later within the function body.
///
/// This supports the same [field syntax] as the `span!` and `event!` macros.
///
/// Note that overlap between the names of fields and (non-skipped) arguments
/// will result in a compile error.
///
Expand Down Expand Up @@ -323,11 +324,15 @@ mod expand;
/// Setting the level for the generated span:
/// ```
/// # use tracing_attributes::instrument;
/// #[instrument(level = "debug")]
/// # use tracing::Level;
/// #[instrument(level = Level::DEBUG)]
/// pub fn my_function() {
/// // ...
/// }
/// ```
/// Levels can be specified either with [`Level`] constants, literal strings
/// (e.g., `"debug"`, `"info"`) or numerically (1—5, corresponding to [`Level::TRACE`]—[`Level::ERROR`]).
///
/// Overriding the generated span's name:
/// ```
/// # use tracing_attributes::instrument;
Expand Down Expand Up @@ -398,7 +403,7 @@ mod expand;
/// }
/// ```
///
/// To add an additional context to the span, pass key-value pairs to `fields`:
/// To add additional context to the span, pass key-value pairs to `fields`:
///
/// ```
/// # use tracing_attributes::instrument;
Expand Down Expand Up @@ -426,7 +431,8 @@ mod expand;
///
/// ```
/// # use tracing_attributes::instrument;
/// #[instrument(ret(level = "warn"))]
/// # use tracing::Level;
/// #[instrument(ret(level = Level::WARN))]
/// fn my_function() -> i32 {
/// 42
/// }
Expand All @@ -447,8 +453,8 @@ mod expand;
/// }
/// ```
///
/// If the function returns a `Result<T, E>` and `E` implements `std::fmt::Display`, you can add
/// `err` or `err(Display)` to emit error events when the function returns `Err`:
/// If the function returns a `Result<T, E>` and `E` implements `std::fmt::Display`, adding
/// `err` or `err(Display)` will emit error events when the function returns `Err`:
///
/// ```
/// # use tracing_attributes::instrument;
Expand All @@ -458,19 +464,20 @@ mod expand;
/// }
/// ```
///
/// Similarly, you can override the level of the `err` event:
/// Similarly, overriding the level of the `err` event :
///
/// ```
/// # use tracing_attributes::instrument;
/// #[instrument(err(level = "info"))]
/// # use tracing::Level;
/// #[instrument(err(level = Level::INFO))]
/// fn my_function(arg: usize) -> Result<(), std::io::Error> {
/// Ok(())
/// }
/// ```
///
/// By default, error values will be recorded using their `std::fmt::Display` implementations.
/// If an error implements `std::fmt::Debug`, it can be recorded using its `Debug` implementation
/// instead, by writing `err(Debug)`:
/// instead by writing `err(Debug)`:
///
/// ```
/// # use tracing_attributes::instrument;
Expand Down Expand Up @@ -529,33 +536,6 @@ mod expand;
/// }
/// ```
///
/// Note than on `async-trait` <= 0.1.43, references to the `Self`
/// type inside the `fields` argument were only allowed when the instrumented
/// function is a method (i.e., the function receives `self` as an argument).
/// For example, this *used to not work* because the instrument function
/// didn't receive `self`:
/// ```
/// # use tracing::instrument;
/// use async_trait::async_trait;
///
/// #[async_trait]
/// pub trait Bar {
/// async fn bar();
/// }
///
/// #[derive(Debug)]
/// struct BarImpl(usize);
///
/// #[async_trait]
/// impl Bar for BarImpl {
/// #[instrument(fields(tmp = std::any::type_name::<Self>()))]
/// async fn bar() {}
/// }
/// ```
/// Instead, you should manually rewrite any `Self` types as the type for
/// which you implement the trait: `#[instrument(fields(tmp = std::any::type_name::<Bar>()))]`
/// (or maybe you can just bump `async-trait`).
///
/// [span]: https://docs.rs/tracing/latest/tracing/span/index.html
/// [name]: https://docs.rs/tracing/latest/tracing/struct.Metadata.html#method.name
/// [target]: https://docs.rs/tracing/latest/tracing/struct.Metadata.html#method.target
Expand All @@ -567,6 +547,9 @@ mod expand;
/// [`follows_from`]: https://docs.rs/tracing/latest/tracing/struct.Span.html#method.follows_from
/// [`tracing`]: https://github.com/tokio-rs/tracing
/// [`fmt::Debug`]: std::fmt::Debug
/// [`Level`]: https://docs.rs/tracing/latest/tracing/struct.Level.html
/// [`Level::TRACE`]: https://docs.rs/tracing/latest/tracing/struct.Level.html#associatedconstant.TRACE
/// [`Level::ERROR`]: https://docs.rs/tracing/latest/tracing/struct.Level.html#associatedconstant.ERROR
#[proc_macro_attribute]
pub fn instrument(
args: proc_macro::TokenStream,
Expand Down
12 changes: 6 additions & 6 deletions tracing-attributes/tests/err.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,15 +240,15 @@ fn err_info() -> Result<u8, TryFromIntError> {
#[test]
fn test_err_info() {
let span = span::mock().named("err_info");
let (collector, handle) = collector::mock()
let (subscriber, handle) = subscriber::mock()
.new_span(span.clone())
.enter(span.clone())
.event(event::mock().at_level(Level::INFO))
.exit(span.clone())
.drop_span(span)
.done()
.run_with_handle();
with_default(collector, || err_info().ok());
with_default(subscriber, || err_info().ok());
handle.assert_finished();
}

Expand All @@ -260,7 +260,7 @@ fn err_dbg_info() -> Result<u8, TryFromIntError> {
#[test]
fn test_err_dbg_info() {
let span = span::mock().named("err_dbg_info");
let (collector, handle) = collector::mock()
let (subscriber, handle) = subscriber::mock()
.new_span(span.clone())
.enter(span.clone())
.event(
Expand All @@ -277,7 +277,7 @@ fn test_err_dbg_info() {
.drop_span(span)
.done()
.run_with_handle();
with_default(collector, || err_dbg_info().ok());
with_default(subscriber, || err_dbg_info().ok());
handle.assert_finished();
}

Expand All @@ -289,14 +289,14 @@ fn err_warn_info() -> Result<u8, TryFromIntError> {
#[test]
fn test_err_warn_info() {
let span = span::mock().named("err_warn_info").at_level(Level::WARN);
let (collector, handle) = collector::mock()
let (subscriber, handle) = subscriber::mock()
.new_span(span.clone())
.enter(span.clone())
.event(event::mock().at_level(Level::INFO))
.exit(span.clone())
.drop_span(span)
.done()
.run_with_handle();
with_default(collector, || err_warn_info().ok());
with_default(subscriber, || err_warn_info().ok());
handle.assert_finished();
}
2 changes: 1 addition & 1 deletion tracing-attributes/tests/instrument.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ fn override_everything() {
#[instrument(target = "my_target", level = "debug")]
fn my_fn() {}

#[instrument(level = "debug", target = "my_target")]
#[instrument(level = Level::DEBUG, target = "my_target")]
fn my_other_fn() {}

let span = span::mock()
Expand Down
46 changes: 46 additions & 0 deletions tracing-attributes/tests/levels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,49 @@ fn numeric_levels() {

handle.assert_finished();
}

#[test]
fn enum_levels() {
#[instrument(level = Level::TRACE)]
fn trace() {}

#[instrument(level = Level::DEBUG)]
fn debug() {}

#[instrument(level = tracing::Level::INFO)]
fn info() {}

#[instrument(level = Level::WARN)]
fn warn() {}

#[instrument(level = Level::ERROR)]
fn error() {}
let (subscriber, handle) = subscriber::mock()
.new_span(span::mock().named("trace").at_level(Level::TRACE))
.enter(span::mock().named("trace").at_level(Level::TRACE))
.exit(span::mock().named("trace").at_level(Level::TRACE))
.new_span(span::mock().named("debug").at_level(Level::DEBUG))
.enter(span::mock().named("debug").at_level(Level::DEBUG))
.exit(span::mock().named("debug").at_level(Level::DEBUG))
.new_span(span::mock().named("info").at_level(Level::INFO))
.enter(span::mock().named("info").at_level(Level::INFO))
.exit(span::mock().named("info").at_level(Level::INFO))
.new_span(span::mock().named("warn").at_level(Level::WARN))
.enter(span::mock().named("warn").at_level(Level::WARN))
.exit(span::mock().named("warn").at_level(Level::WARN))
.new_span(span::mock().named("error").at_level(Level::ERROR))
.enter(span::mock().named("error").at_level(Level::ERROR))
.exit(span::mock().named("error").at_level(Level::ERROR))
.done()
.run_with_handle();

with_default(subscriber, || {
trace();
debug();
info();
warn();
error();
});

handle.assert_finished();
}
8 changes: 4 additions & 4 deletions tracing-attributes/tests/ret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ fn ret_warn_info() -> i32 {
#[test]
fn test_warn_info() {
let span = span::mock().named("ret_warn_info").at_level(Level::WARN);
let (collector, handle) = collector::mock()
let (subscriber, handle) = subscriber::mock()
.new_span(span.clone())
.enter(span.clone())
.event(
Expand All @@ -275,7 +275,7 @@ fn test_warn_info() {
.done()
.run_with_handle();

with_default(collector, ret_warn_info);
with_default(subscriber, ret_warn_info);
handle.assert_finished();
}

Expand All @@ -287,7 +287,7 @@ fn ret_dbg_warn() -> i32 {
#[test]
fn test_dbg_warn() {
let span = span::mock().named("ret_dbg_warn").at_level(Level::INFO);
let (collector, handle) = collector::mock()
let (subscriber, handle) = subscriber::mock()
.new_span(span.clone())
.enter(span.clone())
.event(
Expand All @@ -300,6 +300,6 @@ fn test_dbg_warn() {
.done()
.run_with_handle();

with_default(collector, ret_dbg_warn);
with_default(subscriber, ret_dbg_warn);
handle.assert_finished();
}
1 change: 1 addition & 0 deletions tracing-core/src/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ pub trait Visit {
/// <strong>Note</strong>: This is only enabled when the Rust standard library is
/// present.
/// </pre>
/// </div>
#[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
3 changes: 1 addition & 2 deletions tracing-flame/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,7 @@
while_true
)]

pub use error::Error;

use error::Error;
use error::Kind;
use once_cell::sync::Lazy;
use std::cell::Cell;
Expand Down
2 changes: 0 additions & 2 deletions tracing-futures/src/executor/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#[cfg(feature = "futures-01")]
mod futures_01;
#[cfg(feature = "futures-01")]
pub use self::futures_01::*;

#[cfg(feature = "futures_preview")]
mod futures_preview;
Expand Down
1 change: 1 addition & 0 deletions tracing/src/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ use crate::Metadata;
/// string comparisons. Thus, if possible, once the key for a field is known, it
/// should be used whenever possible.
/// </pre>
/// </div>
pub trait AsField: crate::sealed::Sealed {
/// Attempts to convert `&self` into a `Field` with the specified `metadata`.
///
Expand Down

0 comments on commit b38122d

Please sign in to comment.