Skip to content

Commit 29b265d

Browse files
james7132hawkw
authored andcommitted
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`.
1 parent 0130df7 commit 29b265d

File tree

12 files changed

+66
-82
lines changed

12 files changed

+66
-82
lines changed

examples/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ futures = "0.3"
3232
tokio = { version = "1.1", features = ["full"] }
3333

3434
# env-logger example
35-
env_logger = "0.7"
35+
env_logger = "0.9"
3636

3737
# tower examples
3838
tower = { version = "0.4.4", features = ["full"] }

examples/examples/hyper-echo.rs

-8
Original file line numberDiff line numberDiff line change
@@ -92,17 +92,9 @@ async fn echo(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
9292

9393
#[tokio::main]
9494
async fn main() -> Result<(), Box<dyn std::error::Error>> {
95-
use tracing_log::env_logger::BuilderExt;
96-
9795
let subscriber = tracing_subscriber::fmt()
9896
.with_max_level(Level::TRACE)
9997
.finish();
100-
let mut builder = env_logger::Builder::new();
101-
builder
102-
.filter(Some("hyper_echo"), log::LevelFilter::Off)
103-
.filter(Some("hyper"), log::LevelFilter::Trace)
104-
.emit_traces() // from `tracing_log::env_logger::BuilderExt`
105-
.try_init()?;
10698
tracing::subscriber::set_global_default(subscriber)?;
10799

108100
let local_addr: std::net::SocketAddr = ([127, 0, 0, 1], 3000).into();

tracing-core/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ rust-version = "1.49.0"
2828

2929
[features]
3030
default = ["std", "valuable/std"]
31-
std = ["lazy_static"]
31+
std = ["once_cell"]
3232

3333
[badges]
3434
maintenance = { status = "actively-developed" }
3535

3636
[dependencies]
37-
lazy_static = { version = "1.0.2", optional = true }
37+
once_cell = { version = "1.12", optional = true }
3838

3939
[target.'cfg(tracing_unstable)'.dependencies]
4040
valuable = { version = "0.1.0", optional = true, default_features = false }

tracing-core/src/callsite.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,11 @@ static CALLSITES: Callsites = Callsites {
253253

254254
static DISPATCHERS: Dispatchers = Dispatchers::new();
255255

256+
#[cfg(feature = "std")]
257+
static LOCKED_CALLSITES: once_cell::sync::Lazy<Mutex<Vec<&'static dyn Callsite>>> =
258+
once_cell::sync::Lazy::new(Default::default);
259+
260+
#[cfg(not(feature = "std"))]
256261
crate::lazy_static! {
257262
static ref LOCKED_CALLSITES: Mutex<Vec<&'static dyn Callsite>> = Mutex::new(Vec::new());
258263
}
@@ -510,6 +515,7 @@ mod private {
510515
#[cfg(feature = "std")]
511516
mod dispatchers {
512517
use crate::dispatcher;
518+
use once_cell::sync::Lazy;
513519
use std::sync::{
514520
atomic::{AtomicBool, Ordering},
515521
RwLock, RwLockReadGuard, RwLockWriteGuard,
@@ -519,9 +525,8 @@ mod dispatchers {
519525
has_just_one: AtomicBool,
520526
}
521527

522-
crate::lazy_static! {
523-
static ref LOCKED_DISPATCHERS: RwLock<Vec<dispatcher::Registrar>> = RwLock::new(Vec::new());
524-
}
528+
static LOCKED_DISPATCHERS: Lazy<RwLock<Vec<dispatcher::Registrar>>> =
529+
Lazy::new(Default::default);
525530

526531
pub(super) enum Rebuilder<'a> {
527532
JustOne,

tracing-core/src/lib.rs

-4
Original file line numberDiff line numberDiff line change
@@ -254,10 +254,6 @@ macro_rules! metadata {
254254
};
255255
}
256256

257-
// when `std` is enabled, use the `lazy_static` crate from crates.io
258-
#[cfg(feature = "std")]
259-
pub(crate) use lazy_static::lazy_static;
260-
261257
// Facade module: `no_std` uses spinlocks, `std` uses the mutexes in the standard library
262258
#[cfg(not(feature = "std"))]
263259
#[macro_use]

tracing-flame/Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ smallvec = ["tracing-subscriber/smallvec"]
2828
[dependencies]
2929
tracing-subscriber = { path = "../tracing-subscriber", version = "0.3", default-features = false, features = ["registry", "fmt"] }
3030
tracing = { path = "../tracing", version = "0.1.12", default-features = false, features = ["std"] }
31-
lazy_static = "1.3.0"
31+
once_cell = "1.12"
32+
3233

3334
[dev-dependencies]
3435
tempfile = "3"

tracing-flame/src/lib.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@
137137
pub use error::Error;
138138

139139
use error::Kind;
140-
use lazy_static::lazy_static;
140+
use once_cell::sync::Lazy;
141141
use std::cell::Cell;
142142
use std::fmt;
143143
use std::fmt::Write as _;
@@ -158,9 +158,7 @@ use tracing_subscriber::Layer;
158158

159159
mod error;
160160

161-
lazy_static! {
162-
static ref START: Instant = Instant::now();
163-
}
161+
static START: Lazy<Instant> = Lazy::new(Instant::now);
164162

165163
thread_local! {
166164
static LAST_EVENT: Cell<Instant> = Cell::new(*START);

tracing-log/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ interest-cache = ["lru", "ahash"]
2727
[dependencies]
2828
tracing-core = { path = "../tracing-core", version = "0.1.17"}
2929
log = { version = "0.4" }
30-
lazy_static = "1.3.0"
31-
env_logger = { version = "0.7", optional = true }
30+
once_cell = "1.12"
31+
env_logger = { version = "0.8", optional = true }
3232
lru = { version = "0.7.0", optional = true }
3333
ahash = { version = "0.7.4", optional = true }
3434

tracing-log/src/interest_cache.rs

+6-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use ahash::AHasher;
22
use log::{Level, Metadata};
33
use lru::LruCache;
4+
use once_cell::sync::Lazy;
45
use std::cell::RefCell;
56
use std::hash::Hasher;
67
use std::sync::atomic::{AtomicUsize, Ordering};
@@ -140,12 +141,10 @@ static SENTINEL_METADATA: tracing_core::Metadata<'static> = tracing_core::Metada
140141
tracing_core::metadata::Kind::EVENT,
141142
);
142143

143-
lazy_static::lazy_static! {
144-
static ref CONFIG: Mutex<InterestCacheConfig> = {
145-
tracing_core::callsite::register(&SENTINEL_CALLSITE);
146-
Mutex::new(InterestCacheConfig::disabled())
147-
};
148-
}
144+
static CONFIG: Lazy<Mutex<InterestCacheConfig>> = Lazy::new(|| {
145+
tracing_core::callsite::register(&SENTINEL_CALLSITE);
146+
Mutex::new(InterestCacheConfig::disabled())
147+
});
149148

150149
thread_local! {
151150
static STATE: RefCell<State> = {
@@ -236,10 +235,7 @@ mod tests {
236235

237236
fn lock_for_test() -> impl Drop {
238237
// We need to make sure only one test runs at a time.
239-
240-
lazy_static::lazy_static! {
241-
static ref LOCK: Mutex<()> = Mutex::new(());
242-
}
238+
static LOCK: Lazy<Mutex<()>> = Lazy::new(Mutex::new);
243239

244240
match LOCK.lock() {
245241
Ok(guard) => guard,

tracing-log/src/lib.rs

+6-8
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@
128128
unused_parens,
129129
while_true
130130
)]
131-
use lazy_static::lazy_static;
131+
use once_cell::sync::Lazy;
132132

133133
use std::{fmt, io};
134134

@@ -346,13 +346,11 @@ log_cs!(
346346
ErrorCallsite
347347
);
348348

349-
lazy_static! {
350-
static ref TRACE_FIELDS: Fields = Fields::new(&TRACE_CS);
351-
static ref DEBUG_FIELDS: Fields = Fields::new(&DEBUG_CS);
352-
static ref INFO_FIELDS: Fields = Fields::new(&INFO_CS);
353-
static ref WARN_FIELDS: Fields = Fields::new(&WARN_CS);
354-
static ref ERROR_FIELDS: Fields = Fields::new(&ERROR_CS);
355-
}
349+
static TRACE_FIELDS: Lazy<Fields> = Lazy::new(|| Fields::new(&TRACE_CS));
350+
static DEBUG_FIELDS: Lazy<Fields> = Lazy::new(|| Fields::new(&DEBUG_CS));
351+
static INFO_FIELDS: Lazy<Fields> = Lazy::new(|| Fields::new(&INFO_CS));
352+
static WARN_FIELDS: Lazy<Fields> = Lazy::new(|| Fields::new(&WARN_CS));
353+
static ERROR_FIELDS: Lazy<Fields> = Lazy::new(|| Fields::new(&ERROR_CS));
356354

357355
fn level_to_cs(level: Level) -> (&'static dyn Callsite, &'static Fields) {
358356
match level {

tracing-subscriber/Cargo.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ rust-version = "1.49.0"
2727
default = ["smallvec", "fmt", "ansi", "tracing-log", "std"]
2828
alloc = []
2929
std = ["alloc", "tracing-core/std"]
30-
env-filter = ["matchers", "regex", "lazy_static", "tracing", "std", "thread_local"]
30+
env-filter = ["matchers", "regex", "once_cell", "tracing", "std", "thread_local"]
3131
fmt = ["registry", "std"]
3232
ansi = ["fmt", "ansi_term"]
3333
registry = ["sharded-slab", "thread_local", "std"]
@@ -45,7 +45,7 @@ tracing = { optional = true, path = "../tracing", version = "0.1", default-featu
4545
matchers = { optional = true, version = "0.1.0" }
4646
regex = { optional = true, version = "1", default-features = false, features = ["std"] }
4747
smallvec = { optional = true, version = "1.2.0" }
48-
lazy_static = { optional = true, version = "1" }
48+
once_cell = { optional = true, version = "1.12" }
4949

5050
# fmt
5151
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 }
5858
tracing-serde = { path = "../tracing-serde", version = "0.1.3", optional = true }
5959

6060
# opt-in deps
61-
parking_lot = { version = "0.13", optional = true }
61+
parking_lot = { version = "0.12", optional = true }
6262

6363
# registry
6464
sharded-slab = { version = "0.1.0", optional = true }

tracing-subscriber/src/filter/env/directive.rs

+34-36
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::filter::{
44
env::{field, FieldMap},
55
level::LevelFilter,
66
};
7-
use lazy_static::lazy_static;
7+
use once_cell::sync::Lazy;
88
use regex::Regex;
99
use std::{cmp::Ordering, fmt, iter::FromIterator, str::FromStr};
1010
use tracing_core::{span, Level, Metadata};
@@ -120,41 +120,39 @@ impl Directive {
120120
}
121121

122122
pub(super) fn parse(from: &str, regex: bool) -> Result<Self, ParseError> {
123-
lazy_static! {
124-
static ref DIRECTIVE_RE: Regex = Regex::new(
125-
r"(?x)
126-
^(?P<global_level>(?i:trace|debug|info|warn|error|off|[0-5]))$ |
127-
# ^^^.
128-
# `note: we match log level names case-insensitively
129-
^
130-
(?: # target name or span name
131-
(?P<target>[\w:-]+)|(?P<span>\[[^\]]*\])
132-
){1,2}
133-
(?: # level or nothing
134-
=(?P<level>(?i:trace|debug|info|warn|error|off|[0-5]))?
135-
# ^^^.
136-
# `note: we match log level names case-insensitively
137-
)?
138-
$
139-
"
140-
)
141-
.unwrap();
142-
static ref SPAN_PART_RE: Regex =
143-
Regex::new(r#"(?P<name>[^\]\{]+)?(?:\{(?P<fields>[^\}]*)\})?"#).unwrap();
144-
static ref FIELD_FILTER_RE: Regex =
145-
// TODO(eliza): this doesn't _currently_ handle value matchers that include comma
146-
// characters. We should fix that.
147-
Regex::new(r#"(?x)
148-
(
149-
# field name
150-
[[:word:]][[[:word:]]\.]*
151-
# value part (optional)
152-
(?:=[^,]+)?
153-
)
154-
# trailing comma or EOS
155-
(?:,\s?|$)
156-
"#).unwrap();
157-
}
123+
static DIRECTIVE_RE: Lazy<Regex> = Lazy::new(|| Regex::new(
124+
r"(?x)
125+
^(?P<global_level>(?i:trace|debug|info|warn|error|off|[0-5]))$ |
126+
# ^^^.
127+
# `note: we match log level names case-insensitively
128+
^
129+
(?: # target name or span name
130+
(?P<target>[\w:-]+)|(?P<span>\[[^\]]*\])
131+
){1,2}
132+
(?: # level or nothing
133+
=(?P<level>(?i:trace|debug|info|warn|error|off|[0-5]))?
134+
# ^^^.
135+
# `note: we match log level names case-insensitively
136+
)?
137+
$
138+
"
139+
)
140+
.unwrap());
141+
static SPAN_PART_RE: Lazy<Regex> =
142+
Lazy::new(|| Regex::new(r#"(?P<name>[^\]\{]+)?(?:\{(?P<fields>[^\}]*)\})?"#).unwrap());
143+
static FIELD_FILTER_RE: Lazy<Regex> =
144+
// TODO(eliza): this doesn't _currently_ handle value matchers that include comma
145+
// characters. We should fix that.
146+
Lazy::new(|| Regex::new(r#"(?x)
147+
(
148+
# field name
149+
[[:word:]][[[:word:]]\.]*
150+
# value part (optional)
151+
(?:=[^,]+)?
152+
)
153+
# trailing comma or EOS
154+
(?:,\s?|$)
155+
"#).unwrap());
158156

159157
let caps = DIRECTIVE_RE.captures(from).ok_or_else(ParseError::new)?;
160158

0 commit comments

Comments
 (0)