void Test_configure_stdout() { ResourceMark rm; LogHandle(logging) log; LogOutput* stdoutput = LogOutput::Stdout; // Save current stdout config and clear it char* saved_config = os::strdup_check_oom(stdoutput->config_string()); LogConfiguration::parse_log_arguments("stdout", "all=off", NULL, NULL, log.error_stream()); // Enable 'logging=info', verifying it has been set LogConfiguration::configure_stdout(LogLevel::Info, true, LOG_TAGS(logging)); assert_str_eq("logging=info,", stdoutput->config_string()); assert(log_is_enabled(Info, logging), "logging was not properly enabled"); // Enable 'gc=debug' (no wildcard), verifying no other tags are enabled LogConfiguration::configure_stdout(LogLevel::Debug, true, LOG_TAGS(gc)); // No '+' character means only single tags are enabled, and no combinations assert_char_not_in('+', stdoutput->config_string()); assert(log_is_enabled(Debug, gc), "logging was not properly enabled"); // Enable 'gc*=trace' (with wildcard), verifying at least one tag combination is enabled (gc+...) LogConfiguration::configure_stdout(LogLevel::Trace, false, LOG_TAGS(gc)); assert_char_in('+', stdoutput->config_string()); assert(log_is_enabled(Trace, gc), "logging was not properly enabled"); // Disable 'gc*' and 'logging', verifying all logging is properly disabled LogConfiguration::configure_stdout(LogLevel::Off, false, LOG_TAGS(gc)); LogConfiguration::configure_stdout(LogLevel::Off, true, LOG_TAGS(logging)); assert_str_eq("all=off", stdoutput->config_string()); // Restore saved configuration LogConfiguration::parse_log_arguments("stdout", saved_config, NULL, NULL, log.error_stream()); os::free(saved_config); }
TEST_F(LogConfigurationTest, subscribe) { ResourceMark rm; Log(logging) log; set_log_config("stdout", "logging*=trace"); LogConfiguration::register_update_listener(&Test_logconfiguration_subscribe_helper); LogConfiguration::parse_log_arguments("stdout", "logging=trace", NULL, NULL, log.error_stream()); ASSERT_EQ(1, Test_logconfiguration_subscribe_triggered); LogConfiguration::configure_stdout(LogLevel::Debug, true, LOG_TAGS(gc)); ASSERT_EQ(2, Test_logconfiguration_subscribe_triggered); LogConfiguration::disable_logging(); ASSERT_EQ(3, Test_logconfiguration_subscribe_triggered); }
TEST_F(LogConfigurationTest, configure_stdout) { // Start out with all logging disabled LogConfiguration::disable_logging(); // Enable 'logging=info', verifying it has been set LogConfiguration::configure_stdout(LogLevel::Info, true, LOG_TAGS(logging)); EXPECT_TRUE(log_is_enabled(Info, logging)); EXPECT_FALSE(log_is_enabled(Debug, logging)); EXPECT_FALSE(log_is_enabled(Info, gc)); LogTagSet* logging_ts = &LogTagSetMapping<LOG_TAGS(logging)>::tagset(); EXPECT_EQ(LogLevel::Info, logging_ts->level_for(&StdoutLog)); // Enable 'gc=debug' (no wildcard), verifying no other tags are enabled LogConfiguration::configure_stdout(LogLevel::Debug, true, LOG_TAGS(gc)); EXPECT_TRUE(log_is_enabled(Debug, gc)); EXPECT_TRUE(log_is_enabled(Info, logging)); EXPECT_FALSE(log_is_enabled(Debug, gc, heap)); for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) { if (ts->contains(PREFIX_LOG_TAG(gc))) { if (ts->ntags() == 1) { EXPECT_EQ(LogLevel::Debug, ts->level_for(&StdoutLog)); } else { EXPECT_EQ(LogLevel::Off, ts->level_for(&StdoutLog)); } } } // Enable 'gc*=trace' (with wildcard), verifying that all tag combinations with gc are enabled (gc+...) LogConfiguration::configure_stdout(LogLevel::Trace, false, LOG_TAGS(gc)); EXPECT_TRUE(log_is_enabled(Trace, gc)); EXPECT_TRUE(log_is_enabled(Trace, gc, heap)); for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) { if (ts->contains(PREFIX_LOG_TAG(gc))) { EXPECT_EQ(LogLevel::Trace, ts->level_for(&StdoutLog)); } else if (ts == logging_ts) { // Previous setting for 'logging' should remain EXPECT_EQ(LogLevel::Info, ts->level_for(&StdoutLog)); } else { EXPECT_EQ(LogLevel::Off, ts->level_for(&StdoutLog)); } } // Disable 'gc*' and 'logging', verifying all logging is properly disabled LogConfiguration::configure_stdout(LogLevel::Off, true, LOG_TAGS(logging)); EXPECT_FALSE(log_is_enabled(Error, logging)); LogConfiguration::configure_stdout(LogLevel::Off, false, LOG_TAGS(gc)); EXPECT_FALSE(log_is_enabled(Error, gc)); EXPECT_FALSE(log_is_enabled(Error, gc, heap)); for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) { EXPECT_EQ(LogLevel::Off, ts->level_for(&StdoutLog)); } }
void JvmtiTrace::initialize() { if (_initialized) { return; } SafeResourceMark rm; const char *very_end; const char *curr; if (TraceJVMTI != NULL) { curr = TraceJVMTI; } else { curr = ""; // hack in fixed tracing here } // Enable UL for JVMTI tracing if (strlen(curr) > 0) { if (!log_is_enabled(Trace, jvmti)) { log_warning(arguments)("-XX:+TraceJVMTI specified, " "but no log output configured for the 'jvmti' tag on Trace level. " "Defaulting to -Xlog:jvmti=trace"); LogConfiguration::configure_stdout(LogLevel::Trace, true, LOG_TAGS(jvmti)); } } very_end = curr + strlen(curr); while (curr < very_end) { const char *curr_end = strchr(curr, ','); if (curr_end == NULL) { curr_end = very_end; } const char *op_pos = strchr(curr, '+'); const char *minus_pos = strchr(curr, '-'); if (minus_pos != NULL && (minus_pos < op_pos || op_pos == NULL)) { op_pos = minus_pos; } char op; const char *flags = op_pos + 1; const char *flags_end = curr_end; if (op_pos == NULL || op_pos > curr_end) { flags = "ies"; flags_end = flags + strlen(flags); op_pos = curr_end; op = '+'; } else { op = *op_pos; } jbyte bits = 0; for (; flags < flags_end; ++flags) { switch (*flags) { case 'i': bits |= SHOW_IN; break; case 'I': bits |= SHOW_IN_DETAIL; break; case 'e': bits |= SHOW_ERROR; break; case 'o': bits |= SHOW_OUT; break; case 'O': bits |= SHOW_OUT_DETAIL; break; case 't': bits |= SHOW_EVENT_TRIGGER; break; case 's': bits |= SHOW_EVENT_SENT; break; default: log_warning(jvmti)("Invalid trace flag '%c'", *flags); break; } } const int FUNC = 1; const int EXCLUDE = 2; const int ALL_FUNC = 4; const int EVENT = 8; const int ALL_EVENT = 16; int domain = 0; size_t len = op_pos - curr; if (op_pos == curr) { domain = ALL_FUNC | FUNC | ALL_EVENT | EVENT | EXCLUDE; } else if (len==3 && strncmp(curr, "all", 3)==0) { domain = ALL_FUNC | FUNC | ALL_EVENT | EVENT; } else if (len==7 && strncmp(curr, "allfunc", 7)==0) { domain = ALL_FUNC | FUNC; } else if (len==4 && strncmp(curr, "func", 4)==0) { domain = ALL_FUNC | FUNC | EXCLUDE; } else if (len==8 && strncmp(curr, "allevent", 8)==0) { domain = ALL_EVENT | EVENT; } else if (len==5 && strncmp(curr, "event", 5)==0) { domain = ALL_EVENT | EVENT; } else if (len==2 && strncmp(curr, "ec", 2)==0) { _trace_event_controller = true; log_trace(jvmti)("Tracing the event controller"); } else { domain = FUNC | EVENT; // go searching } int exclude_index = 0; if (domain & FUNC) { if (domain & ALL_FUNC) { if (domain & EXCLUDE) { log_trace(jvmti)("Tracing all significant functions"); } else { log_trace(jvmti)("Tracing all functions"); } } for (int i = 0; i <= _max_function_index; ++i) { if (domain & EXCLUDE && i == _exclude_functions[exclude_index]) { ++exclude_index; } else { bool do_op = false; if (domain & ALL_FUNC) { do_op = true; } else { const char *fname = function_name(i); if (fname != NULL) { size_t fnlen = strlen(fname); if (len==fnlen && strncmp(curr, fname, fnlen)==0) { log_trace(jvmti)("Tracing the function: %s", fname); do_op = true; } } } if (do_op) { if (op == '+') { _trace_flags[i] |= bits; } else { _trace_flags[i] &= ~bits; } _on = true; } } } } if (domain & EVENT) { if (domain & ALL_EVENT) { log_trace(jvmti)("Tracing all events"); } for (int i = 0; i <= _max_event_index; ++i) { bool do_op = false; if (domain & ALL_EVENT) { do_op = true; } else { const char *ename = event_name(i); if (ename != NULL) { size_t evtlen = strlen(ename); if (len==evtlen && strncmp(curr, ename, evtlen)==0) { log_trace(jvmti)("Tracing the event: %s", ename); do_op = true; } } } if (do_op) { if (op == '+') { _event_trace_flags[i] |= bits; } else { _event_trace_flags[i] &= ~bits; } _on = true; } } } if (!_on && (domain & (FUNC|EVENT))) { log_warning(jvmti)("Trace domain not found"); } curr = curr_end + 1; } _initialized = true; }
* 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ #include "precompiled.hpp" #include "logging/logDecorations.hpp" #include "logging/logTagSet.hpp" #include "runtime/os.hpp" #include "unittest.hpp" #include "utilities/globalDefinitions.hpp" static const LogTagSet& tagset = LogTagSetMapping<LOG_TAGS(logging, safepoint)>::tagset(); static const LogDecorators default_decorators; TEST_VM(LogDecorations, level) { for (uint l = LogLevel::First; l <= LogLevel::Last; l++) { LogLevelType level = static_cast<LogLevelType>(l); // Create a decorations object for the current level LogDecorations decorations(level, tagset, default_decorators); // Verify that the level decoration matches the specified level EXPECT_STREQ(LogLevel::name(level), decorations.decoration(LogDecorators::level_decorator)); // Test changing level after object creation time LogLevelType other_level; if (l != LogLevel::Last) { other_level = static_cast<LogLevelType>(l + 1); } else {