--- old/src/share/vm/logging/logConfiguration.cpp 2015-11-05 23:45:57.694470749 +0900 +++ new/src/share/vm/logging/logConfiguration.cpp 2015-11-05 23:45:57.249471902 +0900 @@ -38,6 +38,7 @@ LogOutput** LogConfiguration::_outputs = NULL; size_t LogConfiguration::_n_outputs = 0; +bool LogConfiguration::_post_initialized = false; void LogConfiguration::post_initialize() { assert(LogConfiguration_lock != NULL, "Lock must be initialized before post-initialization"); @@ -49,6 +50,8 @@ MutexLocker ml(LogConfiguration_lock); describe(log.trace_stream()); } + + _post_initialized = true; } void LogConfiguration::initialize(jlong vm_start_time) { @@ -351,3 +354,12 @@ "\t Turn off all logging, including warnings and errors,\n" "\t and then enable messages tagged with 'rt' using 'trace' level to file 'rttrace.txt'.\n"); } + +void LogConfiguration::rotate_all_outputs() { + for (size_t idx = 0; idx < _n_outputs; idx++) { + if (_outputs[idx]->is_rotatable()) { + _outputs[idx]->rotate(true); + } + } +} + --- old/src/share/vm/logging/logConfiguration.hpp 2015-11-05 23:45:59.475466133 +0900 +++ new/src/share/vm/logging/logConfiguration.hpp 2015-11-05 23:45:59.023467305 +0900 @@ -39,6 +39,7 @@ private: static LogOutput** _outputs; static size_t _n_outputs; + static bool _post_initialized; // Create a new output. Returns NULL if failed. static LogOutput* new_output(char* name, const char* options = NULL); @@ -85,6 +86,13 @@ // Prints usage help for command line log configuration. static void print_command_line_help(FILE* out); + + static bool is_post_initialized() { + return _post_initialized; + } + + // Rotates all LogOutput + static void rotate_all_outputs(); }; #endif // SHARE_VM_LOGGING_LOGCONFIGURATION_HPP --- old/src/share/vm/logging/logDiagnosticCommand.cpp 2015-11-05 23:46:01.261461504 +0900 +++ new/src/share/vm/logging/logDiagnosticCommand.cpp 2015-11-05 23:46:00.823462640 +0900 @@ -35,13 +35,15 @@ _what("what", "Configures what tags to log.", "STRING", false), _decorators("decorators", "Configures which decorators to use. Use 'none' or an empty value to remove all.", "STRING", false), _disable("disable", "Turns off all logging and clears the log configuration.", "BOOLEAN", false), - _list("list", "Lists current log configuration.", "BOOLEAN", false) { + _list("list", "Lists current log configuration.", "BOOLEAN", false), + _rotate("rotate", "Rotates all logs.", "BOOLEAN", false) { _dcmdparser.add_dcmd_option(&_output); _dcmdparser.add_dcmd_option(&_output_options); _dcmdparser.add_dcmd_option(&_what); _dcmdparser.add_dcmd_option(&_decorators); _dcmdparser.add_dcmd_option(&_disable); _dcmdparser.add_dcmd_option(&_list); + _dcmdparser.add_dcmd_option(&_rotate); } int LogDiagnosticCommand::num_arguments() { @@ -86,6 +88,11 @@ any_command = true; } + if (_rotate.has_value()) { + LogConfiguration::rotate_all_outputs(); + any_command = true; + } + if (!any_command) { // If no argument was provided, print usage print_help(LogDiagnosticCommand::name()); --- old/src/share/vm/logging/logDiagnosticCommand.hpp 2015-11-05 23:46:02.967457083 +0900 +++ new/src/share/vm/logging/logDiagnosticCommand.hpp 2015-11-05 23:46:02.528458221 +0900 @@ -43,6 +43,7 @@ DCmdArgument _decorators; DCmdArgument _disable; DCmdArgument _list; + DCmdArgument _rotate; public: LogDiagnosticCommand(outputStream* output, bool heap_allocated); @@ -55,7 +56,7 @@ } static const char* description() { - return "Lists, enables, disables or changes a log output configuration."; + return "Lists current log configuration, enables/disables/configures a log output, or rotates all logs."; } // Used by SecurityManager. This DCMD requires ManagementPermission = control. --- old/src/share/vm/logging/logFileOutput.cpp 2015-11-05 23:46:04.661452693 +0900 +++ new/src/share/vm/logging/logFileOutput.cpp 2015-11-05 23:46:04.232453805 +0900 @@ -155,12 +155,7 @@ int written = LogFileStreamOutput::write(decorations, msg); _current_size += written; - if (should_rotate()) { - MutexLockerEx ml(&_rotation_lock, true /* no safepoint check */); - if (should_rotate()) { - rotate(); - } - } + rotate(false); return written; } @@ -182,7 +177,14 @@ } } -void LogFileOutput::rotate() { +void LogFileOutput::rotate(bool force) { + + if (!should_rotate(force)) { + return; + } + + MutexLockerEx ml(&_rotation_lock, true /* no safepoint check */); + // Archive the current log file archive(); --- old/src/share/vm/logging/logFileOutput.hpp 2015-11-05 23:46:06.374448254 +0900 +++ new/src/share/vm/logging/logFileOutput.hpp 2015-11-05 23:46:05.946449363 +0900 @@ -58,13 +58,13 @@ size_t _current_size; void archive(); - void rotate(); bool configure_rotation(const char* options); char *make_file_name(const char* file_name, const char* pid_string, const char* timestamp_string); static size_t parse_value(const char* value_str); - bool should_rotate() const { - return _file_count > 0 && _rotate_size > 0 && _current_size >= _rotate_size; + bool should_rotate(bool force) { + return is_rotatable() && + (force || (_rotate_size > 0 && _current_size >= _rotate_size)); } public: @@ -73,6 +73,12 @@ virtual bool initialize(const char* options); virtual int write(const LogDecorations& decorations, const char* msg); + virtual bool is_rotatable() { + return LogConfiguration::is_post_initialized() && (_file_count > 0); + } + + virtual void rotate(bool force); + virtual const char* name() const { return _name; } --- old/src/share/vm/logging/logOutput.hpp 2015-11-05 23:46:08.100443780 +0900 +++ new/src/share/vm/logging/logOutput.hpp 2015-11-05 23:46:07.647444954 +0900 @@ -63,6 +63,14 @@ virtual const char* name() const = 0; virtual bool initialize(const char* options) = 0; virtual int write(const LogDecorations &decorations, const char* msg) = 0; + + virtual bool is_rotatable() { + return false; + } + + virtual void rotate(bool force) { + // Do nothing by default. + } }; #endif // SHARE_VM_LOGGING_LOGOUTPUT_HPP