JDK-7090324: gclog rotation via external tool
Yasu
yasu at ysfactory.dip.jp
Sun Sep 29 14:40:27 UTC 2013
Hi all,
We are using "logrotate" tool on RHEL for various log rotation.
Current HotSpot has gclog rotation function for log size base,
however I need to rotate gc log synchronizing with logrotate tool.
So I've created RFE as "JDK-7090324: gclog rotation via external tool" .
And Sr. Engineering Manager in Oracle said he use the essence of my patch in one
of the jcmd subcommands.
http://mail.openjdk.java.net/pipermail/hotspot-gc-dev/2011-September/003274.html
2 years ago, I posted a patch for this RFE.
But this patch is too old to apply for current HotSpot.
In last month, a similar discussion was appeared in ML.
So I think it's time to discuss this RFE.
http://mail.openjdk.java.net/pipermail/hotspot-gc-dev/2013-August/008029.html
Please cooperate.
Best regards,
Yasumasa
-------------- next part --------------
diff -r ae2edb3df7fb src/share/vm/runtime/arguments.cpp
--- a/src/share/vm/runtime/arguments.cpp Sun Sep 22 18:07:43 2013 +0200
+++ b/src/share/vm/runtime/arguments.cpp Sun Sep 29 23:11:37 2013 +0900
@@ -1869,18 +1869,17 @@
// NumberOfGCLogFiles is 0, or GCLogFileSize is 0
void check_gclog_consistency() {
if (UseGCLogFileRotation) {
- if ((Arguments::gc_log_filename() == NULL) ||
- (NumberOfGCLogFiles == 0) ||
- (GCLogFileSize == 0)) {
+ if ((Arguments::gc_log_filename() == NULL) || (NumberOfGCLogFiles == 0)) {
jio_fprintf(defaultStream::output_stream(),
- "To enable GC log rotation, use -Xloggc:<filename> -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=<num_of_files> -XX:GCLogFileSize=<num_of_size>[k|K|m|M|g|G]\n"
- "where num_of_file > 0 and num_of_size > 0\n"
+ "To enable GC log rotation, use -Xloggc:<filename> -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=<num_of_files>\n"
+ "where num_of_file > 0\n"
"GC log rotation is turned off\n");
UseGCLogFileRotation = false;
}
}
- if (UseGCLogFileRotation && GCLogFileSize < 8*K) {
+ if (UseGCLogFileRotation && !FLAG_IS_DEFAULT(GCLogFileSize)
+ && (GCLogFileSize < 8*K)) {
FLAG_SET_CMDLINE(uintx, GCLogFileSize, 8*K);
jio_fprintf(defaultStream::output_stream(),
"GCLogFileSize changed to minimum 8K\n");
diff -r ae2edb3df7fb src/share/vm/runtime/safepoint.cpp
--- a/src/share/vm/runtime/safepoint.cpp Sun Sep 22 18:07:43 2013 +0200
+++ b/src/share/vm/runtime/safepoint.cpp Sun Sep 29 23:11:37 2013 +0900
@@ -535,7 +535,7 @@
// rotate log files?
if (UseGCLogFileRotation) {
- gclog_or_tty->rotate_log();
+ gclog_or_tty->rotate_log(false);
}
if (MemTracker::is_on()) {
diff -r ae2edb3df7fb src/share/vm/runtime/vm_operations.hpp
--- a/src/share/vm/runtime/vm_operations.hpp Sun Sep 22 18:07:43 2013 +0200
+++ b/src/share/vm/runtime/vm_operations.hpp Sun Sep 29 23:11:37 2013 +0900
@@ -95,6 +95,7 @@
template(JFRCheckpoint) \
template(Exit) \
template(LinuxDllLoad) \
+ template(RotateGCLog) \
class VM_Operation: public CHeapObj<mtInternal> {
public:
@@ -408,4 +409,17 @@
void doit();
};
+
+class VM_RotateGCLog: public VM_Operation{
+
+ private:
+ bool _is_force;
+
+ public:
+ VM_RotateGCLog(bool is_force) { _is_force = is_force; }
+ VMOp_Type type() const { return VMOp_RotateGCLog; }
+ void doit() { gclog_or_tty->rotate_log(_is_force); }
+
+};
+
#endif // SHARE_VM_RUNTIME_VM_OPERATIONS_HPP
diff -r ae2edb3df7fb src/share/vm/services/diagnosticCommand.cpp
--- a/src/share/vm/services/diagnosticCommand.cpp Sun Sep 22 18:07:43 2013 +0200
+++ b/src/share/vm/services/diagnosticCommand.cpp Sun Sep 29 23:11:37 2013 +0900
@@ -53,6 +53,7 @@
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassStatsDCmd>(full_export, true, false));
#endif // INCLUDE_SERVICES
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(full_export, true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RotateGCLogDCmd>(full_export, true, false));
// Enhanced JMX Agent Support
// These commands won't be exported via the DiagnosticCommandMBean until an
@@ -644,3 +645,35 @@
JavaCalls::call_static(&result, ik, vmSymbols::stopRemoteAgent_name(), vmSymbols::void_method_signature(), CHECK);
}
+
+RotateGCLogDCmd::RotateGCLogDCmd(outputStream* output, bool heap) :
+ DCmdWithParser(output, heap),
+ _force("-force", "Force execute GC log rotation.", "BOOLEAN", false, "false") {
+ _dcmdparser.add_dcmd_option(&_force);
+}
+
+void RotateGCLogDCmd::execute(DCmdSource source, TRAPS) {
+
+ if(UseGCLogFileRotation){
+ VM_RotateGCLog rotateop(_force.value());
+ VMThread::execute(&rotateop);
+ }
+ else{
+ output()->print_cr("Target VM is not supported GC log rotation.");
+ }
+
+}
+
+int RotateGCLogDCmd::num_arguments() {
+ ResourceMark rm;
+ RotateGCLogDCmd* dcmd = new RotateGCLogDCmd(NULL, false);
+
+ if (dcmd != NULL) {
+ DCmdMark mark(dcmd);
+ return dcmd->_dcmdparser.num_arguments();
+ } else {
+ return 0;
+ }
+
+}
+
diff -r ae2edb3df7fb src/share/vm/services/diagnosticCommand.hpp
--- a/src/share/vm/services/diagnosticCommand.hpp Sun Sep 22 18:07:43 2013 +0200
+++ b/src/share/vm/services/diagnosticCommand.hpp Sun Sep 29 23:11:37 2013 +0900
@@ -359,4 +359,20 @@
virtual void execute(DCmdSource source, TRAPS);
};
+
+class RotateGCLogDCmd : public DCmdWithParser {
+protected:
+ DCmdArgument<bool> _force;
+public:
+ RotateGCLogDCmd(outputStream* output, bool heap);
+ static const char* name() { return "GC.rotate_log"; }
+ static const char* description() {
+ return "GC log rotation.";
+ }
+ static const char* impact() { return "Low"; }
+ static int num_arguments();
+ virtual void execute(DCmdSource source, TRAPS);
+};
+
+
#endif // SHARE_VM_SERVICES_DIAGNOSTICCOMMAND_HPP
diff -r ae2edb3df7fb src/share/vm/utilities/ostream.cpp
--- a/src/share/vm/utilities/ostream.cpp Sun Sep 22 18:07:43 2013 +0200
+++ b/src/share/vm/utilities/ostream.cpp Sun Sep 29 23:11:37 2013 +0900
@@ -659,16 +659,26 @@
// write to gc log file at safepoint. If in future, changes made for mutator threads or
// concurrent GC threads to run parallel with VMThread at safepoint, write and rotate_log
// must be synchronized.
-void gcLogFileStream::rotate_log() {
+void gcLogFileStream::rotate_log(bool is_force) {
char time_msg[FILENAMEBUFLEN];
char time_str[EXTRACHARLEN];
char current_file_name[FILENAMEBUFLEN];
char renamed_file_name[FILENAMEBUFLEN];
- if (_bytes_written < (jlong)GCLogFileSize) {
- return;
+ if(!is_force){ /* rotation request is NOT force. */
+
+ if(GCLogFileSize == 0){
+ /* GC log rotation occurs external force trigger ONLY. */
+ return;
+ }
+ else if(_bytes_written < (jlong)GCLogFileSize){
+ /* This case is size-based rotation and not need to rotate log yet. */
+ return;
+ }
+
}
+
#ifdef ASSERT
Thread *thread = Thread::current();
assert(thread == NULL ||
@@ -703,10 +713,19 @@
_file_name, _cur_file_num);
jio_snprintf(current_file_name, filename_len + EXTRACHARLEN, "%s.%d" CURRENTAPPX,
_file_name, _cur_file_num);
- jio_snprintf(time_msg, sizeof(time_msg), "%s GC log file has reached the"
+
+ if(is_force){
+ jio_snprintf(time_msg, sizeof(time_msg), "%s GC log rotating request has received. Saved as %s\n",
+ os::local_time_string((char *)time_str, sizeof(time_str)),
+ renamed_file_name);
+ }
+ else{
+ jio_snprintf(time_msg, sizeof(time_msg), "%s GC log file has reached the"
" maximum size. Saved as %s\n",
- os::local_time_string((char *)time_str, sizeof(time_str)),
+ os::local_time_string((char *)time_str, sizeof(time_str)),
renamed_file_name);
+ }
+
write(time_msg, strlen(time_msg));
fclose(_file);
diff -r ae2edb3df7fb src/share/vm/utilities/ostream.hpp
--- a/src/share/vm/utilities/ostream.hpp Sun Sep 22 18:07:43 2013 +0200
+++ b/src/share/vm/utilities/ostream.hpp Sun Sep 29 23:11:37 2013 +0900
@@ -115,7 +115,7 @@
// flushing
virtual void flush() {}
virtual void write(const char* str, size_t len) = 0;
- virtual void rotate_log() {} // GC log rotation
+ virtual void rotate_log(bool is_force) {} // GC log rotation
virtual ~outputStream() {} // close properly on deletion
void dec_cr() { dec(); cr(); }
@@ -240,7 +240,7 @@
gcLogFileStream(const char* file_name);
~gcLogFileStream();
virtual void write(const char* c, size_t len);
- virtual void rotate_log();
+ virtual void rotate_log(bool is_force);
void dump_loggc_header();
};
More information about the hotspot-gc-dev
mailing list