Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

RPC to allow setting the log filter #7474

Merged
59 commits merged into from
Dec 3, 2020
Merged

RPC to allow setting the log filter #7474

59 commits merged into from
Dec 3, 2020

Conversation

mattrutherford
Copy link
Contributor

@mattrutherford mattrutherford commented Oct 31, 2020

Features to allow dynamically reloading the log filter via RPC in order to add filter directives, or reset to the original directives specified at startup:

  • Implement system_addLogFilter RPC to add log directives to the filter
  • Implement system_resetLogFilter RPC to reset the filter to it's original state
  • Create subscriber reload handle at tracing init
  • Store default directives from substrate, including CLI-supplied log directives
  • Add CLI flag to opt-out of filter reloading (due to small performance cost)

polkadot companion: paritytech/polkadot#1985

@mattrutherford mattrutherford added A3-in_progress Pull request is in progress. No review needed at this stage. B5-clientnoteworthy C1-low PR touches the given topic and has a low impact on builders. labels Oct 31, 2020
@mattrutherford mattrutherford marked this pull request as draft October 31, 2020 13:22
@github-actions github-actions bot added A0-please_review Pull request needs code review. and removed A3-in_progress Pull request is in progress. No review needed at this stage. labels Oct 31, 2020
@@ -33,7 +33,7 @@ use tracing_subscriber::{
/// Span name used for the logging prefix. See macro `sc_cli::prefix_logs_with!`
pub const PREFIX_LOG_SPAN: &str = "substrate-log-prefix";

pub(crate) struct EventFormat<T = SystemTime> {
pub struct EventFormat<T = SystemTime> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this file is now duplicated?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While working out some things I needed access to some of the types here so was considering a refactor to move this to the sc_tracing crate - it needs resolving

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mattrutherford I am confused. Do you mean moving this to the sp_tracing or sc_tracing crate? In #7328 @cecton added this stuff to cli/src/logging.rs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant to sc_tracing because it's client/tracing related code - however, the way we're implementing it now means it's not required to be there - so a refactor would be optional and probably out of scope for this PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I should probably move those in something common (sc-service I guess) that I can share with substrate-browser-utils. I will investigate that on my PR #7463 because it's blocking

@dvdplm dvdplm self-assigned this Nov 4, 2020
Comment on lines 329 to 330
// TODO: Q - There's a small cost to this, do we make it opt-in/out with cli flag?
.with_filter_reloading();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I investigated this and I think we should enable this by default until it can be proven to be significant for our use-case. In an artificial context the performance impact is significant: it's twice as slow, but we're talking about ~35ns –> ~70ns for the worst case. Once you add in all the filtering and other options we use the impact is negligible.

Benchmarks for a "complex" setup very similar to our own (but using a noop writer):

reload/complex-collector                                                                             
                        time:   [1.8996 us 1.9034 us 1.9076 us]
                        change: [-3.5626% -3.1266% -2.7425%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 1 outliers among 100 measurements (1.00%)
  1 (1.00%) high mild
reload/complex-collector-reloadable                                                                             
                        time:   [1.9313 us 1.9382 us 1.9456 us]
                        change: [-1.9828% -1.7096% -1.4540%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 1 outliers among 100 measurements (1.00%)
  1 (1.00%) high mild

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK - nice to have some figures for that. In that case I'll just add an opt-out CLI option --disable-log-reloading or similar

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One reason for leaving it on by default is that making it optional is nasty; the reloading changes the types such that I think we'd have to duplicate a lot of code (essentially everything from here to the end of the method). I don't think it's worth it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, that's a good point. But if it's not too ugly then IMO I think it's worth having - simply because if it's an optional performance configuration option implemented in tracing then I think we should mirror it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll try it out and we can see in review

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just added a commit to do this - it worked out OK, only requiring 2 lines of duplicated code - one to finish the builder, another to call a new function that accepts a generic Subscriber. I don't think there is any downside to having this feature.

@mattrutherford mattrutherford changed the title [WIP] Log reloading Log reloading Nov 9, 2020
@mattrutherford mattrutherford marked this pull request as ready for review November 9, 2020 20:39
@mattrutherford mattrutherford changed the title Log reloading RPC to allow setting the log filter Nov 9, 2020
client/cli/src/config.rs Outdated Show resolved Hide resolved
client/cli/src/config.rs Outdated Show resolved Hide resolved
client/cli/src/lib.rs Show resolved Hide resolved
client/cli/src/params/shared_params.rs Outdated Show resolved Hide resolved
client/cli/src/params/shared_params.rs Outdated Show resolved Hide resolved
client/cli/src/params/shared_params.rs Outdated Show resolved Hide resolved
client/cli/src/params/shared_params.rs Show resolved Hide resolved
client/rpc-api/src/system/mod.rs Outdated Show resolved Hide resolved
client/tracing/src/lib.rs Show resolved Hide resolved
client/tracing/src/lib.rs Outdated Show resolved Hide resolved
client/rpc/src/system/tests.rs Outdated Show resolved Hide resolved
@@ -333,3 +333,92 @@ fn system_network_remove_reserved() {
assert_eq!(runtime.block_on(good_fut), Ok(()));
assert!(runtime.block_on(bad_fut).is_err());
}

#[test]
fn test_add_reset_log_filter() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really nice test!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks! got the initial idea from the Telemetry PR by @cecton

client/cli/src/lib.rs Outdated Show resolved Hide resolved
use sc_tracing::parse_default_directive;

// Accept all valid directives and print invalid ones
fn parse_user_directives(mut env_filter: EnvFilter, dirs: &str) -> EnvFilter {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
fn parse_user_directives(mut env_filter: EnvFilter, dirs: &str) -> EnvFilter {
fn parse_user_directives(mut env_filter: EnvFilter, dirs: &str) -> std::result::Result<EnvFilter, String> {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried out this change of return type, but I reverted it because I think it means:

  1. Have to duplicate code in thew 4 other places it's called
  2. We bail on first bad directive, don't accept the rest and only print the first bad one (in case there may be more than 1 invalid)

Would it make more sense to rename the fn name to add_directives_and_print_invalid ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is completely fine to only bail out the first one. This is about telling the user that he tried an invalid configuration parameter.
He will find out about the others when fixing the first one.

This is very unlikely anyway, however I would like to have this. We already had it twice that we didn't accepted a particular directive, but silently ignored it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, before this PR it was silently ignored. So just to clarify, do you want to just eprintln the bad directive, ignore the remaining (possibly valid) directives but still start the node?

Currently it does actually eprintln all of the invalid directives so the user should be aware; and accept all valid ones.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I for one would be ok to halt the startup process and exit, with an error message Invalid logging directive: x (and if the next is invalid too, rinse&repeat until they get it right): users tend to not read logs very carefully so an eprintln will be missed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I got it now. The behavior before this PR was if init_logger fails the node continues to start - I'll fix that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, before it continued. I want, as @dvdplm that we return an error and exit the node. An eprintln would just be ignored.

client/cli/src/lib.rs Outdated Show resolved Hide resolved
client/cli/src/lib.rs Outdated Show resolved Hide resolved
client/cli/src/lib.rs Outdated Show resolved Hide resolved
client/cli/src/lib.rs Outdated Show resolved Hide resolved
mattrutherford and others added 3 commits November 30, 2020 10:05
Copy link
Member

@bkchr bkchr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some last nitpicks, otherwise it looks good! TY!

client/tracing/src/lib.rs Outdated Show resolved Hide resolved
client/tracing/src/lib.rs Show resolved Hide resolved
client/tracing/src/lib.rs Outdated Show resolved Hide resolved
client/tracing/src/lib.rs Outdated Show resolved Hide resolved
client/cli/src/lib.rs Outdated Show resolved Hide resolved
use sc_tracing::parse_default_directive;

// Accept all valid directives and print invalid ones
fn parse_user_directives(mut env_filter: EnvFilter, dirs: &str) -> EnvFilter {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is completely fine to only bail out the first one. This is about telling the user that he tried an invalid configuration parameter.
He will find out about the others when fixing the first one.

This is very unlikely anyway, however I would like to have this. We already had it twice that we didn't accepted a particular directive, but silently ignored it.

@bkchr bkchr requested a review from cecton November 30, 2020 15:44
mattrutherford and others added 8 commits November 30, 2020 16:05
Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
# Conflicts:
#	Cargo.lock
#	client/cli/Cargo.toml
#	client/executor/Cargo.toml
@mattrutherford
Copy link
Contributor Author

Should be ready for final review

Copy link
Contributor

@cecton cecton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

@mattrutherford mattrutherford removed the A0-please_review Pull request needs code review. label Dec 3, 2020
@mattrutherford
Copy link
Contributor Author

bot merge

@ghost
Copy link

ghost commented Dec 3, 2020

Trying merge.

@ghost ghost merged commit 0dfdc32 into master Dec 3, 2020
@ghost ghost deleted the log-reloading branch December 3, 2020 13:17
darkfriend77 pushed a commit to mogwaicoin/substrate that referenced this pull request Jan 11, 2021
* 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 pull request was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
C1-low PR touches the given topic and has a low impact on builders.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants