diff --git a/substrate/client/cli/src/lib.rs b/substrate/client/cli/src/lib.rs index f16d02cab51d51a77ce8ff535539ad9526ff5b7e..a973acb6f01660ae4db0400c4b7ebd28674fd9af 100644 --- a/substrate/client/cli/src/lib.rs +++ b/substrate/client/cli/src/lib.rs @@ -43,7 +43,7 @@ use structopt::{ clap::{self, AppSettings}, StructOpt, }; -use tracing_subscriber::layer::SubscriberExt; +use tracing_subscriber::{filter::Directive, layer::SubscriberExt}; /// Substrate client CLI /// @@ -234,6 +234,13 @@ pub fn init_logger( tracing_receiver: sc_tracing::TracingReceiver, tracing_targets: Option<String>, ) -> std::result::Result<(), String> { + fn parse_directives(dirs: impl AsRef<str>) -> Vec<Directive> { + dirs.as_ref() + .split(',') + .filter_map(|s| s.parse().ok()) + .collect() + } + if let Err(e) = tracing_log::LogTracer::init() { return Err(format!( "Registering Substrate logger failed: {:}!", e @@ -257,7 +264,7 @@ pub fn init_logger( if lvl != "" { // We're not sure if log or tracing is available at this moment, so silently ignore the // parse error. - if let Ok(directive) = lvl.parse() { + for directive in parse_directives(lvl) { env_filter = env_filter.add_directive(directive); } } @@ -266,7 +273,7 @@ pub fn init_logger( if pattern != "" { // We're not sure if log or tracing is available at this moment, so silently ignore the // parse error. - if let Ok(directive) = pattern.parse() { + for directive in parse_directives(pattern) { env_filter = env_filter.add_directive(directive); } } @@ -299,3 +306,47 @@ pub fn init_logger( } Ok(()) } + +#[cfg(test)] +mod tests { + use super::*; + use tracing::{metadata::Kind, subscriber::Interest, Callsite, Level, Metadata}; + + #[test] + fn test_logger_filters() { + let test_pattern = "afg=debug,sync=trace,client=warn,telemetry"; + init_logger(&test_pattern, Default::default(), Default::default()).unwrap(); + + tracing::dispatcher::get_default(|dispatcher| { + let test_filter = |target, level| { + struct DummyCallSite; + impl Callsite for DummyCallSite { + fn set_interest(&self, _: Interest) {} + fn metadata(&self) -> &Metadata<'_> { + unreachable!(); + } + } + + let metadata = tracing::metadata!( + name: "", + target: target, + level: level, + fields: &[], + callsite: &DummyCallSite, + kind: Kind::SPAN, + ); + + dispatcher.enabled(&metadata) + }; + + assert!(test_filter("afg", Level::INFO)); + assert!(test_filter("afg", Level::DEBUG)); + assert!(!test_filter("afg", Level::TRACE)); + + assert!(test_filter("sync", Level::TRACE)); + assert!(test_filter("client", Level::WARN)); + + assert!(test_filter("telemetry", Level::TRACE)); + }); + } +}