From 6492446133c420f30f0b56d414a7827e1d0fa69e Mon Sep 17 00:00:00 2001 From: hubertbudzynski <44027774+hubertbudzynski@users.noreply.github.com> Date: Wed, 27 Apr 2022 18:04:46 +0200 Subject: [PATCH 01/13] opentelemetry: fix event source locations (#2099) Fixes: #2094 ## Motivation Properly attach event's source locations. ## Solution Append the locations to events' attributes instead of span's attributes. --- tracing-opentelemetry/src/layer.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/tracing-opentelemetry/src/layer.rs b/tracing-opentelemetry/src/layer.rs index bdaf1c32fa..722d7ce804 100644 --- a/tracing-opentelemetry/src/layer.rs +++ b/tracing-opentelemetry/src/layer.rs @@ -602,8 +602,6 @@ where } if self.event_location { - let builder_attrs = builder.attributes.get_or_insert(Vec::new()); - #[cfg(not(feature = "tracing-log"))] let normalized_meta: Option<tracing_core::Metadata<'_>> = None; let (file, module) = match &normalized_meta { @@ -618,13 +616,19 @@ where }; if let Some(file) = file { - builder_attrs.push(KeyValue::new("code.filepath", file)); + otel_event + .attributes + .push(KeyValue::new("code.filepath", file)); } if let Some(module) = module { - builder_attrs.push(KeyValue::new("code.namespace", module)); + otel_event + .attributes + .push(KeyValue::new("code.namespace", module)); } if let Some(line) = meta.line() { - builder_attrs.push(KeyValue::new("code.lineno", line as i64)); + otel_event + .attributes + .push(KeyValue::new("code.lineno", line as i64)); } } From 9a3c5063f74ddd0a27d8670f7c7a43dac0bb3747 Mon Sep 17 00:00:00 2001 From: James Munns <james@onevariable.com> Date: Thu, 5 May 2022 20:54:44 +0200 Subject: [PATCH 02/13] subscriber: don't enable `tracing-core` features by default (#2107) This attempts to address #2106 by disabling the `tracing-core` crate's default features in `tracing-subscriber`'s dependency. Now, `tracing-core`'s optional "alloc" feature is only enabled when "tracing-subscriber/alloc" is enabled. Closes #2106 --- tracing-subscriber/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tracing-subscriber/Cargo.toml b/tracing-subscriber/Cargo.toml index b28f498615..9109efc9ce 100644 --- a/tracing-subscriber/Cargo.toml +++ b/tracing-subscriber/Cargo.toml @@ -38,7 +38,7 @@ valuable = ["tracing-core/valuable", "valuable_crate", "valuable-serde", "tracin local-time = ["time/local-offset"] [dependencies] -tracing-core = { path = "../tracing-core", version = "0.1.22" } +tracing-core = { path = "../tracing-core", version = "0.1.22", default-features = false } # only required by the filter feature tracing = { optional = true, path = "../tracing", version = "0.1", default-features = false } From fea09a8bd6860485e5653777c08622176b4151ad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 May 2022 13:48:08 -0700 Subject: [PATCH 03/13] chore(deps): update tokio-test requirement from 0.2.0 to 0.3.0 (#1379) Updates the requirements on [tokio-test](https://github.com/tokio-rs/tokio) to permit the latest version. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-0.2.0...tokio-0.3.0) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Eliza Weisman <eliza@buoyant.io> --- tracing-attributes/Cargo.toml | 2 +- tracing-futures/Cargo.toml | 2 +- tracing-mock/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tracing-attributes/Cargo.toml b/tracing-attributes/Cargo.toml index 8bc4a96069..85e51f6ffe 100644 --- a/tracing-attributes/Cargo.toml +++ b/tracing-attributes/Cargo.toml @@ -46,7 +46,7 @@ quote = "1" [dev-dependencies] tracing = { path = "../tracing", version = "0.1" } tracing-mock = { path = "../tracing-mock", features = ["tokio-test"] } -tokio-test = { version = "0.2.0" } +tokio-test = { version = "0.3.0" } tracing-core = { path = "../tracing-core", version = "0.1"} async-trait = "0.1.44" diff --git a/tracing-futures/Cargo.toml b/tracing-futures/Cargo.toml index 08afaa36bd..6347b97449 100644 --- a/tracing-futures/Cargo.toml +++ b/tracing-futures/Cargo.toml @@ -36,7 +36,7 @@ tokio = { version = "0.1", optional = true } [dev-dependencies] tokio = "0.1.22" -tokio-test = "0.2" +tokio-test = "0.3" tracing-core = { path = "../tracing-core", version = "0.1.2" } tracing-mock = { path = "../tracing-mock" } diff --git a/tracing-mock/Cargo.toml b/tracing-mock/Cargo.toml index c54adac51d..3b74dced26 100644 --- a/tracing-mock/Cargo.toml +++ b/tracing-mock/Cargo.toml @@ -20,7 +20,7 @@ publish = false [dependencies] tracing = { path = "../tracing", version = "0.1", default-features = false } tracing-core = { path = "../tracing-core", version = "0.1", default-features = false } -tokio-test = { version = "0.2.0", optional = true } +tokio-test = { version = "0.3.0", optional = true } [package.metadata.docs.rs] all-features = true From 6878d8dbc9979571265c598895746c2956ecb1d1 Mon Sep 17 00:00:00 2001 From: Max Davitt <max@davitt.me> Date: Mon, 9 May 2022 17:58:53 -0400 Subject: [PATCH 04/13] journald: disable default features of tracing-subscriber (#1476) ## Motivation Closes #1465. ## Solution I'm just disabling the default features of `tracing-journald`'s dependency on `tracing-subscriber`. The original issue talked about the crate's dependencies more broadly but considering that the standard library is already depended upon I didn't think it made sense to change the `tracing-core` dependency's features (which are just `no_std` support). --- tracing-journald/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tracing-journald/Cargo.toml b/tracing-journald/Cargo.toml index c5cea152d5..e4f5eca8a1 100644 --- a/tracing-journald/Cargo.toml +++ b/tracing-journald/Cargo.toml @@ -18,9 +18,9 @@ rust-version = "1.49.0" [dependencies] libc = "0.2.107" tracing-core = { path = "../tracing-core", version = "0.1.10" } -tracing-subscriber = { path = "../tracing-subscriber", version = "0.3" } +tracing-subscriber = { path = "../tracing-subscriber", version = "0.3", default-features = false, features = ["registry"] } [dev-dependencies] serde_json = "1.0.68" serde = { version = "1.0.130", features = ["derive"] } -tracing = { path = "../tracing", version = "0.1" } \ No newline at end of file +tracing = { path = "../tracing", version = "0.1" } From f22f2861e017057fc34dd13c224ca6c9881db643 Mon Sep 17 00:00:00 2001 From: George Malayil Philip <georgemp@users.noreply.github.com> Date: Tue, 10 May 2022 03:53:57 +0530 Subject: [PATCH 05/13] Add additional information to references of my_crate in env_filter docs. (#1088) Co-authored-by: Bryan Garza <1396101+bryangarza@users.noreply.github.com> --- tracing-subscriber/src/filter/env/mod.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tracing-subscriber/src/filter/env/mod.rs b/tracing-subscriber/src/filter/env/mod.rs index dae20a6a2e..81a9ae2bde 100644 --- a/tracing-subscriber/src/filter/env/mod.rs +++ b/tracing-subscriber/src/filter/env/mod.rs @@ -449,6 +449,11 @@ impl EnvFilter { /// # Ok(()) /// # } /// ``` + /// In the above example, substitute `my_crate`, `module`, etc. with the + /// name your target crate/module is imported with. This might be + /// different from the package name in Cargo.toml (`-` is replaced by `_`). + /// Example, if the package name in your Cargo.toml is `MY-FANCY-LIB`, then + /// the corresponding Rust identifier would be `MY_FANCY_LIB`: pub fn add_directive(mut self, mut directive: Directive) -> Self { if !self.regex { directive.deregexify(); From cc19449ef1078f4c5dd5019f6d52f42acccdad43 Mon Sep 17 00:00:00 2001 From: zz <48124374+zzhengzhuo@users.noreply.github.com> Date: Tue, 10 May 2022 08:13:29 +0800 Subject: [PATCH 06/13] fix opentelemetry example (#2110) Co-authored-by: Bryan Garza <1396101+bryangarza@users.noreply.github.com> --- examples/examples/opentelemetry.rs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/examples/examples/opentelemetry.rs b/examples/examples/opentelemetry.rs index 5c4b4c484a..fbc7469080 100644 --- a/examples/examples/opentelemetry.rs +++ b/examples/examples/opentelemetry.rs @@ -1,3 +1,4 @@ +use opentelemetry::global; use std::{error::Error, thread, time::Duration}; use tracing::{span, trace, warn}; use tracing_attributes::instrument; @@ -26,16 +27,20 @@ fn main() -> Result<(), Box<dyn Error + Send + Sync + 'static>> { .with(opentelemetry) .try_init()?; - let root = span!(tracing::Level::INFO, "app_start", work_units = 2); - let _enter = root.enter(); + { + let root = span!(tracing::Level::INFO, "app_start", work_units = 2); + let _enter = root.enter(); - let work_result = expensive_work(); + let work_result = expensive_work(); - span!(tracing::Level::INFO, "faster_work") - .in_scope(|| thread::sleep(Duration::from_millis(10))); + span!(tracing::Level::INFO, "faster_work") + .in_scope(|| thread::sleep(Duration::from_millis(10))); - warn!("About to exit!"); - trace!("status: {}", work_result); + warn!("About to exit!"); + trace!("status: {}", work_result); + } + + global::shutdown_tracer_provider(); Ok(()) } From 1afc9d5c02e391de9dcefe8f91fb02c94516feed Mon Sep 17 00:00:00 2001 From: Tyson Nottingham <tgnottingham@gmail.com> Date: Wed, 11 May 2022 13:55:06 -0700 Subject: [PATCH 07/13] error: add missing backtick to `prelude` docs (#2120) --- tracing-error/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tracing-error/src/lib.rs b/tracing-error/src/lib.rs index 88f5ae228d..b94205ceeb 100644 --- a/tracing-error/src/lib.rs +++ b/tracing-error/src/lib.rs @@ -221,7 +221,7 @@ pub use self::layer::ErrorLayer; pub mod prelude { //! The `tracing-error` prelude. //! - //! This brings into scope the `InstrumentError, `InstrumentResult`, and `ExtractSpanTrace` + //! This brings into scope the `InstrumentError`, `InstrumentResult`, and `ExtractSpanTrace` //! extension traits. These traits allow attaching `SpanTrace`s to errors and //! subsequently retrieving them from `dyn Error` trait objects. From 92c5425ceee7f942fae3a0b2235e6889e1238656 Mon Sep 17 00:00:00 2001 From: Devin <DevinCarr@users.noreply.github.com> Date: Fri, 20 May 2022 11:54:23 -0700 Subject: [PATCH 08/13] opentelemetry: enforce event_location for span tags (#2124) The `with_event_location(false)` method will now properly omit `code.*` tags from spans. ## Motivation Recently, I attempted to remove the `code.*` tags from opentelemetry tracing spans utilizing the [`with_event_location`] of OpenTelemetrySubscriber. This did not work as expected because the [`on_new_span`] doesn't account for the `event_location` boolean similar to how [`on_event`] does. ## Solution The change presented will expand the use of the `location` field to check before adding the `code.*` KeyValue attributes in `on_new_span`. In addition, `with_event_location` was renamed to `with_location`, as it now controls both span *and* event locations, and the `with_event_location` method has been deprecated. ## Testing Additional unit tests are included in [tracing-opentelemetry/src/subscriber.rs] to cover both boolean cases of `with_location`. [`with_event_location`]: https://github.com/tokio-rs/tracing/blob/master/tracing-opentelemetry/src/subscriber.rs#L343 [`on_new_span`]: https://github.com/tokio-rs/tracing/blob/master/tracing-opentelemetry/src/subscriber.rs#L448-L460 [`on_event`]: https://github.com/tokio-rs/tracing/blob/master/tracing-opentelemetry/src/subscriber.rs#L582 [tracing-opentelemetry/src/subscriber.rs]: https://github.com/tokio-rs/tracing/pull/2124/files#diff-69011e8b23dffcbe19b9b72e5ac54330a7871f424a90700ed7f5c5686daf431bR911-R975) --- tracing-opentelemetry/src/layer.rs | 102 +++++++++++++++++++++++++---- 1 file changed, 88 insertions(+), 14 deletions(-) diff --git a/tracing-opentelemetry/src/layer.rs b/tracing-opentelemetry/src/layer.rs index 722d7ce804..9f2da0b601 100644 --- a/tracing-opentelemetry/src/layer.rs +++ b/tracing-opentelemetry/src/layer.rs @@ -28,7 +28,7 @@ const SPAN_STATUS_MESSAGE_FIELD: &str = "otel.status_message"; /// [tracing]: https://github.com/tokio-rs/tracing pub struct OpenTelemetryLayer<S, T> { tracer: T, - event_location: bool, + location: bool, tracked_inactivity: bool, get_context: WithContext, _registry: marker::PhantomData<S>, @@ -312,7 +312,7 @@ where pub fn new(tracer: T) -> Self { OpenTelemetryLayer { tracer, - event_location: true, + location: true, tracked_inactivity: true, get_context: WithContext(Self::get_context), _registry: marker::PhantomData, @@ -351,20 +351,32 @@ where { OpenTelemetryLayer { tracer, - event_location: self.event_location, + location: self.location, tracked_inactivity: self.tracked_inactivity, get_context: WithContext(OpenTelemetryLayer::<S, Tracer>::get_context), _registry: self._registry, } } + /// Sets whether or not span and event metadata should include detailed + /// location information, such as the file, module and line number. + /// + /// By default, locations are enabled. + pub fn with_location(self, location: bool) -> Self { + Self { location, ..self } + } + /// Sets whether or not event span's metadata should include detailed location /// information, such as the file, module and line number. /// /// By default, event locations are enabled. + #[deprecated( + since = "0.17.3", + note = "renamed to `OpenTelemetrySubscriber::with_location`" + )] pub fn with_event_location(self, event_location: bool) -> Self { Self { - event_location, + location: event_location, ..self } } @@ -467,18 +479,20 @@ where .attributes .get_or_insert(Vec::with_capacity(attrs.fields().len() + 3)); - let meta = attrs.metadata(); + if self.location { + let meta = attrs.metadata(); - if let Some(filename) = meta.file() { - builder_attrs.push(KeyValue::new("code.filepath", filename)); - } + if let Some(filename) = meta.file() { + builder_attrs.push(KeyValue::new("code.filepath", filename)); + } - if let Some(module) = meta.module_path() { - builder_attrs.push(KeyValue::new("code.namespace", module)); - } + if let Some(module) = meta.module_path() { + builder_attrs.push(KeyValue::new("code.namespace", module)); + } - if let Some(line) = meta.line() { - builder_attrs.push(KeyValue::new("code.lineno", line as i64)); + if let Some(line) = meta.line() { + builder_attrs.push(KeyValue::new("code.lineno", line as i64)); + } } attrs.record(&mut SpanAttributeVisitor(&mut builder)); @@ -601,7 +615,7 @@ where builder.status_code = Some(otel::StatusCode::Error); } - if self.event_location { + if self.location { #[cfg(not(feature = "tracing-log"))] let normalized_meta: Option<tracing_core::Metadata<'_>> = None; let (file, module) = match &normalized_meta { @@ -999,4 +1013,64 @@ mod tests { ) ); } + + #[test] + fn includes_span_location() { + let tracer = TestTracer(Arc::new(Mutex::new(None))); + let subscriber = tracing_subscriber::registry() + .with(layer().with_tracer(tracer.clone()).with_location(true)); + + tracing::subscriber::with_default(subscriber, || { + tracing::debug_span!("request"); + }); + + let attributes = tracer + .0 + .lock() + .unwrap() + .as_ref() + .unwrap() + .builder + .attributes + .as_ref() + .unwrap() + .clone(); + let keys = attributes + .iter() + .map(|attr| attr.key.as_str()) + .collect::<Vec<&str>>(); + assert!(keys.contains(&"code.filepath")); + assert!(keys.contains(&"code.namespace")); + assert!(keys.contains(&"code.lineno")); + } + + #[test] + fn excludes_span_location() { + let tracer = TestTracer(Arc::new(Mutex::new(None))); + let subscriber = tracing_subscriber::registry() + .with(layer().with_tracer(tracer.clone()).with_location(false)); + + tracing::subscriber::with_default(subscriber, || { + tracing::debug_span!("request"); + }); + + let attributes = tracer + .0 + .lock() + .unwrap() + .as_ref() + .unwrap() + .builder + .attributes + .as_ref() + .unwrap() + .clone(); + let keys = attributes + .iter() + .map(|attr| attr.key.as_str()) + .collect::<Vec<&str>>(); + assert!(!keys.contains(&"code.filepath")); + assert!(!keys.contains(&"code.namespace")); + assert!(!keys.contains(&"code.lineno")); + } } From fc370cdbf6f2748d91f8f7f5d0dcf69c5780ec5d Mon Sep 17 00:00:00 2001 From: Bryan Garza <1396101+bryangarza@users.noreply.github.com> Date: Mon, 23 May 2022 09:05:51 -0700 Subject: [PATCH 09/13] appender: add initial set of benches (#2128) * appender: add initial set of benches This patch adds blocking and nonblocking benchmarks. This code is from an old PR (#703) that was never merged, and now ported to TOT so that it compiles. Co-authored-by: Zeki Sherif <9832640+zekisherif@users.noreply.github.com> * switch to no-op writers in benchmarks * fix macro resolution issue Co-authored-by: Zeki Sherif <9832640+zekisherif@users.noreply.github.com> Co-authored-by: David Barsky <me@davidbarsky.com> --- tracing-appender/Cargo.toml | 6 ++ tracing-appender/benches/bench.rs | 134 ++++++++++++++++++++++++++++++ tracing/src/macros.rs | 7 +- 3 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 tracing-appender/benches/bench.rs diff --git a/tracing-appender/Cargo.toml b/tracing-appender/Cargo.toml index c57932b503..2d02b38e95 100644 --- a/tracing-appender/Cargo.toml +++ b/tracing-appender/Cargo.toml @@ -32,6 +32,12 @@ default-features = false features = ["fmt", "std"] [dev-dependencies] + +criterion = { version = "0.3", default_features = false } tracing = { path = "../tracing", version = "0.1" } time = { version = "0.3", default-features = false, features = ["formatting", "parsing"] } tempfile = "3" + +[[bench]] +name = "bench" +harness = false \ No newline at end of file diff --git a/tracing-appender/benches/bench.rs b/tracing-appender/benches/bench.rs new file mode 100644 index 0000000000..e8ea4d75a6 --- /dev/null +++ b/tracing-appender/benches/bench.rs @@ -0,0 +1,134 @@ +use criterion::{criterion_group, criterion_main, Criterion}; +use std::{ + thread::{self, JoinHandle}, + time::Instant, +}; +use tracing::{event, Level}; +use tracing_appender::non_blocking; +use tracing_subscriber::fmt::MakeWriter; + +// a no-op writer is used in order to measure the overhead incurred by +// tracing-subscriber. +#[derive(Clone)] +struct NoOpWriter; + +impl NoOpWriter { + fn new() -> NoOpWriter { + NoOpWriter + } +} + +impl<'a> MakeWriter<'a> for NoOpWriter { + type Writer = NoOpWriter; + + fn make_writer(&self) -> Self::Writer { + self.clone() + } +} + +impl std::io::Write for NoOpWriter { + fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> { + Ok(buf.len()) + } + + fn flush(&mut self) -> std::io::Result<()> { + Ok(()) + } +} + +fn synchronous_benchmark(c: &mut Criterion) { + let mut group = c.benchmark_group("synchronous"); + group.bench_function("single_thread", |b| { + let subscriber = tracing_subscriber::fmt().with_writer(NoOpWriter::new()); + tracing::subscriber::with_default(subscriber.finish(), || { + b.iter(|| event!(Level::INFO, "event")) + }); + }); + + group.bench_function("multiple_writers", |b| { + b.iter_custom(|iters| { + let mut handles: Vec<JoinHandle<()>> = Vec::new(); + + let start = Instant::now(); + + let make_writer = NoOpWriter::new(); + let cloned_make_writer = make_writer.clone(); + + handles.push(thread::spawn(move || { + let subscriber = tracing_subscriber::fmt().with_writer(make_writer); + tracing::subscriber::with_default(subscriber.finish(), || { + for _ in 0..iters { + event!(Level::INFO, "event"); + } + }); + })); + + handles.push(thread::spawn(move || { + let subscriber = tracing_subscriber::fmt().with_writer(cloned_make_writer); + tracing::subscriber::with_default(subscriber.finish(), || { + for _ in 0..iters { + event!(Level::INFO, "event"); + } + }); + })); + + for handle in handles { + let _ = handle.join(); + } + + start.elapsed() + }); + }); +} + +fn non_blocking_benchmark(c: &mut Criterion) { + let mut group = c.benchmark_group("non_blocking"); + + group.bench_function("single_thread", |b| { + let (non_blocking, _guard) = non_blocking(NoOpWriter::new()); + let subscriber = tracing_subscriber::fmt().with_writer(non_blocking); + + tracing::subscriber::with_default(subscriber.finish(), || { + b.iter(|| event!(Level::INFO, "event")) + }); + }); + + group.bench_function("multiple_writers", |b| { + b.iter_custom(|iters| { + let (non_blocking, _guard) = non_blocking(NoOpWriter::new()); + + let mut handles: Vec<JoinHandle<()>> = Vec::new(); + + let start = Instant::now(); + + let cloned_make_writer = non_blocking.clone(); + + handles.push(thread::spawn(move || { + let subscriber = tracing_subscriber::fmt().with_writer(non_blocking); + tracing::subscriber::with_default(subscriber.finish(), || { + for _ in 0..iters { + event!(Level::INFO, "event"); + } + }); + })); + + handles.push(thread::spawn(move || { + let subscriber = tracing_subscriber::fmt().with_writer(cloned_make_writer); + tracing::subscriber::with_default(subscriber.finish(), || { + for _ in 0..iters { + event!(Level::INFO, "event"); + } + }); + })); + + for handle in handles { + let _ = handle.join(); + } + + start.elapsed() + }); + }); +} + +criterion_group!(benches, synchronous_benchmark, non_blocking_benchmark); +criterion_main!(benches); diff --git a/tracing/src/macros.rs b/tracing/src/macros.rs index bca42933b3..b134af6e81 100644 --- a/tracing/src/macros.rs +++ b/tracing/src/macros.rs @@ -832,6 +832,8 @@ macro_rules! event { /// } /// ``` /// +/// [`enabled!`]: crate::enabled +/// [`span_enabled!`]: crate::span_enabled #[macro_export] macro_rules! event_enabled { ($($rest:tt)*)=> ( @@ -864,6 +866,8 @@ macro_rules! event_enabled { /// } /// ``` /// +/// [`enabled!`]: crate::enabled +/// [`span_enabled!`]: crate::span_enabled #[macro_export] macro_rules! span_enabled { ($($rest:tt)*)=> ( @@ -959,7 +963,8 @@ macro_rules! span_enabled { /// [`Metadata`]: crate::Metadata /// [`is_event`]: crate::Metadata::is_event /// [`is_span`]: crate::Metadata::is_span -/// +/// [`enabled!`]: crate::enabled +/// [`span_enabled!`]: crate::span_enabled #[macro_export] macro_rules! enabled { (kind: $kind:expr, target: $target:expr, $lvl:expr, { $($fields:tt)* } )=> ({ From aa55bd1a395ba40a3c548963b072d8eba1f80a14 Mon Sep 17 00:00:00 2001 From: jamen marz <me@jamen.dev> Date: Wed, 25 May 2022 10:31:06 -0600 Subject: [PATCH 10/13] docs: remove incorrect MSRV note (#2137) `tracing`'s lib.rs incorrectly states its MSRV; this commit removes it. --- tracing/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/tracing/src/lib.rs b/tracing/src/lib.rs index fdd12bd3eb..65a4ebc951 100644 --- a/tracing/src/lib.rs +++ b/tracing/src/lib.rs @@ -119,8 +119,6 @@ //! tracing = "0.1" //! ``` //! -//! *Compiler support: [requires `rustc` 1.42+][msrv]* -//! //! ## Recording Spans and Events //! //! Spans and events are recorded using macros. From 44892b40b8de8e5d696951e54495c852962cfb38 Mon Sep 17 00:00:00 2001 From: Eliza Weisman <eliza@buoyant.io> Date: Wed, 25 May 2022 12:18:39 -0700 Subject: [PATCH 11/13] opentelemetry: add support for thread names/ids (#2134) OpenTelemetry has [semantic conventions][1] for reporting thread names and IDs on spans. This branch adds support for recording thread names and IDs according to these conventions. [1]: https://opentelemetry.io/docs/reference/specification/trace/semantic_conventions/span-general/#source-code-attributes Signed-off-by: Eliza Weisman <eliza@buoyant.io> --- tracing-opentelemetry/Cargo.toml | 1 + tracing-opentelemetry/src/layer.rs | 231 +++++++++++++++++++---------- 2 files changed, 150 insertions(+), 82 deletions(-) diff --git a/tracing-opentelemetry/Cargo.toml b/tracing-opentelemetry/Cargo.toml index 788db1eb26..9e98b68f33 100644 --- a/tracing-opentelemetry/Cargo.toml +++ b/tracing-opentelemetry/Cargo.toml @@ -28,6 +28,7 @@ tracing = { path = "../tracing", version = "0.1", default-features = false, feat tracing-core = { path = "../tracing-core", version = "0.1" } tracing-subscriber = { path = "../tracing-subscriber", version = "0.3", default-features = false, features = ["registry", "std"] } tracing-log = { path = "../tracing-log", version = "0.1", default-features = false, optional = true } +once_cell = "1" [dev-dependencies] async-trait = "0.1" diff --git a/tracing-opentelemetry/src/layer.rs b/tracing-opentelemetry/src/layer.rs index 9f2da0b601..2c4749a1c1 100644 --- a/tracing-opentelemetry/src/layer.rs +++ b/tracing-opentelemetry/src/layer.rs @@ -1,4 +1,5 @@ use crate::{OtelData, PreSampledTracer}; +use once_cell::unsync; use opentelemetry::{ trace::{self as otel, noop, TraceContextExt}, Context as OtelContext, Key, KeyValue, Value, @@ -7,6 +8,7 @@ use std::any::TypeId; use std::borrow::Cow; use std::fmt; use std::marker; +use std::thread; use std::time::{Instant, SystemTime}; use tracing_core::span::{self, Attributes, Id, Record}; use tracing_core::{field, Event, Subscriber}; @@ -30,6 +32,7 @@ pub struct OpenTelemetryLayer<S, T> { tracer: T, location: bool, tracked_inactivity: bool, + with_threads: bool, get_context: WithContext, _registry: marker::PhantomData<S>, } @@ -314,6 +317,7 @@ where tracer, location: true, tracked_inactivity: true, + with_threads: true, get_context: WithContext(Self::get_context), _registry: marker::PhantomData, } @@ -353,23 +357,34 @@ where tracer, location: self.location, tracked_inactivity: self.tracked_inactivity, + with_threads: self.with_threads, get_context: WithContext(OpenTelemetryLayer::<S, Tracer>::get_context), _registry: self._registry, } } - /// Sets whether or not span and event metadata should include detailed - /// location information, such as the file, module and line number. + /// Sets whether or not span and event metadata should include OpenTelemetry + /// attributes with location information, such as the file, module and line number. + /// + /// These attributes follow the [OpenTelemetry semantic conventions for + /// source locations][conv]. /// /// By default, locations are enabled. + /// + /// [conv]: https://opentelemetry.io/docs/reference/specification/trace/semantic_conventions/span-general/#source-code-attributes pub fn with_location(self, location: bool) -> Self { Self { location, ..self } } - /// Sets whether or not event span's metadata should include detailed location - /// information, such as the file, module and line number. + /// Sets whether or not span and event metadata should include OpenTelemetry + /// attributes with location information, such as the file, module and line number. + /// + /// These attributes follow the [OpenTelemetry semantic conventions for + /// source locations][conv]. + /// + /// By default, locations are enabled. /// - /// By default, event locations are enabled. + /// [conv]: https://opentelemetry.io/docs/reference/specification/trace/semantic_conventions/span-general/#source-code-attributes #[deprecated( since = "0.17.3", note = "renamed to `OpenTelemetrySubscriber::with_location`" @@ -391,6 +406,20 @@ where } } + /// Sets whether or not spans record additional attributes for the thread + /// name and thread ID of the thread they were created on, following the + /// [OpenTelemetry semantic conventions for threads][conv]. + /// + /// By default, thread attributes are enabled. + /// + /// [conv]: https://opentelemetry.io/docs/reference/specification/trace/semantic_conventions/span-general/#general-thread-attributes + pub fn with_threads(self, threads: bool) -> Self { + Self { + with_threads: threads, + ..self + } + } + /// Retrieve the parent OpenTelemetry [`Context`] from the current tracing /// [`span`] through the [`Registry`]. This [`Context`] links spans to their /// parent for proper hierarchical visualization. @@ -443,6 +472,30 @@ where f(builder, &layer.tracer); } } + + fn extra_span_attrs(&self) -> usize { + let mut extra_attrs = 0; + if self.location { + extra_attrs += 3; + } + if self.with_threads { + extra_attrs += 2; + } + extra_attrs + } +} + +thread_local! { + static THREAD_ID: unsync::Lazy<u64> = unsync::Lazy::new(|| { + // OpenTelemetry's semantic conventions require the thread ID to be + // recorded as an integer, but `std::thread::ThreadId` does not expose + // the integer value on stable, so we have to convert it to a `usize` by + // parsing it. Since this requires allocating a `String`, store it in a + // thread local so we only have to do this once. + // TODO(eliza): once `std::thread::ThreadId::as_u64` is stabilized + // (https://github.com/rust-lang/rust/issues/67939), just use that. + thread_id_integer(thread::current().id()) + }); } impl<S, T> Layer<S> for OpenTelemetryLayer<S, T> @@ -475,9 +528,9 @@ where builder.trace_id = Some(self.tracer.new_trace_id()); } - let builder_attrs = builder - .attributes - .get_or_insert(Vec::with_capacity(attrs.fields().len() + 3)); + let builder_attrs = builder.attributes.get_or_insert(Vec::with_capacity( + attrs.fields().len() + self.extra_span_attrs(), + )); if self.location { let meta = attrs.metadata(); @@ -495,6 +548,17 @@ where } } + if self.with_threads { + THREAD_ID.with(|id| builder_attrs.push(KeyValue::new("thread.id", **id as i64))); + if let Some(name) = std::thread::current().name() { + // TODO(eliza): it's a bummer that we have to allocate here, but + // we can't easily get the string as a `static`. it would be + // nice if `opentelemetry` could also take `Arc<str>`s as + // `String` values... + builder_attrs.push(KeyValue::new("thread.name", name.to_owned())); + } + } + attrs.record(&mut SpanAttributeVisitor(&mut builder)); extensions.insert(OtelData { builder, parent_cx }); } @@ -718,15 +782,27 @@ impl Timings { } } +fn thread_id_integer(id: thread::ThreadId) -> u64 { + let thread_id = format!("{:?}", id); + thread_id + .trim_start_matches("ThreadId(") + .trim_end_matches(')') + .parse::<u64>() + .expect("thread ID should parse as an integer") +} + #[cfg(test)] mod tests { use super::*; use crate::OtelData; use opentelemetry::trace::{noop, SpanKind, TraceFlags}; - use std::borrow::Cow; - use std::collections::HashMap; - use std::sync::{Arc, Mutex}; - use std::time::SystemTime; + use std::{ + borrow::Cow, + collections::HashMap, + sync::{Arc, Mutex}, + thread, + time::SystemTime, + }; use tracing_subscriber::prelude::*; #[derive(Debug, Clone)] @@ -770,6 +846,14 @@ mod tests { } } + impl TestTracer { + fn with_data<T>(&self, f: impl FnOnce(&OtelData) -> T) -> T { + let lock = self.0.lock().unwrap(); + let data = lock.as_ref().expect("no span data has been recorded yet"); + f(data) + } + } + #[derive(Debug, Clone)] struct TestSpan(otel::SpanContext); impl otel::Span for TestSpan { @@ -820,15 +904,7 @@ mod tests { tracing::debug_span!("request", otel.kind = %SpanKind::Server); }); - let recorded_kind = tracer - .0 - .lock() - .unwrap() - .as_ref() - .unwrap() - .builder - .span_kind - .clone(); + let recorded_kind = tracer.with_data(|data| data.builder.span_kind.clone()); assert_eq!(recorded_kind, Some(otel::SpanKind::Server)) } @@ -840,14 +916,8 @@ mod tests { tracing::subscriber::with_default(subscriber, || { tracing::debug_span!("request", otel.status_code = ?otel::StatusCode::Ok); }); - let recorded_status_code = tracer - .0 - .lock() - .unwrap() - .as_ref() - .unwrap() - .builder - .status_code; + + let recorded_status_code = tracer.with_data(|data| data.builder.status_code); assert_eq!(recorded_status_code, Some(otel::StatusCode::Ok)) } @@ -862,16 +932,7 @@ mod tests { tracing::debug_span!("request", otel.status_message = message); }); - let recorded_status_message = tracer - .0 - .lock() - .unwrap() - .as_ref() - .unwrap() - .builder - .status_message - .clone(); - + let recorded_status_message = tracer.with_data(|data| data.builder.status_message.clone()); assert_eq!(recorded_status_message, Some(message.into())) } @@ -893,16 +954,8 @@ mod tests { tracing::debug_span!("request", otel.kind = %SpanKind::Server); }); - let recorded_trace_id = tracer - .0 - .lock() - .unwrap() - .as_ref() - .unwrap() - .parent_cx - .span() - .span_context() - .trace_id(); + let recorded_trace_id = + tracer.with_data(|data| data.parent_cx.span().span_context().trace_id()); assert_eq!(recorded_trace_id, trace_id) } @@ -919,17 +972,7 @@ mod tests { tracing::debug_span!("request"); }); - let attributes = tracer - .0 - .lock() - .unwrap() - .as_ref() - .unwrap() - .builder - .attributes - .as_ref() - .unwrap() - .clone(); + let attributes = tracer.with_data(|data| data.builder.attributes.as_ref().unwrap().clone()); let keys = attributes .iter() .map(|attr| attr.key.as_str()) @@ -1024,17 +1067,7 @@ mod tests { tracing::debug_span!("request"); }); - let attributes = tracer - .0 - .lock() - .unwrap() - .as_ref() - .unwrap() - .builder - .attributes - .as_ref() - .unwrap() - .clone(); + let attributes = tracer.with_data(|data| data.builder.attributes.as_ref().unwrap().clone()); let keys = attributes .iter() .map(|attr| attr.key.as_str()) @@ -1054,17 +1087,7 @@ mod tests { tracing::debug_span!("request"); }); - let attributes = tracer - .0 - .lock() - .unwrap() - .as_ref() - .unwrap() - .builder - .attributes - .as_ref() - .unwrap() - .clone(); + let attributes = tracer.with_data(|data| data.builder.attributes.as_ref().unwrap().clone()); let keys = attributes .iter() .map(|attr| attr.key.as_str()) @@ -1073,4 +1096,48 @@ mod tests { assert!(!keys.contains(&"code.namespace")); assert!(!keys.contains(&"code.lineno")); } + + #[test] + fn includes_thread() { + let thread = thread::current(); + let expected_name = thread + .name() + .map(|name| Value::String(Cow::Owned(name.to_owned()))); + let expected_id = Value::I64(thread_id_integer(thread.id()) as i64); + + let tracer = TestTracer(Arc::new(Mutex::new(None))); + let subscriber = tracing_subscriber::registry() + .with(layer().with_tracer(tracer.clone()).with_threads(true)); + + tracing::subscriber::with_default(subscriber, || { + tracing::debug_span!("request"); + }); + + let attributes = tracer + .with_data(|data| data.builder.attributes.as_ref().unwrap().clone()) + .drain(..) + .map(|keyval| (keyval.key.as_str().to_string(), keyval.value)) + .collect::<HashMap<_, _>>(); + assert_eq!(attributes.get("thread.name"), expected_name.as_ref()); + assert_eq!(attributes.get("thread.id"), Some(&expected_id)); + } + + #[test] + fn excludes_thread() { + let tracer = TestTracer(Arc::new(Mutex::new(None))); + let subscriber = tracing_subscriber::registry() + .with(layer().with_tracer(tracer.clone()).with_threads(false)); + + tracing::subscriber::with_default(subscriber, || { + tracing::debug_span!("request"); + }); + + let attributes = tracer.with_data(|data| data.builder.attributes.as_ref().unwrap().clone()); + let keys = attributes + .iter() + .map(|attr| attr.key.as_str()) + .collect::<Vec<&str>>(); + assert!(!keys.contains(&"thread.name")); + assert!(!keys.contains(&"thread.id")); + } } From 094783de18ef90e915030013bd5e76c2234e406f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 May 2022 13:52:19 -0700 Subject: [PATCH 12/13] chore(deps): update parking_lot requirement from >= 0.9.0, <= 0.12 to >= 0.9.0, <= 0.13 (#2143) Updates the requirements on [parking_lot](https://github.com/Amanieu/parking_lot) to permit the latest version. - [Release notes](https://github.com/Amanieu/parking_lot/releases) - [Changelog](https://github.com/Amanieu/parking_lot/blob/master/CHANGELOG.md) - [Commits](https://github.com/Amanieu/parking_lot/compare/0.12.0...0.12.1) --- updated-dependencies: - dependency-name: parking_lot dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- tracing-subscriber/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tracing-subscriber/Cargo.toml b/tracing-subscriber/Cargo.toml index 9109efc9ce..8f36c8f7eb 100644 --- a/tracing-subscriber/Cargo.toml +++ b/tracing-subscriber/Cargo.toml @@ -58,7 +58,7 @@ serde = { version = "1.0", optional = true } tracing-serde = { path = "../tracing-serde", version = "0.1.3", optional = true } # opt-in deps -parking_lot = { version = "0.12", optional = true } +parking_lot = { version = "0.13", optional = true } # registry sharded-slab = { version = "0.1.0", optional = true } From bd014f089157ab4b65b2489930fa6ae05da54076 Mon Sep 17 00:00:00 2001 From: James Liu <contact@jamessliu.com> Date: Mon, 6 Jun 2022 10:32:41 -0700 Subject: [PATCH 13/13] core, subscriber: migrate from `lazy_static` to `once_cell` (#2147) Replace `lazy_static` with `once_cell`. Fixes #2146. ## Motivation `lazy_static!`, while a declarative macro, is a macro nonetheless. It can add quite a bit of additional compilation time cost. `once_cell::sync::Lazy` does the same thing with generics, and can be used more flexibly (i.e. non-static lazily initialized values), and has been proposed to be added to `std` (see linked issue). I'm trying to reduce the compile time and dependency tree complexity of a dependent project: [bevy](https://bevyengine.org), which is using tracing. `lazy_static` and `once_cell` are both in our dependency tree and both end up doing the same thing. ## Solution Migrate to `once_cell`. --- examples/Cargo.toml | 2 +- examples/examples/hyper-echo.rs | 8 --- tracing-core/Cargo.toml | 4 +- tracing-core/src/callsite.rs | 11 ++- tracing-core/src/lib.rs | 4 -- tracing-flame/Cargo.toml | 3 +- tracing-flame/src/lib.rs | 6 +- tracing-log/Cargo.toml | 4 +- tracing-log/src/interest_cache.rs | 16 ++--- tracing-log/src/lib.rs | 14 ++-- tracing-subscriber/Cargo.toml | 6 +- .../src/filter/env/directive.rs | 70 +++++++++---------- 12 files changed, 66 insertions(+), 82 deletions(-) diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 14d2ee34de..1f829940a0 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -32,7 +32,7 @@ futures = "0.3" tokio = { version = "1.1", features = ["full"] } # env-logger example -env_logger = "0.7" +env_logger = "0.9" # tower examples tower = { version = "0.4.4", features = ["full"] } diff --git a/examples/examples/hyper-echo.rs b/examples/examples/hyper-echo.rs index 3404a8d5e9..f0396d19cf 100644 --- a/examples/examples/hyper-echo.rs +++ b/examples/examples/hyper-echo.rs @@ -92,17 +92,9 @@ async fn echo(req: Request<Body>) -> Result<Response<Body>, hyper::Error> { #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { - use tracing_log::env_logger::BuilderExt; - let subscriber = tracing_subscriber::fmt() .with_max_level(Level::TRACE) .finish(); - let mut builder = env_logger::Builder::new(); - builder - .filter(Some("hyper_echo"), log::LevelFilter::Off) - .filter(Some("hyper"), log::LevelFilter::Trace) - .emit_traces() // from `tracing_log::env_logger::BuilderExt` - .try_init()?; tracing::subscriber::set_global_default(subscriber)?; let local_addr: std::net::SocketAddr = ([127, 0, 0, 1], 3000).into(); diff --git a/tracing-core/Cargo.toml b/tracing-core/Cargo.toml index 77075846e7..cedffe7bfc 100644 --- a/tracing-core/Cargo.toml +++ b/tracing-core/Cargo.toml @@ -28,13 +28,13 @@ rust-version = "1.49.0" [features] default = ["std", "valuable/std"] -std = ["lazy_static"] +std = ["once_cell"] [badges] maintenance = { status = "actively-developed" } [dependencies] -lazy_static = { version = "1.0.2", optional = true } +once_cell = { version = "1.12", optional = true } [target.'cfg(tracing_unstable)'.dependencies] valuable = { version = "0.1.0", optional = true, default_features = false } diff --git a/tracing-core/src/callsite.rs b/tracing-core/src/callsite.rs index 573125a89a..87d084647b 100644 --- a/tracing-core/src/callsite.rs +++ b/tracing-core/src/callsite.rs @@ -253,6 +253,11 @@ static CALLSITES: Callsites = Callsites { static DISPATCHERS: Dispatchers = Dispatchers::new(); +#[cfg(feature = "std")] +static LOCKED_CALLSITES: once_cell::sync::Lazy<Mutex<Vec<&'static dyn Callsite>>> = + once_cell::sync::Lazy::new(Default::default); + +#[cfg(not(feature = "std"))] crate::lazy_static! { static ref LOCKED_CALLSITES: Mutex<Vec<&'static dyn Callsite>> = Mutex::new(Vec::new()); } @@ -510,6 +515,7 @@ mod private { #[cfg(feature = "std")] mod dispatchers { use crate::dispatcher; + use once_cell::sync::Lazy; use std::sync::{ atomic::{AtomicBool, Ordering}, RwLock, RwLockReadGuard, RwLockWriteGuard, @@ -519,9 +525,8 @@ mod dispatchers { has_just_one: AtomicBool, } - crate::lazy_static! { - static ref LOCKED_DISPATCHERS: RwLock<Vec<dispatcher::Registrar>> = RwLock::new(Vec::new()); - } + static LOCKED_DISPATCHERS: Lazy<RwLock<Vec<dispatcher::Registrar>>> = + Lazy::new(Default::default); pub(super) enum Rebuilder<'a> { JustOne, diff --git a/tracing-core/src/lib.rs b/tracing-core/src/lib.rs index 7424a6cb3f..eceef7be22 100644 --- a/tracing-core/src/lib.rs +++ b/tracing-core/src/lib.rs @@ -254,10 +254,6 @@ macro_rules! metadata { }; } -// when `std` is enabled, use the `lazy_static` crate from crates.io -#[cfg(feature = "std")] -pub(crate) use lazy_static::lazy_static; - // Facade module: `no_std` uses spinlocks, `std` uses the mutexes in the standard library #[cfg(not(feature = "std"))] #[macro_use] diff --git a/tracing-flame/Cargo.toml b/tracing-flame/Cargo.toml index 5c6b9c0ba5..43ee62c922 100644 --- a/tracing-flame/Cargo.toml +++ b/tracing-flame/Cargo.toml @@ -28,7 +28,8 @@ smallvec = ["tracing-subscriber/smallvec"] [dependencies] tracing-subscriber = { path = "../tracing-subscriber", version = "0.3", default-features = false, features = ["registry", "fmt"] } tracing = { path = "../tracing", version = "0.1.12", default-features = false, features = ["std"] } -lazy_static = "1.3.0" +once_cell = "1.12" + [dev-dependencies] tempfile = "3" diff --git a/tracing-flame/src/lib.rs b/tracing-flame/src/lib.rs index b37bae74c1..f7d670aa61 100644 --- a/tracing-flame/src/lib.rs +++ b/tracing-flame/src/lib.rs @@ -137,7 +137,7 @@ pub use error::Error; use error::Kind; -use lazy_static::lazy_static; +use once_cell::sync::Lazy; use std::cell::Cell; use std::fmt; use std::fmt::Write as _; @@ -158,9 +158,7 @@ use tracing_subscriber::Layer; mod error; -lazy_static! { - static ref START: Instant = Instant::now(); -} +static START: Lazy<Instant> = Lazy::new(Instant::now); thread_local! { static LAST_EVENT: Cell<Instant> = Cell::new(*START); diff --git a/tracing-log/Cargo.toml b/tracing-log/Cargo.toml index b482341eab..a774357788 100644 --- a/tracing-log/Cargo.toml +++ b/tracing-log/Cargo.toml @@ -27,8 +27,8 @@ interest-cache = ["lru", "ahash"] [dependencies] 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 } +once_cell = "1.12" +env_logger = { version = "0.8", optional = true } lru = { version = "0.7.0", optional = true } ahash = { version = "0.7.4", optional = true } diff --git a/tracing-log/src/interest_cache.rs b/tracing-log/src/interest_cache.rs index fb3da875eb..aabf9ebaf7 100644 --- a/tracing-log/src/interest_cache.rs +++ b/tracing-log/src/interest_cache.rs @@ -1,6 +1,7 @@ use ahash::AHasher; use log::{Level, Metadata}; use lru::LruCache; +use once_cell::sync::Lazy; use std::cell::RefCell; use std::hash::Hasher; use std::sync::atomic::{AtomicUsize, Ordering}; @@ -140,12 +141,10 @@ static SENTINEL_METADATA: tracing_core::Metadata<'static> = tracing_core::Metada tracing_core::metadata::Kind::EVENT, ); -lazy_static::lazy_static! { - static ref CONFIG: Mutex<InterestCacheConfig> = { - tracing_core::callsite::register(&SENTINEL_CALLSITE); - Mutex::new(InterestCacheConfig::disabled()) - }; -} +static CONFIG: Lazy<Mutex<InterestCacheConfig>> = Lazy::new(|| { + tracing_core::callsite::register(&SENTINEL_CALLSITE); + Mutex::new(InterestCacheConfig::disabled()) +}); thread_local! { static STATE: RefCell<State> = { @@ -236,10 +235,7 @@ mod tests { fn lock_for_test() -> impl Drop { // We need to make sure only one test runs at a time. - - lazy_static::lazy_static! { - static ref LOCK: Mutex<()> = Mutex::new(()); - } + static LOCK: Lazy<Mutex<()>> = Lazy::new(Mutex::new); match LOCK.lock() { Ok(guard) => guard, diff --git a/tracing-log/src/lib.rs b/tracing-log/src/lib.rs index 09e9114a4c..44b3f1d32d 100644 --- a/tracing-log/src/lib.rs +++ b/tracing-log/src/lib.rs @@ -128,7 +128,7 @@ unused_parens, while_true )] -use lazy_static::lazy_static; +use once_cell::sync::Lazy; use std::{fmt, io}; @@ -346,13 +346,11 @@ log_cs!( ErrorCallsite ); -lazy_static! { - static ref TRACE_FIELDS: Fields = Fields::new(&TRACE_CS); - static ref DEBUG_FIELDS: Fields = Fields::new(&DEBUG_CS); - static ref INFO_FIELDS: Fields = Fields::new(&INFO_CS); - static ref WARN_FIELDS: Fields = Fields::new(&WARN_CS); - static ref ERROR_FIELDS: Fields = Fields::new(&ERROR_CS); -} +static TRACE_FIELDS: Lazy<Fields> = Lazy::new(|| Fields::new(&TRACE_CS)); +static DEBUG_FIELDS: Lazy<Fields> = Lazy::new(|| Fields::new(&DEBUG_CS)); +static INFO_FIELDS: Lazy<Fields> = Lazy::new(|| Fields::new(&INFO_CS)); +static WARN_FIELDS: Lazy<Fields> = Lazy::new(|| Fields::new(&WARN_CS)); +static ERROR_FIELDS: Lazy<Fields> = Lazy::new(|| Fields::new(&ERROR_CS)); fn level_to_cs(level: Level) -> (&'static dyn Callsite, &'static Fields) { match level { diff --git a/tracing-subscriber/Cargo.toml b/tracing-subscriber/Cargo.toml index 8f36c8f7eb..3595318c46 100644 --- a/tracing-subscriber/Cargo.toml +++ b/tracing-subscriber/Cargo.toml @@ -27,7 +27,7 @@ rust-version = "1.49.0" default = ["smallvec", "fmt", "ansi", "tracing-log", "std"] alloc = [] std = ["alloc", "tracing-core/std"] -env-filter = ["matchers", "regex", "lazy_static", "tracing", "std", "thread_local"] +env-filter = ["matchers", "regex", "once_cell", "tracing", "std", "thread_local"] fmt = ["registry", "std"] ansi = ["fmt", "ansi_term"] registry = ["sharded-slab", "thread_local", "std"] @@ -45,7 +45,7 @@ tracing = { optional = true, path = "../tracing", version = "0.1", default-featu matchers = { optional = true, version = "0.1.0" } regex = { optional = true, version = "1", default-features = false, features = ["std"] } smallvec = { optional = true, version = "1.2.0" } -lazy_static = { optional = true, version = "1" } +once_cell = { optional = true, version = "1.12" } # fmt tracing-log = { path = "../tracing-log", version = "0.1.2", optional = true, default-features = false, features = ["log-tracer", "std"] } @@ -58,7 +58,7 @@ serde = { version = "1.0", optional = true } tracing-serde = { path = "../tracing-serde", version = "0.1.3", optional = true } # opt-in deps -parking_lot = { version = "0.13", optional = true } +parking_lot = { version = "0.12", optional = true } # registry sharded-slab = { version = "0.1.0", optional = true } diff --git a/tracing-subscriber/src/filter/env/directive.rs b/tracing-subscriber/src/filter/env/directive.rs index 3e993f6c92..f062e6ef93 100644 --- a/tracing-subscriber/src/filter/env/directive.rs +++ b/tracing-subscriber/src/filter/env/directive.rs @@ -4,7 +4,7 @@ use crate::filter::{ env::{field, FieldMap}, level::LevelFilter, }; -use lazy_static::lazy_static; +use once_cell::sync::Lazy; use regex::Regex; use std::{cmp::Ordering, fmt, iter::FromIterator, str::FromStr}; use tracing_core::{span, Level, Metadata}; @@ -120,41 +120,39 @@ impl Directive { } pub(super) fn parse(from: &str, regex: bool) -> Result<Self, ParseError> { - lazy_static! { - static ref DIRECTIVE_RE: Regex = Regex::new( - r"(?x) - ^(?P<global_level>(?i:trace|debug|info|warn|error|off|[0-5]))$ | - # ^^^. - # `note: we match log level names case-insensitively - ^ - (?: # target name or span name - (?P<target>[\w:-]+)|(?P<span>\[[^\]]*\]) - ){1,2} - (?: # level or nothing - =(?P<level>(?i:trace|debug|info|warn|error|off|[0-5]))? - # ^^^. - # `note: we match log level names case-insensitively - )? - $ - " - ) - .unwrap(); - static ref SPAN_PART_RE: Regex = - Regex::new(r#"(?P<name>[^\]\{]+)?(?:\{(?P<fields>[^\}]*)\})?"#).unwrap(); - static ref FIELD_FILTER_RE: Regex = - // TODO(eliza): this doesn't _currently_ handle value matchers that include comma - // characters. We should fix that. - Regex::new(r#"(?x) - ( - # field name - [[:word:]][[[:word:]]\.]* - # value part (optional) - (?:=[^,]+)? - ) - # trailing comma or EOS - (?:,\s?|$) - "#).unwrap(); - } + static DIRECTIVE_RE: Lazy<Regex> = Lazy::new(|| Regex::new( + r"(?x) + ^(?P<global_level>(?i:trace|debug|info|warn|error|off|[0-5]))$ | + # ^^^. + # `note: we match log level names case-insensitively + ^ + (?: # target name or span name + (?P<target>[\w:-]+)|(?P<span>\[[^\]]*\]) + ){1,2} + (?: # level or nothing + =(?P<level>(?i:trace|debug|info|warn|error|off|[0-5]))? + # ^^^. + # `note: we match log level names case-insensitively + )? + $ + " + ) + .unwrap()); + static SPAN_PART_RE: Lazy<Regex> = + Lazy::new(|| Regex::new(r#"(?P<name>[^\]\{]+)?(?:\{(?P<fields>[^\}]*)\})?"#).unwrap()); + static FIELD_FILTER_RE: Lazy<Regex> = + // TODO(eliza): this doesn't _currently_ handle value matchers that include comma + // characters. We should fix that. + Lazy::new(|| Regex::new(r#"(?x) + ( + # field name + [[:word:]][[[:word:]]\.]* + # value part (optional) + (?:=[^,]+)? + ) + # trailing comma or EOS + (?:,\s?|$) + "#).unwrap()); let caps = DIRECTIVE_RE.captures(from).ok_or_else(ParseError::new)?;