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
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();
 };
 

Reply via email to