8153945: Track if log configuration has changed during runtime
Reviewed-by: lfoltan, hseigel
This commit is contained in:
parent
cb275ca384
commit
851718cee4
@ -78,6 +78,11 @@ bool ConfigurationLock::current_thread_has_lock() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void LogConfiguration::post_initialize() {
|
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();
|
LogDiagnosticCommand::registerCommand();
|
||||||
Log(logging) log;
|
Log(logging) log;
|
||||||
if (log.is_info()) {
|
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);
|
assert(idx < _n_outputs, "Invalid index, idx = " SIZE_FORMAT " and _n_outputs = " SIZE_FORMAT, idx, _n_outputs);
|
||||||
LogOutput* output = _outputs[idx];
|
LogOutput* output = _outputs[idx];
|
||||||
|
|
||||||
|
output->_reconfigured = true;
|
||||||
|
|
||||||
// Clear the previous config description
|
// Clear the previous config description
|
||||||
output->clear_config_string();
|
output->clear_config_string();
|
||||||
|
|
||||||
@ -447,7 +454,7 @@ bool LogConfiguration::parse_log_arguments(const char* outputstr,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogConfiguration::describe_available(outputStream* out){
|
void LogConfiguration::describe_available(outputStream* out) {
|
||||||
out->print("Available log levels:");
|
out->print("Available log levels:");
|
||||||
for (size_t i = 0; i < LogLevel::Count; i++) {
|
for (size_t i = 0; i < LogLevel::Count; i++) {
|
||||||
out->print("%s %s", (i == 0 ? "" : ","), LogLevel::name(static_cast<LogLevelType>(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);
|
LogTagSet::describe_tagsets(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogConfiguration::describe_current_configuration(outputStream* out){
|
void LogConfiguration::describe_current_configuration(outputStream* out) {
|
||||||
out->print_cr("Log output configuration:");
|
out->print_cr("Log output configuration:");
|
||||||
for (size_t i = 0; i < _n_outputs; i++) {
|
for (size_t i = 0; i < _n_outputs; i++) {
|
||||||
out->print(" #" SIZE_FORMAT ": ", i);
|
out->print(" #" SIZE_FORMAT ": ", i);
|
||||||
_outputs[i]->describe(out);
|
_outputs[i]->describe(out);
|
||||||
|
if (_outputs[i]->is_reconfigured()) {
|
||||||
|
out->print(" (reconfigured)");
|
||||||
|
}
|
||||||
out->cr();
|
out->cr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -43,6 +43,12 @@ class LogOutput : public CHeapObj<mtLogging> {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static const size_t InitialConfigBufferSize = 256;
|
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;
|
char* _config_string;
|
||||||
size_t _config_string_buffer_size;
|
size_t _config_string_buffer_size;
|
||||||
|
|
||||||
@ -65,11 +71,15 @@ class LogOutput : public CHeapObj<mtLogging> {
|
|||||||
return _decorators;
|
return _decorators;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_reconfigured() const {
|
||||||
|
return _reconfigured;
|
||||||
|
}
|
||||||
|
|
||||||
const char* config_string() const {
|
const char* config_string() const {
|
||||||
return _config_string;
|
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();
|
virtual ~LogOutput();
|
||||||
|
@ -225,7 +225,7 @@ TEST_VM_F(LogConfigurationTest, reconfigure_decorators) {
|
|||||||
|
|
||||||
// Now reconfigure logging on stderr with no decorators
|
// Now reconfigure logging on stderr with no decorators
|
||||||
set_log_config("stderr", "all=off", "none");
|
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
|
// Test that invalid options cause configuration errors
|
||||||
@ -414,6 +414,33 @@ TEST_VM_F(LogConfigurationTest, output_name_normalization) {
|
|||||||
delete_file(buf);
|
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) {
|
TEST_VM_F(LogConfigurationTest, suggest_similar_selection) {
|
||||||
static const char* nonexisting_tagset = "logging+start+exit+safepoint+gc";
|
static const char* nonexisting_tagset = "logging+start+exit+safepoint+gc";
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user