8153945: Track if log configuration has changed during runtime

Reviewed-by: lfoltan, hseigel
This commit is contained in:
Marcus Larsson 2018-02-28 10:37:02 +01:00
parent cb275ca384
commit 851718cee4
3 changed files with 52 additions and 5 deletions

View File

@ -78,6 +78,11 @@ bool ConfigurationLock::current_thread_has_lock() {
#endif
void LogConfiguration::post_initialize() {
// Reset the reconfigured status of all outputs
for (size_t i = 0; i < _n_outputs; i++) {
_outputs[i]->_reconfigured = false;
}
LogDiagnosticCommand::registerCommand();
Log(logging) log;
if (log.is_info()) {
@ -213,6 +218,8 @@ void LogConfiguration::configure_output(size_t idx, const LogSelectionList& sele
assert(idx < _n_outputs, "Invalid index, idx = " SIZE_FORMAT " and _n_outputs = " SIZE_FORMAT, idx, _n_outputs);
LogOutput* output = _outputs[idx];
output->_reconfigured = true;
// Clear the previous config description
output->clear_config_string();
@ -447,7 +454,7 @@ bool LogConfiguration::parse_log_arguments(const char* outputstr,
return true;
}
void LogConfiguration::describe_available(outputStream* out){
void LogConfiguration::describe_available(outputStream* out) {
out->print("Available log levels:");
for (size_t i = 0; i < LogLevel::Count; i++) {
out->print("%s %s", (i == 0 ? "" : ","), LogLevel::name(static_cast<LogLevelType>(i)));
@ -467,11 +474,14 @@ void LogConfiguration::describe_available(outputStream* out){
LogTagSet::describe_tagsets(out);
}
void LogConfiguration::describe_current_configuration(outputStream* out){
void LogConfiguration::describe_current_configuration(outputStream* out) {
out->print_cr("Log output configuration:");
for (size_t i = 0; i < _n_outputs; i++) {
out->print(" #" SIZE_FORMAT ": ", i);
_outputs[i]->describe(out);
if (_outputs[i]->is_reconfigured()) {
out->print(" (reconfigured)");
}
out->cr();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -43,6 +43,12 @@ class LogOutput : public CHeapObj<mtLogging> {
private:
static const size_t InitialConfigBufferSize = 256;
// Track if the output has been reconfigured dynamically during runtime.
// The status is set each time the configuration of the output is modified,
// and is reset once after logging initialization is complete.
bool _reconfigured;
char* _config_string;
size_t _config_string_buffer_size;
@ -65,11 +71,15 @@ class LogOutput : public CHeapObj<mtLogging> {
return _decorators;
}
bool is_reconfigured() const {
return _reconfigured;
}
const char* config_string() const {
return _config_string;
}
LogOutput() : _config_string(NULL), _config_string_buffer_size(0) {
LogOutput() : _reconfigured(false), _config_string(NULL), _config_string_buffer_size(0) {
}
virtual ~LogOutput();

View File

@ -225,7 +225,7 @@ TEST_VM_F(LogConfigurationTest, reconfigure_decorators) {
// Now reconfigure logging on stderr with no decorators
set_log_config("stderr", "all=off", "none");
EXPECT_TRUE(is_described("#1: stderr all=off none\n")) << "Expecting no decorators";
EXPECT_TRUE(is_described("#1: stderr all=off none (reconfigured)\n")) << "Expecting no decorators";
}
// Test that invalid options cause configuration errors
@ -414,6 +414,33 @@ TEST_VM_F(LogConfigurationTest, output_name_normalization) {
delete_file(buf);
}
static size_t count_occurrences(const char* haystack, const char* needle) {
size_t count = 0;
for (const char* p = strstr(haystack, needle); p != NULL; p = strstr(p + 1, needle)) {
count++;
}
return count;
}
TEST_OTHER_VM(LogConfiguration, output_reconfigured) {
ResourceMark rm;
stringStream ss;
EXPECT_FALSE(is_described("(reconfigured)"));
bool success = LogConfiguration::parse_log_arguments("#1", "all=warning", NULL, NULL, &ss);
ASSERT_TRUE(success);
EXPECT_EQ(0u, ss.size());
LogConfiguration::describe(&ss);
EXPECT_EQ(1u, count_occurrences(ss.as_string(), "(reconfigured)"));
ss.reset();
LogConfiguration::configure_stdout(LogLevel::Info, false, LOG_TAGS(logging));
LogConfiguration::describe(&ss);
EXPECT_EQ(2u, count_occurrences(ss.as_string(), "(reconfigured)"));
}
TEST_VM_F(LogConfigurationTest, suggest_similar_selection) {
static const char* nonexisting_tagset = "logging+start+exit+safepoint+gc";