diff --git a/doc/release-notes-31767.md b/doc/release-notes-31767.md new file mode 100644 index 00000000000..f2247cfbeb0 --- /dev/null +++ b/doc/release-notes-31767.md @@ -0,0 +1,3 @@ +Logging +--- +Passing -debug=0 or -debug=none now behaves like -nodebug: previously set debug categories will be cleared, but subsequent -debug options will still be applied. diff --git a/src/init/common.cpp b/src/init/common.cpp index 70c4230cfdb..bc0a2f65080 100644 --- a/src/init/common.cpp +++ b/src/init/common.cpp @@ -80,15 +80,17 @@ util::Result SetLoggingLevel(const ArgsManager& args) util::Result SetLoggingCategories(const ArgsManager& args) { if (args.IsArgSet("-debug")) { - // Special-case: if -debug=0/-nodebug is set, turn off debugging messages const std::vector categories = args.GetArgs("-debug"); - if (std::none_of(categories.begin(), categories.end(), - [](std::string cat){return cat == "0" || cat == "none";})) { - for (const auto& cat : categories) { - if (!LogInstance().EnableCategory(cat)) { - return util::Error{strprintf(_("Unsupported logging category %s=%s."), "-debug", cat)}; - } + // Special-case: Disregard any debugging categories appearing before -debug=0/none + const auto last_negated = std::find_if(categories.rbegin(), categories.rend(), + [](const std::string& cat) { return cat == "0" || cat == "none"; }); + + const auto categories_to_process = (last_negated == categories.rend()) ? categories : std::ranges::subrange(last_negated.base(), categories.end()); + + for (const auto& cat : categories_to_process) { + if (!LogInstance().EnableCategory(cat)) { + return util::Error{strprintf(_("Unsupported logging category %s=%s."), "-debug", cat)}; } } } diff --git a/test/functional/feature_logging.py b/test/functional/feature_logging.py index ab817fd12d2..bc868d19565 100755 --- a/test/functional/feature_logging.py +++ b/test/functional/feature_logging.py @@ -99,6 +99,21 @@ class LoggingTest(BitcoinTestFramework): match=ErrorMatch.PARTIAL_REGEX, ) + self.log.info("Test that -nodebug,-debug=0,-debug=none clear previously specified debug options") + disable_debug_options = [ + '-debug=0', + '-debug=none', + '-nodebug' + ] + + for disable_debug_opt in disable_debug_options: + # Every category before disable_debug_opt will be ignored, including the invalid 'abc' + self.restart_node(0, ['-debug=http', '-debug=abc', disable_debug_opt, '-debug=rpc', '-debug=net']) + logging = self.nodes[0].logging() + assert not logging['http'] + assert 'abc' not in logging + assert logging['rpc'] + assert logging['net'] if __name__ == '__main__': LoggingTest(__file__).main()