8293873: Centralize the initialization of UL

Reviewed-by: stuefe, rehn
This commit is contained in:
Johan Sjölen 2022-10-24 09:12:59 +00:00
parent 08d3ef4fe6
commit 89a94d0502
10 changed files with 66 additions and 94 deletions

View File

@ -102,12 +102,21 @@ void LogConfiguration::post_initialize() {
}
void LogConfiguration::initialize(jlong vm_start_time) {
StdoutLog = new LogStdoutOutput();
StderrLog = new LogStderrOutput();
LogFileOutput::set_file_name_parameters(vm_start_time);
assert(_outputs == NULL, "Should not initialize _outputs before this function, initialize called twice?");
_outputs = NEW_C_HEAP_ARRAY(LogOutput*, 2, mtLogging);
_outputs[0] = &StdoutLog;
_outputs[1] = &StderrLog;
_outputs[0] = StdoutLog;
_outputs[1] = StderrLog;
_n_outputs = 2;
_outputs[0]->set_config_string("all=warning");
_outputs[1]->set_config_string("all=off");
// Set the default output to warning and error level for all new tagsets.
for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
ts->set_output_level(StdoutLog, LogLevel::Default);
}
}
void LogConfiguration::finalize() {
@ -411,13 +420,13 @@ bool LogConfiguration::parse_command_line_arguments(const char* opts) {
static bool stderr_configured = false;
// Normally options can't be used to change an existing output
// (parse_log_arguments() will report an error), and
// both StdoutLog and StderrLog are created by static initializers,
// so we have to process their options (e.g. foldmultilines) directly first.
// (parse_log_arguments() will report an error), but we make an exception for
// both StdoutLog and StderrLog as they're initialized automatically
// very early in the boot process.
if (output == NULL || strlen(output) == 0 ||
strcmp("stdout", output) == 0 || strcmp("#0", output) == 0) {
if (!stdout_configured) {
success = StdoutLog.parse_options(output_options, &ss);
success = StdoutLog->parse_options(output_options, &ss);
stdout_configured = true;
// We no longer need to pass output options to parse_log_arguments().
output_options = NULL;
@ -426,7 +435,7 @@ bool LogConfiguration::parse_command_line_arguments(const char* opts) {
// with a warning
} else if (strcmp("stderr", output) == 0 || strcmp("#1", output) == 0) {
if (!stderr_configured) {
success = StderrLog.parse_options(output_options, &ss);
success = StderrLog->parse_options(output_options, &ss);
stderr_configured = true;
// We no longer need to pass output options to parse_log_arguments().
output_options = NULL;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2022, 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
@ -32,27 +32,8 @@
#include "utilities/defaultStream.hpp"
const char* const LogFileStreamOutput::FoldMultilinesOptionKey = "foldmultilines";
static bool initialized;
static union {
char stdoutmem[sizeof(LogStdoutOutput)];
jlong dummy;
} aligned_stdoutmem;
static union {
char stderrmem[sizeof(LogStderrOutput)];
jlong dummy;
} aligned_stderrmem;
LogStdoutOutput &StdoutLog = reinterpret_cast<LogStdoutOutput&>(aligned_stdoutmem.stdoutmem);
LogStderrOutput &StderrLog = reinterpret_cast<LogStderrOutput&>(aligned_stderrmem.stderrmem);
LogFileStreamInitializer::LogFileStreamInitializer() {
if (!initialized) {
::new (&StdoutLog) LogStdoutOutput();
::new (&StderrLog) LogStderrOutput();
initialized = true;
}
}
LogStdoutOutput* StdoutLog = nullptr;
LogStderrOutput* StderrLog = nullptr;
bool LogFileStreamOutput::set_option(const char* key, const char* value, outputStream* errstream) {
bool success = false;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2022, 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
@ -31,14 +31,6 @@
class LogDecorations;
class LogFileStreamInitializer {
public:
LogFileStreamInitializer();
};
// Ensure the default log streams have been initialized (stdout, stderr) using the static initializer below
static LogFileStreamInitializer log_stream_initializer;
// Base class for all FileStream-based log outputs.
class LogFileStreamOutput : public LogOutput {
private:
@ -72,13 +64,11 @@ class LogFileStreamOutput : public LogOutput {
class LogStdoutOutput : public LogFileStreamOutput {
friend class LogFileStreamInitializer;
private:
LogStdoutOutput() : LogFileStreamOutput(stdout) {
set_config_string("all=warning");
}
virtual bool initialize(const char* options, outputStream* errstream) {
return false;
}
public:
LogStdoutOutput() : LogFileStreamOutput(stdout) {}
virtual const char* name() const {
return "stdout";
}
@ -87,19 +77,17 @@ class LogStdoutOutput : public LogFileStreamOutput {
class LogStderrOutput : public LogFileStreamOutput {
friend class LogFileStreamInitializer;
private:
LogStderrOutput() : LogFileStreamOutput(stderr) {
set_config_string("all=off");
}
virtual bool initialize(const char* options, outputStream* errstream) {
return false;
}
public:
LogStderrOutput() : LogFileStreamOutput(stderr) {}
virtual const char* name() const {
return "stderr";
}
};
extern LogStderrOutput &StderrLog;
extern LogStdoutOutput &StdoutLog;
extern LogStderrOutput* StderrLog;
extern LogStdoutOutput* StdoutLog;
#endif // SHARE_LOGGING_LOGFILESTREAMOUTPUT_HPP

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2022, 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
@ -48,6 +48,7 @@ class LogOutput : public CHeapObj<mtLogging> {
// 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.
// This is only used during logging of the configuration.
bool _reconfigured;
char* _config_string;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2022, 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
@ -51,9 +51,6 @@ LogTagSet::LogTagSet(PrefixWriter prefix_writer, LogTagType t0, LogTagType t1, L
}
_list = this;
_ntagsets++;
// Set the default output to warning and error level for all new tagsets.
_output_list.set_output_level(&StdoutLog, LogLevel::Default);
}
void LogTagSet::update_decorators(const LogDecorators& decorator) {

View File

@ -32,9 +32,7 @@
#include "jvmci/jvmci.hpp"
#endif
#include "interpreter/bytecodes.hpp"
#include "logging/log.hpp"
#include "logging/logAsyncWriter.hpp"
#include "logging/logTag.hpp"
#include "memory/universe.hpp"
#include "prims/jvmtiExport.hpp"
#include "prims/methodHandles.hpp"

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2022, 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
@ -23,8 +23,6 @@
*/
#include "precompiled.hpp"
#include "logging/log.hpp"
#include "logging/logStream.hpp"
#include "runtime/vm_version.hpp"
#include "services/attachListener.hpp"
#include "services/management.hpp"

View File

@ -71,8 +71,8 @@ TEST_VM_F(LogConfigurationTest, describe) {
const char* description = ss.as_string();
// Verify that stdout and stderr are listed by default
EXPECT_PRED2(string_contains_substring, description, StdoutLog.name());
EXPECT_PRED2(string_contains_substring, description, StderrLog.name());
EXPECT_PRED2(string_contains_substring, description, StdoutLog->name());
EXPECT_PRED2(string_contains_substring, description, StderrLog->name());
// Verify that each tag, level and decorator is listed
for (size_t i = 0; i < LogTag::Count; i++) {
@ -129,7 +129,7 @@ TEST_VM_F(LogConfigurationTest, update_output) {
EXPECT_TRUE(is_described("all=info"));
// Verify by iterating over tagsets
LogOutput* o = &StdoutLog;
LogOutput* o = StdoutLog;
for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
EXPECT_TRUE(ts->has_output(o));
EXPECT_TRUE(ts->is_level(LogLevel::Info));
@ -181,8 +181,8 @@ TEST_VM_F(LogConfigurationTest, disable_logging) {
// Verify that no tagset has logging enabled
for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
EXPECT_FALSE(ts->has_output(&StdoutLog));
EXPECT_FALSE(ts->has_output(&StderrLog));
EXPECT_FALSE(ts->has_output(StdoutLog));
EXPECT_FALSE(ts->has_output(StderrLog));
EXPECT_FALSE(ts->is_level(LogLevel::Error));
}
}
@ -196,7 +196,7 @@ TEST_VM_F(LogConfigurationTest, disable_output) {
EXPECT_TRUE(is_described("#0: stdout all=off"));
// Verify by iterating over tagsets
LogOutput* o = &StdoutLog;
LogOutput* o = StdoutLog;
for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
EXPECT_FALSE(ts->has_output(o));
EXPECT_FALSE(ts->is_level(LogLevel::Error));
@ -336,7 +336,7 @@ TEST_VM_F(LogConfigurationTest, parse_empty_command_line_arguments) {
bool ret = LogConfiguration::parse_command_line_arguments(cmdline);
EXPECT_TRUE(ret) << "Error parsing command line arguments '" << cmdline << "'";
for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
EXPECT_EQ(LogLevel::Unspecified, ts->level_for(&StdoutLog));
EXPECT_EQ(LogLevel::Unspecified, ts->level_for(StdoutLog));
}
}
}
@ -418,7 +418,7 @@ TEST_VM_F(LogConfigurationTest, configure_stdout) {
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));
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));
@ -428,9 +428,9 @@ TEST_VM_F(LogConfigurationTest, configure_stdout) {
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));
EXPECT_EQ(LogLevel::Debug, ts->level_for(StdoutLog));
} else {
EXPECT_EQ(LogLevel::Off, ts->level_for(&StdoutLog));
EXPECT_EQ(LogLevel::Off, ts->level_for(StdoutLog));
}
}
}
@ -441,12 +441,12 @@ TEST_VM_F(LogConfigurationTest, configure_stdout) {
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));
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));
EXPECT_EQ(LogLevel::Info, ts->level_for(StdoutLog));
} else {
EXPECT_EQ(LogLevel::Off, ts->level_for(&StdoutLog));
EXPECT_EQ(LogLevel::Off, ts->level_for(StdoutLog));
}
}
@ -457,7 +457,7 @@ TEST_VM_F(LogConfigurationTest, configure_stdout) {
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));
EXPECT_EQ(LogLevel::Off, ts->level_for(StdoutLog));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2022, 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
@ -174,7 +174,7 @@ TEST(LogOutputList, is_level_single_output) {
for (size_t i = LogLevel::First; i < LogLevel::Count; i++) {
LogLevelType level = static_cast<LogLevelType>(i);
LogOutputList list;
list.set_output_level(&StdoutLog, level);
list.set_output_level(StdoutLog, level);
for (size_t j = LogLevel::First; j < LogLevel::Count; j++) {
LogLevelType other = static_cast<LogLevelType>(j);
// Verify that levels finer than the current level for stdout are reported as disabled,
@ -202,8 +202,8 @@ TEST(LogOutputList, is_level_empty) {
// Test is_level() on lists with two outputs on different levels
TEST(LogOutputList, is_level_multiple_outputs) {
for (size_t i = LogLevel::First; i < LogLevel::Count - 1; i++) {
LogOutput* dummy1 = &StdoutLog;
LogOutput* dummy2 = &StderrLog;
LogOutput* dummy1 = StdoutLog;
LogOutput* dummy2 = StderrLog;
LogLevelType first = static_cast<LogLevelType>(i);
LogLevelType second = static_cast<LogLevelType>(i + 1);
LogOutputList list;
@ -227,19 +227,19 @@ TEST(LogOutputList, level_for) {
LogOutputList list;
// Ask the empty list about stdout, stderr
EXPECT_EQ(LogLevel::Off, list.level_for(&StdoutLog));
EXPECT_EQ(LogLevel::Off, list.level_for(&StderrLog));
EXPECT_EQ(LogLevel::Off, list.level_for(StdoutLog));
EXPECT_EQ(LogLevel::Off, list.level_for(StderrLog));
// Ask for level in a list with two outputs on different levels
list.set_output_level(&StdoutLog, LogLevel::Info);
list.set_output_level(&StderrLog, LogLevel::Trace);
EXPECT_EQ(LogLevel::Info, list.level_for(&StdoutLog));
EXPECT_EQ(LogLevel::Trace, list.level_for(&StderrLog));
list.set_output_level(StdoutLog, LogLevel::Info);
list.set_output_level(StderrLog, LogLevel::Trace);
EXPECT_EQ(LogLevel::Info, list.level_for(StdoutLog));
EXPECT_EQ(LogLevel::Trace, list.level_for(StderrLog));
// Remove and ask again
list.set_output_level(&StdoutLog, LogLevel::Off);
EXPECT_EQ(LogLevel::Off, list.level_for(&StdoutLog));
EXPECT_EQ(LogLevel::Trace, list.level_for(&StderrLog));
list.set_output_level(StdoutLog, LogLevel::Off);
EXPECT_EQ(LogLevel::Off, list.level_for(StdoutLog));
EXPECT_EQ(LogLevel::Trace, list.level_for(StderrLog));
// Ask about an unknown output
LogOutput* dummy = dummy_output(4711);
@ -252,5 +252,5 @@ TEST(LogOutputList, level_for) {
}
// Make sure the stderr level is still the same
EXPECT_EQ(LogLevel::Trace, list.level_for(&StderrLog));
EXPECT_EQ(LogLevel::Trace, list.level_for(StderrLog));
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2022, 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
@ -39,18 +39,18 @@ TEST(LogTagSet, defaults) {
EXPECT_TRUE(ts->is_level(LogLevel::Error));
EXPECT_TRUE(ts->is_level(LogLevel::Warning));
EXPECT_FALSE(ts->is_level(LogLevel::Info));
EXPECT_TRUE(ts->has_output(&StdoutLog));
EXPECT_FALSE(ts->has_output(&StderrLog));
EXPECT_TRUE(ts->has_output(StdoutLog));
EXPECT_FALSE(ts->has_output(StderrLog));
}
}
TEST(LogTagSet, has_output) {
LogTagSet& ts = LogTagSetMapping<LOG_TAGS(logging)>::tagset();
ts.set_output_level(&StderrLog, LogLevel::Trace);
EXPECT_TRUE(ts.has_output(&StderrLog));
ts.set_output_level(StderrLog, LogLevel::Trace);
EXPECT_TRUE(ts.has_output(StderrLog));
EXPECT_FALSE(ts.has_output(NULL));
ts.set_output_level(&StderrLog, LogLevel::Off);
EXPECT_FALSE(ts.has_output(&StderrLog));
ts.set_output_level(StderrLog, LogLevel::Off);
EXPECT_FALSE(ts.has_output(StderrLog));
}
TEST(LogTagSet, ntags) {
@ -63,18 +63,18 @@ TEST(LogTagSet, ntags) {
TEST(LogTagSet, is_level) {
LogTagSet& ts = LogTagSetMapping<LOG_TAGS(logging)>::tagset();
// Set info level on stdout and verify that is_level() reports correctly
ts.set_output_level(&StdoutLog, LogLevel::Info);
ts.set_output_level(StdoutLog, LogLevel::Info);
EXPECT_TRUE(ts.is_level(LogLevel::Error));
EXPECT_TRUE(ts.is_level(LogLevel::Warning));
EXPECT_TRUE(ts.is_level(LogLevel::Info));
EXPECT_FALSE(ts.is_level(LogLevel::Debug));
EXPECT_FALSE(ts.is_level(LogLevel::Trace));
ts.set_output_level(&StdoutLog, LogLevel::Default);
ts.set_output_level(StdoutLog, LogLevel::Default);
EXPECT_TRUE(ts.is_level(LogLevel::Default));
}
TEST(LogTagSet, level_for) {
LogOutput* output = &StdoutLog;
LogOutput* output = StdoutLog;
LogTagSet& ts = LogTagSetMapping<LOG_TAGS(logging)>::tagset();
for (uint i = 0; i < LogLevel::Count; i++) {
LogLevelType level = static_cast<LogLevelType>(i);