RPC to allow setting the log filter (#7474)

* Add filter reload handle

* add RPC, move logging module from cli to tracing

* remove dup fn

* working example

* Update client/rpc-api/src/system/mod.rs

Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>

* Prefer "set" to "reload"

* Re-enable the commented out features of the logger

* Remove duplicate code

* cleanup

* unneeded lvar

* Bump to latest patch release

* Add new CLI option to disable log filter reloading,

Move profiling CLI options to SharedParams

* Apply suggestions from code review

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Applied suggestions from reviews

* Fix calls to init_logger()

* Handle errors when parsing logging directives

* Deny `system_setLogFilter` RPC by default

* One more time

* Don't ignore parse errors for log directives set via CLI or RPC

* Improve docs

* Apply suggestions from code review

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Update client/cli/src/config.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* fix merge errors

* include default directives with system_setLogFilter RPC,

implement system_rawSetLogFilter RPC to exclude defaults

* docs etc...

* update test

* refactor: rename fn

* Add a test for system_set_log_filter – NOTE: the code should likely change to return an error when bad directives are passed

* Update client/cli/src/lib.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Address review grumbles

* Add doc note on panicking behaviour

* print all invalid directives before panic

* change RPCs to: addLogFilter and resetLogFilter

* make CLI log directives default

* add comments

* restore previous behaviour to panic when hard-coded directives are invalid

* change/refactor directive parsing

* fix line width

* add test for log filter reloading

* Apply suggestions from code review

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* finish up suggestions from code review

* improve test

* change expect message

* change fn name

* Apply suggestions from code review

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* add docs, remove unused fn

* propagate Err on invalid log directive

* Update tracing-subscriber version

* Improve docs for `disable_log_reloading` CLI param

Co-authored-by: Matt <mattrutherford@users.noreply.github.com>
Co-authored-by: David <dvdplm@gmail.com>
Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
mattrutherford
2020-12-03 13:17:44 +00:00
committed by GitHub
parent f717a20446
commit 56c97ce604
18 changed files with 365 additions and 97 deletions
+69 -41
View File
@@ -27,7 +27,6 @@ pub mod arg_enums;
mod commands;
mod config;
mod error;
mod logging;
mod params;
mod runner;
@@ -48,8 +47,13 @@ use structopt::{
StructOpt,
};
use tracing_subscriber::{
filter::Directive, fmt::time::ChronoLocal, layer::SubscriberExt, FmtSubscriber, Layer,
fmt::time::ChronoLocal,
EnvFilter,
FmtSubscriber,
Layer,
layer::SubscriberExt,
};
pub use sc_tracing::logging;
pub use logging::PREFIX_LOG_SPAN;
#[doc(hidden)]
@@ -243,12 +247,16 @@ pub fn init_logger(
pattern: &str,
tracing_receiver: sc_tracing::TracingReceiver,
profiling_targets: Option<String>,
disable_log_reloading: bool,
) -> std::result::Result<(), String> {
fn parse_directives(dirs: impl AsRef<str>) -> Vec<Directive> {
dirs.as_ref()
.split(',')
.filter_map(|s| s.parse().ok())
.collect()
use sc_tracing::parse_default_directive;
// Accept all valid directives and print invalid ones
fn parse_user_directives(mut env_filter: EnvFilter, dirs: &str) -> std::result::Result<EnvFilter, String> {
for dir in dirs.split(',') {
env_filter = env_filter.add_directive(parse_default_directive(&dir)?);
}
Ok(env_filter)
}
if let Err(e) = tracing_log::LogTracer::init() {
@@ -257,33 +265,35 @@ pub fn init_logger(
))
}
let mut env_filter = tracing_subscriber::EnvFilter::default()
// Initialize filter - ensure to use `parse_default_directive` for any defaults to persist
// after log filter reloading by RPC
let mut env_filter = EnvFilter::default()
// Enable info
.add_directive(parse_default_directive("info")
.expect("provided directive is valid"))
// Disable info logging by default for some modules.
.add_directive("ws=off".parse().expect("provided directive is valid"))
.add_directive("yamux=off".parse().expect("provided directive is valid"))
.add_directive("cranelift_codegen=off".parse().expect("provided directive is valid"))
.add_directive(parse_default_directive("ws=off")
.expect("provided directive is valid"))
.add_directive(parse_default_directive("yamux=off")
.expect("provided directive is valid"))
.add_directive(parse_default_directive("cranelift_codegen=off")
.expect("provided directive is valid"))
// Set warn logging by default for some modules.
.add_directive("cranelift_wasm=warn".parse().expect("provided directive is valid"))
.add_directive("hyper=warn".parse().expect("provided directive is valid"))
// Enable info for others.
.add_directive(tracing_subscriber::filter::LevelFilter::INFO.into());
.add_directive(parse_default_directive("cranelift_wasm=warn")
.expect("provided directive is valid"))
.add_directive(parse_default_directive("hyper=warn")
.expect("provided directive is valid"));
if let Ok(lvl) = std::env::var("RUST_LOG") {
if lvl != "" {
// We're not sure if log or tracing is available at this moment, so silently ignore the
// parse error.
for directive in parse_directives(lvl) {
env_filter = env_filter.add_directive(directive);
}
env_filter = parse_user_directives(env_filter, &lvl)?;
}
}
if pattern != "" {
// We're not sure if log or tracing is available at this moment, so silently ignore the
// parse error.
for directive in parse_directives(pattern) {
env_filter = env_filter.add_directive(directive);
}
env_filter = parse_user_directives(env_filter, pattern)?;
}
// If we're only logging `INFO` entries then we'll use a simplified logging format.
@@ -293,19 +303,16 @@ pub fn init_logger(
};
// Always log the special target `sc_tracing`, overrides global level.
// Required because profiling traces are emitted via `sc_tracing`
// NOTE: this must be done after we check the `max_level_hint` otherwise
// it is always raised to `TRACE`.
env_filter = env_filter.add_directive(
"sc_tracing=trace"
.parse()
.expect("provided directive is valid"),
parse_default_directive("sc_tracing=trace").expect("provided directive is valid")
);
// Make sure to include profiling targets in the filter
if let Some(profiling_targets) = profiling_targets.clone() {
for directive in parse_directives(profiling_targets) {
env_filter = env_filter.add_directive(directive);
}
env_filter = parse_user_directives(env_filter, &profiling_targets)?;
}
let enable_color = atty::is(atty::Stream::Stderr);
@@ -315,22 +322,42 @@ pub fn init_logger(
"%Y-%m-%d %H:%M:%S%.3f".to_string()
});
let subscriber = FmtSubscriber::builder()
let subscriber_builder = FmtSubscriber::builder()
.with_env_filter(env_filter)
.with_writer(std::io::stderr)
.with_writer(std::io::stderr as _)
.event_format(logging::EventFormat {
timer,
enable_color,
display_target: !simple,
display_level: !simple,
display_thread_name: !simple,
enable_color,
})
.finish()
.with(logging::NodeNameLayer);
});
if disable_log_reloading {
let subscriber = subscriber_builder
.finish()
.with(logging::NodeNameLayer);
initialize_tracing(subscriber, tracing_receiver, profiling_targets)
} else {
let subscriber_builder = subscriber_builder.with_filter_reloading();
let handle = subscriber_builder.reload_handle();
sc_tracing::set_reload_handle(handle);
let subscriber = subscriber_builder
.finish()
.with(logging::NodeNameLayer);
initialize_tracing(subscriber, tracing_receiver, profiling_targets)
}
}
fn initialize_tracing<S>(
subscriber: S,
tracing_receiver: sc_tracing::TracingReceiver,
profiling_targets: Option<String>,
) -> std::result::Result<(), String>
where
S: tracing::Subscriber + Send + Sync + 'static,
{
if let Some(profiling_targets) = profiling_targets {
let profiling = sc_tracing::ProfilingLayer::new(tracing_receiver, &profiling_targets);
if let Err(e) = tracing::subscriber::set_global_default(subscriber.with(profiling)) {
return Err(format!(
"Registering Substrate tracing subscriber failed: {:}!", e
@@ -339,7 +366,7 @@ pub fn init_logger(
} else {
if let Err(e) = tracing::subscriber::set_global_default(subscriber) {
return Err(format!(
"Registering Substrate tracing subscriber failed: {:}!", e
"Registering Substrate tracing subscriber failed: {:}!", e
))
}
}
@@ -356,7 +383,7 @@ mod tests {
#[test]
fn test_logger_filters() {
let test_pattern = "afg=debug,sync=trace,client=warn,telemetry,something-with-dash=error";
init_logger(&test_pattern, Default::default(), Default::default()).unwrap();
init_logger(&test_pattern, Default::default(), Default::default(), false).unwrap();
tracing::dispatcher::get_default(|dispatcher| {
let test_filter = |target, level| {
@@ -415,7 +442,7 @@ mod tests {
fn log_something_with_dash_target_name() {
if env::var("ENABLE_LOGGING").is_ok() {
let test_pattern = "test-target=info";
init_logger(&test_pattern, Default::default(), Default::default()).unwrap();
init_logger(&test_pattern, Default::default(), Default::default(), false).unwrap();
log::info!(target: "test-target", "{}", EXPECTED_LOG_MESSAGE);
}
@@ -450,7 +477,8 @@ mod tests {
#[test]
fn prefix_in_log_lines_entrypoint() {
if env::var("ENABLE_LOGGING").is_ok() {
init_logger("", Default::default(), Default::default()).unwrap();
let test_pattern = "test-target=info";
init_logger(&test_pattern, Default::default(), Default::default(), false).unwrap();
prefix_in_log_lines_process();
}
}
@@ -466,7 +494,7 @@ mod tests {
#[test]
fn do_not_write_with_colors_on_tty_entrypoint() {
if env::var("ENABLE_LOGGING").is_ok() {
init_logger("", Default::default(), Default::default()).unwrap();
init_logger("", Default::default(), Default::default(), false).unwrap();
log::info!("{}", ansi_term::Colour::Yellow.paint(EXPECTED_LOG_MESSAGE));
}
}