diff --git a/src/hotspot/share/logging/logConfiguration.cpp b/src/hotspot/share/logging/logConfiguration.cpp index 194bd622b1553..662c1f1c2bb79 100644 --- a/src/hotspot/share/logging/logConfiguration.cpp +++ b/src/hotspot/share/logging/logConfiguration.cpp @@ -336,11 +336,9 @@ void LogConfiguration::disable_logging() { notify_update_listeners(); } -void LogConfiguration::configure_stdout(LogLevelType level, int exact_match, ...) { +LogSelectionList LogConfiguration::create_selection_list(LogLevelType level, int exact_match, va_list ap) { size_t i; - va_list ap; LogTagType tags[LogTag::MaxTags]; - va_start(ap, exact_match); for (i = 0; i < LogTag::MaxTags; i++) { LogTagType tag = static_cast(va_arg(ap, int)); tags[i] = tag; @@ -351,12 +349,32 @@ void LogConfiguration::configure_stdout(LogLevelType level, int exact_match, ... } assert(i < LogTag::MaxTags || static_cast(va_arg(ap, int)) == LogTag::__NO_TAG, "Too many tags specified! Can only have up to %zu tags in a tag set.", LogTag::MaxTags); - va_end(ap); LogSelection selection(tags, !exact_match, level); assert(selection.tag_sets_selected() > 0, - "configure_stdout() called with invalid/non-existing log selection"); - LogSelectionList list(selection); + "create_selection_list() called with invalid/non-existing log selection"); + return LogSelectionList(selection); +} + +void LogConfiguration::disable_tags(int exact_match, ...) { + va_list ap; + va_start(ap, exact_match); + LogSelectionList list = create_selection_list(LogLevel::Off, exact_match, ap); + va_end(ap); + + // Apply configuration to all outputs, with the same decorators as before. + ConfigurationLock cl; + for (size_t i = 0; i < _n_outputs; i++) { + configure_output(i, list, _outputs[i]->decorators()); + } + notify_update_listeners(); +} + +void LogConfiguration::configure_stdout(LogLevelType level, int exact_match, ...) { + va_list ap; + va_start(ap, exact_match); + LogSelectionList list = create_selection_list(level, exact_match, ap); + va_end(ap); // Apply configuration to stdout (output #0), with the same decorators as before. ConfigurationLock cl; diff --git a/src/hotspot/share/logging/logConfiguration.hpp b/src/hotspot/share/logging/logConfiguration.hpp index 840f6a9af57b0..6e84199fddec8 100644 --- a/src/hotspot/share/logging/logConfiguration.hpp +++ b/src/hotspot/share/logging/logConfiguration.hpp @@ -97,6 +97,8 @@ class LogConfiguration : public AllStatic { static void describe_available(outputStream* out); static void describe_current_configuration(outputStream* out); + // Create a LogSelectionList given a level and a set of tags + static LogSelectionList create_selection_list(LogLevelType level, int exact_match, va_list ap); public: // Initialization and finalization of log configuration, to be run at vm startup and shutdown respectively. @@ -109,6 +111,13 @@ class LogConfiguration : public AllStatic { // Disable all logging, equivalent to -Xlog:disable. static void disable_logging(); + // Disables logging on all outputs for the given tags. + // If exact_match is true, only tagsets with precisely the specified tags will be disabled + // (exact_match=false is the same as "-Xlog:*=off", and exact_match=true is "-Xlog:=off"). + // Tags should be specified using the LOG_TAGS macro, e.g. + // LogConfiguration::disable_tags(, LOG_TAGS()); + static void disable_tags(int exact_match, ...); + // Configures logging on stdout for the given tags and level combination. // Intended for mappings between -XX: flags and Unified Logging configuration. // If exact_match is true, only tagsets with precisely the specified tags will be configured diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index c6651c46e029f..8de6f427c3f1d 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -3800,7 +3800,8 @@ jint Arguments::apply_ergo() { if (log_is_enabled(Info, perf, class, link)) { if (!UsePerfData) { warning("Disabling -Xlog:perf+class+link since UsePerfData is turned off."); - LogConfiguration::configure_stdout(LogLevel::Off, false, LOG_TAGS(perf, class, link)); + LogConfiguration::disable_tags(false, LOG_TAGS(perf, class, link)); + assert(!log_is_enabled(Info, perf, class, link), "sanity"); } } diff --git a/test/hotspot/gtest/logging/test_logConfiguration.cpp b/test/hotspot/gtest/logging/test_logConfiguration.cpp index 918c1c71cad45..c5b15d2ac63e5 100644 --- a/test/hotspot/gtest/logging/test_logConfiguration.cpp +++ b/test/hotspot/gtest/logging/test_logConfiguration.cpp @@ -216,6 +216,32 @@ TEST_VM_F(LogConfigurationTest, disable_output) { } } +TEST_VM_F(LogConfigurationTest, disable_tags) { + set_log_config("stdout", "logging*=info"); + set_log_config(TestLogFileName, "logging*=info"); + + EXPECT_TRUE(log_is_enabled(Info, logging, gc)); + LogConfiguration::disable_tags(true, LOG_TAGS(logging, gc)); + EXPECT_FALSE(log_is_enabled(Info, logging, gc)); + EXPECT_TRUE(log_is_enabled(Info, logging)); + + set_log_config("stdout", "logging*=info"); + set_log_config(TestLogFileName, "logging*=info"); + + EXPECT_TRUE(log_is_enabled(Info, logging)); + LogConfiguration::disable_tags(true, LOG_TAGS(logging)); + EXPECT_TRUE(log_is_enabled(Info, logging, gc)); + EXPECT_FALSE(log_is_enabled(Info, logging)); + + set_log_config("stdout", "logging*=info"); + set_log_config(TestLogFileName, "logging*=info"); + + EXPECT_TRUE(log_is_enabled(Info, logging)); + LogConfiguration::disable_tags(false, LOG_TAGS(logging)); + EXPECT_FALSE(log_is_enabled(Info, logging, gc)); + EXPECT_FALSE(log_is_enabled(Info, logging)); +} + // Test reconfiguration of the selected decorators for an output TEST_VM_F(LogConfigurationTest, reconfigure_decorators) { // Configure stderr with all decorators