diff --git a/CHANGELOG.md b/CHANGELOG.md index 42eb05f7..e64faa5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#107]: https://github.com/elfo-rs/elfo/pull/107 +### Fixed +- logger: `tracing-log` events are now properly filtered by target when `tracing-log` feature is enabled ([#106]). + +[#106]: https://github.com/elfo-rs/elfo/pull/106 + ## [0.2.0-alpha.7] - 2023-08-11 ### Fixed - supervisor: deadlock if a router returns `Outcome::Multicast` ([#105]). diff --git a/elfo-logger/Cargo.toml b/elfo-logger/Cargo.toml index dee2a5fe..8c4e9991 100644 --- a/elfo-logger/Cargo.toml +++ b/elfo-logger/Cargo.toml @@ -10,11 +10,15 @@ license.workspace = true edition.workspace = true readme.workspace = true +[features] +tracing-log = [ "dep:tracing-log", "log" ] + [dependencies] elfo-core = { version = "0.2.0-alpha.7", path = "../elfo-core", features = ["unstable"] } elfo-utils = { version = "0.2.3", path = "../elfo-utils" } arc-swap = "1.2.0" +once_cell = { version = "1.8.0", features = ["parking_lot"] } derive_more = "0.99.11" futures-intrusive = "0.5" tokio = { version = "1.5", features = ["macros", "fs", "io-util"] } @@ -24,6 +28,8 @@ parking_lot = "0.12" sharded-slab = "0.1.1" tracing = "0.1.25" tracing-subscriber = { version = "0.3.2", features = ["env-filter", "parking_lot"] } +tracing-log = { version = "0.1.3", optional = true } +log = { version = "0.4.20", optional = true } metrics = "0.17" dashmap = "5" fxhash = "0.2.1" diff --git a/elfo-logger/src/filtering_layer.rs b/elfo-logger/src/filtering_layer.rs index ecad72b6..9d7d73b6 100644 --- a/elfo-logger/src/filtering_layer.rs +++ b/elfo-logger/src/filtering_layer.rs @@ -2,6 +2,8 @@ use std::sync::Arc; use arc_swap::ArcSwap; use fxhash::FxHashMap; +#[cfg(feature = "tracing-log")] +use once_cell::sync::OnceCell; use tracing::{metadata::LevelFilter, subscriber::Interest, Metadata, Subscriber}; use tracing_subscriber::{ filter::Targets, @@ -27,6 +29,8 @@ impl Default for FilteringConfig { struct Inner { config: ArcSwap, + #[cfg(feature = "tracing-log")] + log_metadata_name: OnceCell<&'static str>, } #[derive(Clone)] @@ -39,6 +43,8 @@ impl FilteringLayer { Self { inner: Arc::new(Inner { config: ArcSwap::new(Arc::new(FilteringConfig::default())), + #[cfg(feature = "tracing-log")] + log_metadata_name: OnceCell::new(), }), } } @@ -76,6 +82,35 @@ impl Layer for FilteringLayer { // We don't need to recheck `.targets` here, because `.register_callsite()` // would already eliminate logs that would be filtered by it. let level = *meta.level(); + + #[cfg(feature = "tracing-log")] + { + // `tracing-log` doesn't call `.register_callsite()`, so we have to recheck + // `.targets` in this one case. + let name = meta.name(); + if let Some(&log_name) = self.inner.log_metadata_name.get() { + // We've already got logs from `tracing-log`, just compare str + // pointers for performance. + if std::ptr::eq(log_name, name) { + let config = self.inner.config.load(); + if !config.targets.would_enable(meta.target(), meta.level()) { + return false; + } + } + } else if name == "log record" { + let config = self.inner.config.load(); + if !config.targets.would_enable(meta.target(), meta.level()) { + return false; + } + // That's "initialized tracing_log adapter" to set `log_metadata_name`, just + // ignore it. Any actual logs from `elfo_logger` would use `tracing`. + if meta.target() == "elfo_logger" { + self.inner.log_metadata_name.set(name).ok(); + return false; + } + } + } + scope::try_with(|scope| { if !scope.permissions().is_logging_enabled(level) { return false; diff --git a/elfo-logger/src/lib.rs b/elfo-logger/src/lib.rs index df492ce8..93d6091a 100644 --- a/elfo-logger/src/lib.rs +++ b/elfo-logger/src/lib.rs @@ -82,6 +82,19 @@ pub fn init() -> Blueprint { install_subscriber(subscriber); }; + #[cfg(feature = "tracing-log")] + { + if let Err(e) = tracing_log::LogTracer::init() { + tracing::error!( + error = &*e.to_string(), + "can't integrate with log adapter, logs produced via `log` crate might be not available", + ); + } else { + // Required to initialize `tracing-log` logs detection in `filtering_layer`. + log::error!("initialized tracing_log adapter"); + } + } + blueprint } diff --git a/elfo/Cargo.toml b/elfo/Cargo.toml index 848239ca..44bd1ade 100644 --- a/elfo/Cargo.toml +++ b/elfo/Cargo.toml @@ -26,6 +26,7 @@ test-util = ["elfo-test", "elfo-core/test-util"] network = ["elfo-network"] unstable = ["elfo-core/unstable", "elfo-telemeter/unstable" ] unstable-stuck-detection = ["elfo-core/unstable-stuck-detection"] +tracing-log = ["elfo-logger/tracing-log"] [dependencies] elfo-core = { version = "0.2.0-alpha.7", path = "../elfo-core" }