aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-02-08 01:23:34 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-02-08 01:23:34 +0000
commita3c6b48058fc1098048be918cd524a02254950e6 (patch)
tree58e96ae82105644131a8467af870a1b4da4d5751
parentb3adb4dfaf366cd1c67e7710206a8a5a24cabb81 (diff)
parent745770d77e5edb29868c0a058b92105372e6927b (diff)
downloadtracing-core-simpleperf-release.tar.gz
Snap for 11421525 from 745770d77e5edb29868c0a058b92105372e6927b to simpleperf-releasesimpleperf-release
Change-Id: I9e891e82f2b61e3f72a4ab8373e5668b8dd4b0a0
-rw-r--r--.cargo_vcs_info.json6
-rw-r--r--Android.bp35
-rw-r--r--CHANGELOG.md46
-rw-r--r--Cargo.toml12
-rw-r--r--Cargo.toml.orig4
-rw-r--r--METADATA25
-rw-r--r--README.md34
-rw-r--r--src/callsite.rs4
-rw-r--r--src/dispatcher.rs185
-rw-r--r--src/field.rs54
-rw-r--r--src/lib.rs16
-rw-r--r--src/metadata.rs1
-rw-r--r--src/subscriber.rs8
-rw-r--r--tests/local_dispatch_before_init.rs43
14 files changed, 327 insertions, 146 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
new file mode 100644
index 0000000..351e2f9
--- /dev/null
+++ b/.cargo_vcs_info.json
@@ -0,0 +1,6 @@
+{
+ "git": {
+ "sha1": "c4b2a56937dd40aaa2e2991636eca6748353201f"
+ },
+ "path_in_vcs": "tracing-core"
+} \ No newline at end of file
diff --git a/Android.bp b/Android.bp
index 2f39599..dc4e580 100644
--- a/Android.bp
+++ b/Android.bp
@@ -23,7 +23,7 @@ rust_library {
host_supported: true,
crate_name: "tracing_core",
cargo_env_compat: true,
- cargo_pkg_version: "0.1.30",
+ cargo_pkg_version: "0.1.32",
srcs: ["src/lib.rs"],
edition: "2018",
features: [
@@ -46,7 +46,7 @@ rust_test {
host_supported: true,
crate_name: "tracing_core",
cargo_env_compat: true,
- cargo_pkg_version: "0.1.30",
+ cargo_pkg_version: "0.1.32",
srcs: ["src/lib.rs"],
test_suites: ["general-tests"],
auto_gen_config: true,
@@ -68,7 +68,7 @@ rust_test {
host_supported: true,
crate_name: "dispatch",
cargo_env_compat: true,
- cargo_pkg_version: "0.1.30",
+ cargo_pkg_version: "0.1.32",
srcs: ["tests/dispatch.rs"],
test_suites: ["general-tests"],
auto_gen_config: true,
@@ -93,7 +93,7 @@ rust_test {
host_supported: true,
crate_name: "global_dispatch",
cargo_env_compat: true,
- cargo_pkg_version: "0.1.30",
+ cargo_pkg_version: "0.1.32",
srcs: ["tests/global_dispatch.rs"],
test_suites: ["general-tests"],
auto_gen_config: true,
@@ -114,11 +114,36 @@ rust_test {
}
rust_test {
+ name: "tracing-core_test_tests_local_dispatch_before_init",
+ host_supported: true,
+ crate_name: "local_dispatch_before_init",
+ cargo_env_compat: true,
+ cargo_pkg_version: "0.1.32",
+ srcs: ["tests/local_dispatch_before_init.rs"],
+ test_suites: ["general-tests"],
+ auto_gen_config: true,
+ test_options: {
+ unit_test: true,
+ },
+ edition: "2018",
+ features: [
+ "default",
+ "once_cell",
+ "std",
+ "valuable",
+ ],
+ rustlibs: [
+ "libonce_cell",
+ "libtracing_core",
+ ],
+}
+
+rust_test {
name: "tracing-core_test_tests_macros",
host_supported: true,
crate_name: "macros",
cargo_env_compat: true,
- cargo_pkg_version: "0.1.30",
+ cargo_pkg_version: "0.1.32",
srcs: ["tests/macros.rs"],
test_suites: ["general-tests"],
auto_gen_config: true,
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cf0d8e3..2e92f74 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,49 @@
+# 0.1.32 (October 13, 2023)
+
+### Documented
+
+- Fix typo in `field` docs ([#2611])
+- Remove duplicate wording ([#2674])
+
+### Changed
+
+- Allow `ValueSet`s of any length ([#2508])
+
+[#2611]: https://github.com/tokio-rs/tracing/pull/2611
+[#2674]: https://github.com/tokio-rs/tracing/pull/2674
+[#2508]: https://github.com/tokio-rs/tracing/pull/2508
+
+# 0.1.31 (May 11, 2023)
+
+This release of `tracing-core` fixes a bug that caused threads which call
+`dispatcher::get_default` _before_ a global default subscriber is set to never
+see the global default once it is set. In addition, it includes improvements for
+instrumentation performance in some cases, especially when using a global
+default dispatcher.
+
+### Fixed
+
+- Fixed incorrect thread-local caching of `Dispatch::none` if
+ `dispatcher::get_default` is called before `dispatcher::set_global_default`
+ ([#2593])
+
+### Changed
+
+- Cloning a `Dispatch` that points at a global default subscriber no longer
+ requires an `Arc` reference count increment, improving performance
+ substantially ([#2593])
+- `dispatcher::get_default` no longer attempts to access a thread local if the
+ scoped dispatcher is not in use, improving performance when the default
+ dispatcher is global ([#2593])
+- Added `#[inline]` annotations called by the `event!` and `span!` macros to
+ reduce the size of macro-generated code and improve recording performance
+ ([#2555])
+
+Thanks to new contributor @ldm0 for contributing to this release!
+
+[#2593]: https://github.com/tokio-rs/tracing/pull/2593
+[#2555]: https://github.com/tokio-rs/tracing/pull/2555
+
# 0.1.30 (October 6, 2022)
This release of `tracing-core` adds a new `on_register_dispatch` method to the
diff --git a/Cargo.toml b/Cargo.toml
index 8060061..961b391 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,9 +11,9 @@
[package]
edition = "2018"
-rust-version = "1.49.0"
+rust-version = "1.56.0"
name = "tracing-core"
-version = "0.1.30"
+version = "0.1.32"
authors = ["Tokio Contributors <team@tokio.rs>"]
description = """
Core primitives for application-level tracing.
@@ -35,13 +35,13 @@ repository = "https://github.com/tokio-rs/tracing"
[package.metadata.docs.rs]
all-features = true
-rustdoc-args = [
- "--cfg",
- "docsrs",
+rustc-args = [
"--cfg",
"tracing_unstable",
]
-rustc-args = [
+rustdoc-args = [
+ "--cfg",
+ "docsrs",
"--cfg",
"tracing_unstable",
]
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index aacd334..a9ed02f 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -8,7 +8,7 @@ name = "tracing-core"
# - README.md
# - Update CHANGELOG.md.
# - Create "v0.1.x" git tag.
-version = "0.1.30"
+version = "0.1.32"
authors = ["Tokio Contributors <team@tokio.rs>"]
license = "MIT"
readme = "README.md"
@@ -24,7 +24,7 @@ categories = [
]
keywords = ["logging", "tracing", "profiling"]
edition = "2018"
-rust-version = "1.49.0"
+rust-version = "1.56.0"
[features]
default = ["std", "valuable/std"]
diff --git a/METADATA b/METADATA
index 374df14..6993fb6 100644
--- a/METADATA
+++ b/METADATA
@@ -1,19 +1,20 @@
+# This project was upgraded with external_updater.
+# Usage: tools/external_updater/updater.sh update external/rust/crates/tracing-core
+# For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md
+
name: "tracing-core"
description: "Core primitives for application-level tracing."
third_party {
- url {
- type: HOMEPAGE
- value: "https://crates.io/crates/tracing-core"
- }
- url {
- type: ARCHIVE
- value: "https://static.crates.io/crates/tracing-core/tracing-core-0.1.30.crate"
- }
- version: "0.1.30"
license_type: NOTICE
last_upgrade_date {
- year: 2023
- month: 3
- day: 3
+ year: 2024
+ month: 2
+ day: 6
+ }
+ homepage: "https://crates.io/crates/tracing-core"
+ identifier {
+ type: "Archive"
+ value: "https://static.crates.io/crates/tracing-core/tracing-core-0.1.32.crate"
+ version: "0.1.32"
}
}
diff --git a/README.md b/README.md
index f06c760..3655948 100644
--- a/README.md
+++ b/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.30
+[crates-url]: https://crates.io/crates/tracing-core/0.1.31
[docs-badge]: https://docs.rs/tracing-core/badge.svg
-[docs-url]: https://docs.rs/tracing-core/0.1.30
+[docs-url]: https://docs.rs/tracing-core/0.1.31
[docs-master-badge]: https://img.shields.io/badge/docs-master-blue
[docs-master-url]: https://tracing-rs.netlify.com/tracing_core
[mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg
@@ -53,7 +53,7 @@ The crate provides:
In addition, it defines the global callsite registry and per-thread current
dispatcher which other components of the tracing system rely on.
-*Compiler support: [requires `rustc` 1.49+][msrv]*
+*Compiler support: [requires `rustc` 1.56+][msrv]*
[msrv]: #supported-rust-versions
@@ -79,34 +79,34 @@ The following crate feature flags are available:
```toml
[dependencies]
- tracing-core = { version = "0.1.30", default-features = false }
+ tracing-core = { version = "0.1.31", default-features = false }
```
**Note**:`tracing-core`'s `no_std` support requires `liballoc`.
[`tracing`]: ../tracing
-[`span::Id`]: https://docs.rs/tracing-core/0.1.30/tracing_core/span/struct.Id.html
-[`Event`]: https://docs.rs/tracing-core/0.1.30/tracing_core/event/struct.Event.html
-[`Subscriber`]: https://docs.rs/tracing-core/0.1.30/tracing_core/subscriber/trait.Subscriber.html
-[`Metadata`]: https://docs.rs/tracing-core/0.1.30/tracing_core/metadata/struct.Metadata.html
-[`Callsite`]: https://docs.rs/tracing-core/0.1.30/tracing_core/callsite/trait.Callsite.html
-[`Field`]: https://docs.rs/tracing-core/0.1.30/tracing_core/field/struct.Field.html
-[`FieldSet`]: https://docs.rs/tracing-core/0.1.30/tracing_core/field/struct.FieldSet.html
-[`Value`]: https://docs.rs/tracing-core/0.1.30/tracing_core/field/trait.Value.html
-[`ValueSet`]: https://docs.rs/tracing-core/0.1.30/tracing_core/field/struct.ValueSet.html
-[`Dispatch`]: https://docs.rs/tracing-core/0.1.30/tracing_core/dispatcher/struct.Dispatch.html
+[`span::Id`]: https://docs.rs/tracing-core/0.1.31/tracing_core/span/struct.Id.html
+[`Event`]: https://docs.rs/tracing-core/0.1.31/tracing_core/event/struct.Event.html
+[`Subscriber`]: https://docs.rs/tracing-core/0.1.31/tracing_core/subscriber/trait.Subscriber.html
+[`Metadata`]: https://docs.rs/tracing-core/0.1.31/tracing_core/metadata/struct.Metadata.html
+[`Callsite`]: https://docs.rs/tracing-core/0.1.31/tracing_core/callsite/trait.Callsite.html
+[`Field`]: https://docs.rs/tracing-core/0.1.31/tracing_core/field/struct.Field.html
+[`FieldSet`]: https://docs.rs/tracing-core/0.1.31/tracing_core/field/struct.FieldSet.html
+[`Value`]: https://docs.rs/tracing-core/0.1.31/tracing_core/field/trait.Value.html
+[`ValueSet`]: https://docs.rs/tracing-core/0.1.31/tracing_core/field/struct.ValueSet.html
+[`Dispatch`]: https://docs.rs/tracing-core/0.1.31/tracing_core/dispatcher/struct.Dispatch.html
## Supported Rust Versions
Tracing is built against the latest stable release. The minimum supported
-version is 1.49. The current Tracing version is not guaranteed to build on Rust
+version is 1.56. 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
project. The current stable Rust compiler and the three most recent minor
versions before it will always be supported. For example, if the current stable
-compiler version is 1.45, the minimum supported version will not be increased
-past 1.42, three minor versions prior. Increasing the minimum supported compiler
+compiler version is 1.69, the minimum supported version will not be increased
+past 1.69, three minor versions prior. Increasing the minimum supported compiler
version is not considered a semver breaking change as long as doing so complies
with this policy.
diff --git a/src/callsite.rs b/src/callsite.rs
index f887132..62fa8c4 100644
--- a/src/callsite.rs
+++ b/src/callsite.rs
@@ -9,9 +9,7 @@
//! * Storing the span or event's [`Metadata`],
//! * Uniquely [identifying](Identifier) the span or event definition,
//! * Caching the subscriber's [`Interest`][^1] in that span or event, to avoid
-//! re-evaluating filters,
-//! * Storing a [`Registration`] that allows the callsite to be part of a global
-//! list of all callsites in the program.
+//! re-evaluating filters.
//!
//! # Registering Callsites
//!
diff --git a/src/dispatcher.rs b/src/dispatcher.rs
index 36b3cfd..de02afb 100644
--- a/src/dispatcher.rs
+++ b/src/dispatcher.rs
@@ -140,7 +140,7 @@ use crate::stdlib::{
#[cfg(feature = "std")]
use crate::stdlib::{
- cell::{Cell, RefCell, RefMut},
+ cell::{Cell, Ref, RefCell},
error,
};
@@ -153,7 +153,7 @@ use core::ops::Deref;
/// `Dispatch` trace data to a [`Subscriber`].
#[derive(Clone)]
pub struct Dispatch {
- subscriber: Arc<dyn Subscriber + Send + Sync>,
+ subscriber: Kind<Arc<dyn Subscriber + Send + Sync>>,
}
/// `WeakDispatch` is a version of [`Dispatch`] that holds a non-owning reference
@@ -176,13 +176,12 @@ pub struct Dispatch {
/// [here]: Subscriber#avoiding-memory-leaks
#[derive(Clone)]
pub struct WeakDispatch {
- subscriber: Weak<dyn Subscriber + Send + Sync>,
+ subscriber: Kind<Weak<dyn Subscriber + Send + Sync>>,
}
-#[cfg(feature = "alloc")]
#[derive(Clone)]
enum Kind<T> {
- Global(&'static (dyn Collect + Send + Sync)),
+ Global(&'static (dyn Subscriber + Send + Sync)),
Scoped(T),
}
@@ -197,11 +196,20 @@ thread_local! {
static EXISTS: AtomicBool = AtomicBool::new(false);
static GLOBAL_INIT: AtomicUsize = AtomicUsize::new(UNINITIALIZED);
+#[cfg(feature = "std")]
+static SCOPED_COUNT: AtomicUsize = AtomicUsize::new(0);
+
const UNINITIALIZED: usize = 0;
const INITIALIZING: usize = 1;
const INITIALIZED: usize = 2;
-static mut GLOBAL_DISPATCH: Option<Dispatch> = None;
+static mut GLOBAL_DISPATCH: Dispatch = Dispatch {
+ subscriber: Kind::Global(&NO_SUBSCRIBER),
+};
+static NONE: Dispatch = Dispatch {
+ subscriber: Kind::Global(&NO_SUBSCRIBER),
+};
+static NO_SUBSCRIBER: NoSubscriber = NoSubscriber::new();
/// The dispatch state of a thread.
#[cfg(feature = "std")]
@@ -305,8 +313,20 @@ pub fn set_global_default(dispatcher: Dispatch) -> Result<(), SetGlobalDefaultEr
)
.is_ok()
{
+ let subscriber = {
+ let subscriber = match dispatcher.subscriber {
+ Kind::Global(s) => s,
+ Kind::Scoped(s) => unsafe {
+ // safety: this leaks the subscriber onto the heap. the
+ // reference count will always be at least 1, because the
+ // global default will never be dropped.
+ &*Arc::into_raw(s)
+ },
+ };
+ Kind::Global(subscriber)
+ };
unsafe {
- GLOBAL_DISPATCH = Some(dispatcher);
+ GLOBAL_DISPATCH = Dispatch { subscriber };
}
GLOBAL_INIT.store(INITIALIZED, Ordering::SeqCst);
EXISTS.store(true, Ordering::Release);
@@ -365,15 +385,21 @@ pub fn get_default<T, F>(mut f: F) -> T
where
F: FnMut(&Dispatch) -> T,
{
+ if SCOPED_COUNT.load(Ordering::Acquire) == 0 {
+ // fast path if no scoped dispatcher has been set; just use the global
+ // default.
+ return f(get_global());
+ }
+
CURRENT_STATE
.try_with(|state| {
if let Some(entered) = state.enter() {
- return f(&*entered.current());
+ return f(&entered.current());
}
- f(&Dispatch::none())
+ f(&NONE)
})
- .unwrap_or_else(|_| f(&Dispatch::none()))
+ .unwrap_or_else(|_| f(&NONE))
}
/// Executes a closure with a reference to this thread's current [dispatcher].
@@ -387,10 +413,16 @@ where
#[doc(hidden)]
#[inline(never)]
pub fn get_current<T>(f: impl FnOnce(&Dispatch) -> T) -> Option<T> {
+ if SCOPED_COUNT.load(Ordering::Acquire) == 0 {
+ // fast path if no scoped dispatcher has been set; just use the global
+ // default.
+ return Some(f(get_global()));
+ }
+
CURRENT_STATE
.try_with(|state| {
let entered = state.enter()?;
- Some(f(&*entered.current()))
+ Some(f(&entered.current()))
})
.ok()?
}
@@ -401,8 +433,7 @@ pub fn get_current<T>(f: impl FnOnce(&Dispatch) -> T) -> Option<T> {
#[cfg(not(feature = "std"))]
#[doc(hidden)]
pub fn get_current<T>(f: impl FnOnce(&Dispatch) -> T) -> Option<T> {
- let dispatch = get_global()?;
- Some(f(&dispatch))
+ Some(f(get_global()))
}
/// Executes a closure with a reference to the current [dispatcher].
@@ -413,35 +444,30 @@ pub fn get_default<T, F>(mut f: F) -> T
where
F: FnMut(&Dispatch) -> T,
{
- if let Some(d) = get_global() {
- f(d)
- } else {
- f(&Dispatch::none())
- }
+ f(&get_global())
}
-fn get_global() -> Option<&'static Dispatch> {
+#[inline]
+fn get_global() -> &'static Dispatch {
if GLOBAL_INIT.load(Ordering::SeqCst) != INITIALIZED {
- return None;
+ return &NONE;
}
unsafe {
// This is safe given the invariant that setting the global dispatcher
// also sets `GLOBAL_INIT` to `INITIALIZED`.
- Some(GLOBAL_DISPATCH.as_ref().expect(
- "invariant violated: GLOBAL_DISPATCH must be initialized before GLOBAL_INIT is set",
- ))
+ &GLOBAL_DISPATCH
}
}
#[cfg(feature = "std")]
-pub(crate) struct Registrar(Weak<dyn Subscriber + Send + Sync>);
+pub(crate) struct Registrar(Kind<Weak<dyn Subscriber + Send + Sync>>);
impl Dispatch {
/// Returns a new `Dispatch` that discards events and spans.
#[inline]
pub fn none() -> Self {
Dispatch {
- subscriber: Arc::new(NoSubscriber::default()),
+ subscriber: Kind::Global(&NO_SUBSCRIBER),
}
}
@@ -453,7 +479,7 @@ impl Dispatch {
S: Subscriber + Send + Sync + 'static,
{
let me = Dispatch {
- subscriber: Arc::new(subscriber),
+ subscriber: Kind::Scoped(Arc::new(subscriber)),
};
callsite::register_dispatch(&me);
me
@@ -461,7 +487,7 @@ impl Dispatch {
#[cfg(feature = "std")]
pub(crate) fn registrar(&self) -> Registrar {
- Registrar(Arc::downgrade(&self.subscriber))
+ Registrar(self.subscriber.downgrade())
}
/// Creates a [`WeakDispatch`] from this `Dispatch`.
@@ -480,18 +506,20 @@ impl Dispatch {
/// [here]: Subscriber#avoiding-memory-leaks
pub fn downgrade(&self) -> WeakDispatch {
WeakDispatch {
- subscriber: Arc::downgrade(&self.subscriber),
+ subscriber: self.subscriber.downgrade(),
}
}
#[inline(always)]
- #[cfg(not(feature = "alloc"))]
pub(crate) fn subscriber(&self) -> &(dyn Subscriber + Send + Sync) {
- &self.subscriber
+ match self.subscriber {
+ Kind::Global(s) => s,
+ Kind::Scoped(ref s) => s.as_ref(),
+ }
}
- /// Registers a new callsite with this collector, returning whether or not
- /// the collector is interested in being notified about the callsite.
+ /// Registers a new callsite with this subscriber, returning whether or not
+ /// the subscriber is interested in being notified about the callsite.
///
/// This calls the [`register_callsite`] function on the [`Subscriber`]
/// that this `Dispatch` forwards to.
@@ -500,7 +528,7 @@ impl Dispatch {
/// [`register_callsite`]: super::subscriber::Subscriber::register_callsite
#[inline]
pub fn register_callsite(&self, metadata: &'static Metadata<'static>) -> subscriber::Interest {
- self.subscriber.register_callsite(metadata)
+ self.subscriber().register_callsite(metadata)
}
/// Returns the highest [verbosity level][level] that this [`Subscriber`] will
@@ -516,7 +544,7 @@ impl Dispatch {
// TODO(eliza): consider making this a public API?
#[inline]
pub(crate) fn max_level_hint(&self) -> Option<LevelFilter> {
- self.subscriber.max_level_hint()
+ self.subscriber().max_level_hint()
}
/// Record the construction of a new span, returning a new [ID] for the
@@ -530,7 +558,7 @@ impl Dispatch {
/// [`new_span`]: super::subscriber::Subscriber::new_span
#[inline]
pub fn new_span(&self, span: &span::Attributes<'_>) -> span::Id {
- self.subscriber.new_span(span)
+ self.subscriber().new_span(span)
}
/// Record a set of values on a span.
@@ -542,7 +570,7 @@ impl Dispatch {
/// [`record`]: super::subscriber::Subscriber::record
#[inline]
pub fn record(&self, span: &span::Id, values: &span::Record<'_>) {
- self.subscriber.record(span, values)
+ self.subscriber().record(span, values)
}
/// Adds an indication that `span` follows from the span with the id
@@ -555,7 +583,7 @@ impl Dispatch {
/// [`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)
+ self.subscriber().record_follows_from(span, follows)
}
/// Returns true if a span with the specified [metadata] would be
@@ -569,7 +597,7 @@ impl Dispatch {
/// [`enabled`]: super::subscriber::Subscriber::enabled
#[inline]
pub fn enabled(&self, metadata: &Metadata<'_>) -> bool {
- self.subscriber.enabled(metadata)
+ self.subscriber().enabled(metadata)
}
/// Records that an [`Event`] has occurred.
@@ -582,8 +610,9 @@ impl Dispatch {
/// [`event`]: super::subscriber::Subscriber::event
#[inline]
pub fn event(&self, event: &Event<'_>) {
- if self.subscriber.event_enabled(event) {
- self.subscriber.event(event);
+ let subscriber = self.subscriber();
+ if subscriber.event_enabled(event) {
+ subscriber.event(event);
}
}
@@ -595,7 +624,7 @@ impl Dispatch {
/// [`Subscriber`]: super::subscriber::Subscriber
/// [`enter`]: super::subscriber::Subscriber::enter
pub fn enter(&self, span: &span::Id) {
- self.subscriber.enter(span);
+ self.subscriber().enter(span);
}
/// Records that a span has been exited.
@@ -606,7 +635,7 @@ impl Dispatch {
/// [`Subscriber`]: super::subscriber::Subscriber
/// [`exit`]: super::subscriber::Subscriber::exit
pub fn exit(&self, span: &span::Id) {
- self.subscriber.exit(span);
+ self.subscriber().exit(span);
}
/// Notifies the subscriber that a [span ID] has been cloned.
@@ -625,7 +654,7 @@ impl Dispatch {
/// [`new_span`]: super::subscriber::Subscriber::new_span
#[inline]
pub fn clone_span(&self, id: &span::Id) -> span::Id {
- self.subscriber.clone_span(id)
+ self.subscriber().clone_span(id)
}
/// Notifies the subscriber that a [span ID] has been dropped.
@@ -654,7 +683,7 @@ impl Dispatch {
#[deprecated(since = "0.1.2", note = "use `Dispatch::try_close` instead")]
pub fn drop_span(&self, id: span::Id) {
#[allow(deprecated)]
- self.subscriber.drop_span(id);
+ self.subscriber().drop_span(id);
}
/// Notifies the subscriber that a [span ID] has been dropped, and returns
@@ -673,7 +702,7 @@ impl Dispatch {
/// [`try_close`]: super::subscriber::Subscriber::try_close
/// [`new_span`]: super::subscriber::Subscriber::new_span
pub fn try_close(&self, id: span::Id) -> bool {
- self.subscriber.try_close(id)
+ self.subscriber().try_close(id)
}
/// Returns a type representing this subscriber's view of the current span.
@@ -684,21 +713,21 @@ impl Dispatch {
/// [`current`]: super::subscriber::Subscriber::current_span
#[inline]
pub fn current_span(&self) -> span::Current {
- self.subscriber.current_span()
+ self.subscriber().current_span()
}
/// Returns `true` if this `Dispatch` forwards to a `Subscriber` of type
/// `T`.
#[inline]
pub fn is<T: Any>(&self) -> bool {
- <dyn Subscriber>::is::<T>(&self.subscriber)
+ <dyn Subscriber>::is::<T>(self.subscriber())
}
/// Returns some reference to the `Subscriber` this `Dispatch` forwards to
/// if it is of type `T`, or `None` if it isn't.
#[inline]
pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
- <dyn Subscriber>::downcast_ref(&self.subscriber)
+ <dyn Subscriber>::downcast_ref(self.subscriber())
}
}
@@ -711,9 +740,16 @@ impl Default for Dispatch {
impl fmt::Debug for Dispatch {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_tuple("Dispatch")
- .field(&format_args!("{:p}", self.subscriber))
- .finish()
+ match self.subscriber {
+ Kind::Scoped(ref s) => f
+ .debug_tuple("Dispatch::Scoped")
+ .field(&format_args!("{:p}", s))
+ .finish(),
+ Kind::Global(s) => f
+ .debug_tuple("Dispatch::Global")
+ .field(&format_args!("{:p}", s))
+ .finish(),
+ }
}
}
@@ -757,12 +793,16 @@ impl WeakDispatch {
impl fmt::Debug for WeakDispatch {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- let mut tuple = f.debug_tuple("WeakDispatch");
- match self.subscriber.upgrade() {
- Some(subscriber) => tuple.field(&format_args!("Some({:p})", subscriber)),
- None => tuple.field(&format_args!("None")),
- };
- tuple.finish()
+ match self.subscriber {
+ Kind::Scoped(ref s) => f
+ .debug_tuple("WeakDispatch::Scoped")
+ .field(&format_args!("{:p}", s))
+ .finish(),
+ Kind::Global(s) => f
+ .debug_tuple("WeakDispatch::Global")
+ .field(&format_args!("{:p}", s))
+ .finish(),
+ }
}
}
@@ -775,6 +815,26 @@ impl Registrar {
// ===== impl State =====
+impl Kind<Arc<dyn Subscriber + Send + Sync>> {
+ fn downgrade(&self) -> Kind<Weak<dyn Subscriber + Send + Sync>> {
+ match self {
+ Kind::Global(s) => Kind::Global(*s),
+ Kind::Scoped(ref s) => Kind::Scoped(Arc::downgrade(s)),
+ }
+ }
+}
+
+impl Kind<Weak<dyn Subscriber + Send + Sync>> {
+ fn upgrade(&self) -> Option<Kind<Arc<dyn Subscriber + Send + Sync>>> {
+ match self {
+ Kind::Global(s) => Some(Kind::Global(*s)),
+ Kind::Scoped(ref s) => Some(Kind::Scoped(s.upgrade()?)),
+ }
+ }
+}
+
+// ===== impl State =====
+
#[cfg(feature = "std")]
impl State {
/// Replaces the current default dispatcher on this thread with the provided
@@ -792,6 +852,7 @@ impl State {
.ok()
.flatten();
EXISTS.store(true, Ordering::Release);
+ SCOPED_COUNT.fetch_add(1, Ordering::Release);
DefaultGuard(prior)
}
@@ -810,10 +871,11 @@ impl State {
#[cfg(feature = "std")]
impl<'a> Entered<'a> {
#[inline]
- fn current(&self) -> RefMut<'a, Dispatch> {
- let default = self.0.default.borrow_mut();
- RefMut::map(default, |default| {
- default.get_or_insert_with(|| get_global().cloned().unwrap_or_else(Dispatch::none))
+ fn current(&self) -> Ref<'a, Dispatch> {
+ let default = self.0.default.borrow();
+ Ref::map(default, |default| match default {
+ Some(default) => default,
+ None => get_global(),
})
}
}
@@ -838,6 +900,7 @@ impl Drop for DefaultGuard {
// could then also attempt to access the same thread local
// state -- causing a clash.
let prev = CURRENT_STATE.try_with(|state| state.default.replace(self.0.take()));
+ SCOPED_COUNT.fetch_sub(1, Ordering::Release);
drop(prev)
}
}
diff --git a/src/field.rs b/src/field.rs
index e103c75..90c4eaa 100644
--- a/src/field.rs
+++ b/src/field.rs
@@ -1,13 +1,13 @@
//! `Span` and `Event` key-value data.
//!
-//! Spans and events may be annotated with key-value data, referred to as known
-//! as _fields_. These fields consist of a mapping from a key (corresponding to
-//! a `&str` but represented internally as an array index) to a [`Value`].
+//! Spans and events may be annotated with key-value data, known as _fields_.
+//! These fields consist of a mapping from a key (corresponding to a `&str` but
+//! represented internally as an array index) to a [`Value`].
//!
//! # `Value`s and `Subscriber`s
//!
//! `Subscriber`s consume `Value`s as fields attached to [span]s or [`Event`]s.
-//! The set of field keys on a given span or is defined on its [`Metadata`].
+//! The set of field keys on a given span or event is defined on its [`Metadata`].
//! When a span is created, it provides [`Attributes`] to the `Subscriber`'s
//! [`new_span`] method, containing any fields whose values were provided when
//! the span was created; and may call the `Subscriber`'s [`record`] method
@@ -315,6 +315,7 @@ pub trait Visit {
/// <strong>Note</strong>: This is only enabled when the Rust standard library is
/// present.
/// </pre>
+ /// </div>
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
fn record_error(&mut self, field: &Field, value: &(dyn std::error::Error + 'static)) {
@@ -469,6 +470,10 @@ macro_rules! impl_one_value {
impl $crate::sealed::Sealed for $value_ty {}
impl $crate::field::Value for $value_ty {
fn record(&self, key: &$crate::field::Field, visitor: &mut dyn $crate::field::Visit) {
+ // `op` is always a function; the closure is used because
+ // sometimes there isn't a real function corresponding to that
+ // operation. the clippy warning is not that useful here.
+ #[allow(clippy::redundant_closure_call)]
visitor.$record(key, $op(*self))
}
}
@@ -484,6 +489,10 @@ macro_rules! impl_one_value {
impl $crate::sealed::Sealed for ty_to_nonzero!($value_ty) {}
impl $crate::field::Value for ty_to_nonzero!($value_ty) {
fn record(&self, key: &$crate::field::Field, visitor: &mut dyn $crate::field::Visit) {
+ // `op` is always a function; the closure is used because
+ // sometimes there isn't a real function corresponding to that
+ // operation. the clippy warning is not that useful here.
+ #[allow(clippy::redundant_closure_call)]
visitor.$record(key, $op(self.get()))
}
}
@@ -819,6 +828,7 @@ impl FieldSet {
///
/// [`Identifier`]: super::callsite::Identifier
/// [`Callsite`]: super::callsite::Callsite
+ #[inline]
pub(crate) fn callsite(&self) -> callsite::Identifier {
callsite::Identifier(self.callsite.0)
}
@@ -856,6 +866,7 @@ impl FieldSet {
}
/// Returns an iterator over the `Field`s in this `FieldSet`.
+ #[inline]
pub fn iter(&self) -> Iter {
let idxs = 0..self.len();
Iter {
@@ -868,9 +879,6 @@ impl FieldSet {
}
/// Returns a new `ValueSet` with entries for this `FieldSet`'s values.
- ///
- /// Note that a `ValueSet` may not be constructed with arrays of over 32
- /// elements.
#[doc(hidden)]
pub fn value_set<'v, V>(&'v self, values: &'v V) -> ValueSet<'v>
where
@@ -959,6 +967,7 @@ impl PartialEq for FieldSet {
impl Iterator for Iter {
type Item = Field;
+ #[inline]
fn next(&mut self) -> Option<Field> {
let i = self.idxs.next()?;
Some(Field {
@@ -1068,28 +1077,10 @@ impl<'a> fmt::Display for ValueSet<'a> {
mod private {
use super::*;
- /// Marker trait implemented by arrays which are of valid length to
- /// construct a `ValueSet`.
- ///
- /// `ValueSet`s may only be constructed from arrays containing 32 or fewer
- /// elements, to ensure the array is small enough to always be allocated on the
- /// stack. This trait is only implemented by arrays of an appropriate length,
- /// ensuring that the correct size arrays are used at compile-time.
+ /// Restrictions on `ValueSet` lengths were removed in #2508 but this type remains for backwards compatibility.
pub trait ValidLen<'a>: Borrow<[(&'a Field, Option<&'a (dyn Value + 'a)>)]> {}
-}
-
-macro_rules! impl_valid_len {
- ( $( $len:tt ),+ ) => {
- $(
- impl<'a> private::ValidLen<'a> for
- [(&'a Field, Option<&'a (dyn Value + 'a)>); $len] {}
- )+
- }
-}
-impl_valid_len! {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32
+ impl<'a, const N: usize> ValidLen<'a> for [(&'a Field, Option<&'a (dyn Value + 'a)>); N] {}
}
#[cfg(test)]
@@ -1098,8 +1089,9 @@ mod test {
use crate::metadata::{Kind, Level, Metadata};
use crate::stdlib::{borrow::ToOwned, string::String};
- struct TestCallsite1;
- static TEST_CALLSITE_1: TestCallsite1 = TestCallsite1;
+ // Make sure TEST_CALLSITE_* have non-zero size, so they can't be located at the same address.
+ struct TestCallsite1(u8);
+ static TEST_CALLSITE_1: TestCallsite1 = TestCallsite1(0);
static TEST_META_1: Metadata<'static> = metadata! {
name: "field_test1",
target: module_path!(),
@@ -1119,8 +1111,8 @@ mod test {
}
}
- struct TestCallsite2;
- static TEST_CALLSITE_2: TestCallsite2 = TestCallsite2;
+ struct TestCallsite2(u8);
+ static TEST_CALLSITE_2: TestCallsite2 = TestCallsite2(0);
static TEST_META_2: Metadata<'static> = metadata! {
name: "field_test2",
target: module_path!(),
diff --git a/src/lib.rs b/src/lib.rs
index c1f87b2..d43a6b8 100644
--- a/src/lib.rs
+++ b/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.49+][msrv]*
+//! *Compiler support: [requires `rustc` 1.56+][msrv]*
//!
//! [msrv]: #supported-rust-versions
//!
@@ -92,14 +92,14 @@
//! ## Supported Rust Versions
//!
//! Tracing is built against the latest stable release. The minimum supported
-//! version is 1.49. The current Tracing version is not guaranteed to build on
+//! version is 1.56. 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
//! project. The current stable Rust compiler and the three most recent minor
//! versions before it will always be supported. For example, if the current
-//! stable compiler version is 1.45, the minimum supported version will not be
-//! increased past 1.42, three minor versions prior. Increasing the minimum
+//! stable compiler version is 1.69, the minimum supported version will not be
+//! increased past 1.66, three minor versions prior. Increasing the minimum
//! supported compiler version is not considered a semver breaking change as
//! long as doing so complies with this policy.
//!
@@ -116,7 +116,6 @@
//! [`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.22")]
#![doc(
html_logo_url = "https://raw.githubusercontent.com/tokio-rs/tracing/master/assets/logo-type.png",
issue_tracker_base_url = "https://github.com/tokio-rs/tracing/issues/"
@@ -129,7 +128,6 @@
rust_2018_idioms,
unreachable_pub,
bad_style,
- const_err,
dead_code,
improper_ctypes,
non_shorthand_field_patterns,
@@ -245,9 +243,9 @@ macro_rules! metadata {
$name,
$target,
$level,
- Some(file!()),
- Some(line!()),
- Some(module_path!()),
+ ::core::option::Option::Some(file!()),
+ ::core::option::Option::Some(line!()),
+ ::core::option::Option::Some(module_path!()),
$crate::field::FieldSet::new($fields, $crate::identify_callsite!($callsite)),
$kind,
)
diff --git a/src/metadata.rs b/src/metadata.rs
index a154419..5e475c1 100644
--- a/src/metadata.rs
+++ b/src/metadata.rs
@@ -273,6 +273,7 @@ impl<'a> Metadata<'a> {
}
/// Returns the names of the fields on the described span or event.
+ #[inline]
pub fn fields(&self) -> &field::FieldSet {
&self.fields
}
diff --git a/src/subscriber.rs b/src/subscriber.rs
index e8f4441..17b6316 100644
--- a/src/subscriber.rs
+++ b/src/subscriber.rs
@@ -699,6 +699,14 @@ impl Subscriber for NoSubscriber {
fn exit(&self, _span: &span::Id) {}
}
+impl NoSubscriber {
+ /// Returns a new `NoSubscriber`.
+ #[must_use]
+ pub const fn new() -> Self {
+ Self(())
+ }
+}
+
impl<S> Subscriber for Box<S>
where
S: Subscriber + ?Sized,
diff --git a/tests/local_dispatch_before_init.rs b/tests/local_dispatch_before_init.rs
new file mode 100644
index 0000000..71b67f8
--- /dev/null
+++ b/tests/local_dispatch_before_init.rs
@@ -0,0 +1,43 @@
+mod common;
+
+use common::*;
+use tracing_core::{
+ dispatcher::{self, Dispatch},
+ subscriber::NoSubscriber,
+};
+
+/// This test reproduces the following issues:
+/// - https://github.com/tokio-rs/tracing/issues/2587
+/// - https://github.com/tokio-rs/tracing/issues/2411
+/// - https://github.com/tokio-rs/tracing/issues/2436
+#[test]
+fn local_dispatch_before_init() {
+ dispatcher::get_default(|current| assert!(dbg!(current).is::<NoSubscriber>()));
+
+ // Temporarily override the default dispatcher with a scoped dispatcher.
+ // Using a scoped dispatcher makes the thread local state attempt to cache
+ // the scoped default.
+ #[cfg(feature = "std")]
+ {
+ dispatcher::with_default(&Dispatch::new(TestSubscriberB), || {
+ dispatcher::get_default(|current| {
+ assert!(
+ dbg!(current).is::<TestSubscriberB>(),
+ "overriden subscriber not set",
+ );
+ })
+ })
+ }
+
+ dispatcher::get_default(|current| assert!(current.is::<NoSubscriber>()));
+
+ dispatcher::set_global_default(Dispatch::new(TestSubscriberA))
+ .expect("set global dispatch failed");
+
+ dispatcher::get_default(|current| {
+ assert!(
+ dbg!(current).is::<TestSubscriberA>(),
+ "default subscriber not set"
+ );
+ });
+}