Hi Thien,

ACK from me.

Best regards,
Hieu
-----Original Message-----
From: Thien Minh Huynh <thien.m.hu...@dektech.com.au> 
Sent: Thursday, August 4, 2022 2:28 PM
To: Minh Hon Chau <minh.c...@dektech.com.au>; Thang Duc Nguyen 
<thang.d.ngu...@dektech.com.au>; Hieu Hong Hoang <hieu.h.ho...@dektech.com.au>
Cc: opensaf-devel@lists.sourceforge.net; Thien Minh Huynh 
<thien.m.hu...@dektech.com.au>
Subject: [PATCH 1/1] log: delete the empty log file when rotate log file [#3320]

When performing an admin op command with id = 2 (SA_LOG_ADMIN_ROTATE_FILE) 
without parameters and there are no log record in the stream.
There will be a empty log file created.

By checking the size of the stream, this ticket avoids creating an empty log 
file. Osaflogd will remove the current file If there are no log records in the 
stream and create a new file with a new timestamp.
---
 src/log/apitest/tet_LogOiOps.c | 104 +++++++++++++++++++++++++++++++--
 src/log/logd/lgs_stream.cc     |  52 ++++++++++++-----
 2 files changed, 136 insertions(+), 20 deletions(-)

diff --git a/src/log/apitest/tet_LogOiOps.c b/src/log/apitest/tet_LogOiOps.c 
index 2fde9b5d4..1b6c487d4 100644
--- a/src/log/apitest/tet_LogOiOps.c
+++ b/src/log/apitest/tet_LogOiOps.c
@@ -5590,13 +5590,14 @@ void verRotatedLogCfgFile(void)
        rc_validate(num_files, max_file * 2);
 }
 
-// Verify that log file is rotated via admin operation with admin id = 2 -// 
and no parameter
+// Verify that log file is rotated via admin operation with admin id = 
+2, // current log file not empty and no parameter
 //
 // Step1: Create and delete the app stream with (saLogStreamMaxFilesRotated = 
2) -// step2: Do admin operation 2 times to rotate log file.
+// Step2: Write a record to stream
+// step3: Do admin operation 2 times to rotate log file.
 //        Two new log file are created
-// step3: Verify log file is rotated via admin operation by checking that
+// step4: Verify log file is rotated via admin operation by checking 
+that
 //        there are 2 log files on disk
 void verRotatedLogCfgFile2(void)
 {
@@ -5620,11 +5621,20 @@ void verRotatedLogCfgFile2(void)
                rc_validate(rc, 0);
                return;
        }
+
+       char command[MAX_DATA];
+
+       sprintf(command, "saflogger -a %s %s", object_dn, __func__);
+       // Write a record to stream
+       rc = systemCall(command);
+       if (rc != 0) {
+               rc_validate(rc, 0);
+               return;
+       }
        osaf_nanosleep(&kHundredMilliseconds);
 
        // Do admin operation to rotate log file without the parameter
        // Two new log files are created. One oldest file is removed.
-       char command[MAX_DATA];
        sprintf(command, "immadm -o 2 %s", object_dn);
        for (int i = 0; i < 2; ++i) {
                rc = execute_admin_operation_and_retries(command);
@@ -5744,6 +5754,85 @@ void verRotatedLogCfgFile3(void)
        rc_validate(num_files, 1);
 }
 
+
+// Verify that log file is rotated via admin operation with admin id = 
+2, // current log file empty and no parameter // // Step1: Create and 
+delete the app stream with (saLogStreamMaxFilesRotated = 2) // step2: 
+Do admin operation 2 times to rotate log file.
+//        Two new log file are created
+// step3: Verify log file is rotated via admin operation by checking that
+//        there is a log file on disk
+void verRotatedLogCfgFile4(void)
+{
+       const char *object_dn =
+                       "safLgStrCfg=verRotatedFile4,safApp=safLogService";
+       // Command to create configuration application stream
+       char create_cfg_application_stream[MAX_DATA];
+
+       sprintf(create_cfg_application_stream,
+               "immcfg -c SaLogStreamConfig %s "
+               " -a saLogStreamPathName=. "
+               "-a saLogStreamFileName=verRotatedFile4"
+               " -a saLogStreamMaxFilesRotated=2",
+               object_dn);
+       // Command to delete configuration application stream
+       char delete_cfg_application_stream[MAX_DATA];
+
+       sprintf(delete_cfg_application_stream, "immcfg -d %s", object_dn);
+
+       // Create  the app stream.
+       int rc = systemCall(create_cfg_application_stream);
+
+       if (rc != 0) {
+               rc_validate(rc, 0);
+               return;
+       }
+
+       osaf_nanosleep(&kHundredMilliseconds);
+
+       // Do admin operation to rotate log file without the parameter
+       // Two new log files are created. One oldest file is removed.
+       char command[MAX_DATA];
+
+       sprintf(command, "immadm -o 2 %s", object_dn);
+       for (int i = 0; i < 2; ++i) {
+               rc = execute_admin_operation_and_retries(command);
+               if (rc != 0) {
+                       systemCall(delete_cfg_application_stream);
+                       rc_validate(rc, 0);
+                       return;
+               }
+       }
+
+       // Find all log files and count number of files
+       // Step 1: Find all that files's data were last modified 1 minutes ago
+       // Step 2: Filter all 'verRotatedFile4_[0-9]{8}_[0-9]{6}.log'
+       // Step 3: Count number of files at step 2
+       sprintf(command, "find %s -type f -mmin -1 "
+                        "| egrep '%s.*\\.log$' "
+                        "| wc -l | awk '{printf $1}'",
+                        log_root_path, "verRotatedFile4");
+       char num_files_c[10];
+       FILE *fp = popen(command, "r");
+       // Get number of log files
+       while (fgets(num_files_c, sizeof(num_files_c) - 1, fp) != NULL);
+       pclose(fp);
+
+       // Close the application stream
+       rc = systemCall(delete_cfg_application_stream);
+       if (rc != 0) {
+               rc_validate(rc, 0);
+               return;
+       }
+
+       // Verify 1 empty log is removed
+       // by checking that there is 1 log file on disk
+       uint32_t num_files = atoi(num_files_c);
+
+       rc_validate(num_files, 1);
+}
+
 __attribute__((constructor)) static void saOiOperations_constructor(void)  {
        /* Stream objects */
@@ -6106,8 +6195,11 @@ __attribute__((constructor)) static void 
saOiOperations_constructor(void)
              "Verify that both log and cfg files are rotated");
        test_case_add(6, verRotatedLogCfgFile2,
              "Verify log file is rotated via admin operation "
-             "without parameter");
+             "without parameter and current log file not empty");
        test_case_add(6, verRotatedLogCfgFile3,
              "Verify oldest log files are removed via admin operation "
              "with parameter");
+       test_case_add(6, verRotatedLogCfgFile4,
+             "Verify log file is rotated via admin operation "
+             "without parameter and current log file empty");
 }
diff --git a/src/log/logd/lgs_stream.cc b/src/log/logd/lgs_stream.cc index 
fc9aa7d75..0e9aa1d32 100644
--- a/src/log/logd/lgs_stream.cc
+++ b/src/log/logd/lgs_stream.cc
@@ -1114,14 +1114,26 @@ int log_rotation_stb(log_stream_t *stream) {
       }
     }
 
-    std::string emptyStr = "";
-    // Rename file to give it the "close timestamp"
-    rc = lgs_file_rename_h(root_path, stream->pathName,
-                           stream->stb_logFileCurrent, current_time_str,
-                           LGS_LOG_FILE_EXT, &emptyStr);
-    if (rc == -1) {
-      LOG_NO("Rename log file failed");
-      return rc;
+    if (stream->stb_curFileSize == 0) {
+      std::string pathname = root_path + "/" + stream->pathName + "/" +
+                             stream->stb_logFileCurrent + ".log";
+      TRACE("Delete empty file %s", pathname.c_str());
+      rc = file_unlink_h(pathname);
+      if (rc == -1) {
+        LOG_NO("Delete empty file fail: %s - %s", pathname.c_str(),
+               strerror(errno));
+        return rc;
+      }
+    } else {
+      std::string emptyStr = "";
+      // Rename file to give it the "close timestamp"
+      rc = lgs_file_rename_h(root_path, stream->pathName,
+                             stream->stb_logFileCurrent, current_time_str,
+                             LGS_LOG_FILE_EXT, &emptyStr);
+      if (rc == -1) {
+        LOG_NO("Rename log file failed");
+        return rc;
+      }
     }
 
     // Remove oldest file if needed
@@ -1179,12 +1191,24 @@ int log_rotation_act(log_stream_t *stream) {
     }
   }
 
-  // Rename file to give it the "close timestamp"
-  rc = lgs_file_rename_h(root_path, stream->pathName, stream->logFileCurrent,
-                         current_time, LGS_LOG_FILE_EXT, &emptyStr);
-  if (rc == -1) {
-    LOG_NO("Rename log file failed");
-    return rc;
+  if (stream->curFileSize == 0) {
+    std::string pathname = root_path + "/" + stream->pathName + "/" +
+                           stream->logFileCurrent + ".log";
+    TRACE("Delete empty file %s", pathname.c_str());
+    rc = file_unlink_h(pathname);
+    if (rc == -1) {
+      LOG_NO("Delete empty file fail: %s - %s", pathname.c_str(),
+             strerror(errno));
+      return rc;
+    }
+  } else {
+    // Rename file to give it the "close timestamp"
+    rc = lgs_file_rename_h(root_path, stream->pathName, stream->logFileCurrent,
+                           current_time, LGS_LOG_FILE_EXT, &emptyStr);
+    if (rc == -1) {
+      LOG_NO("Rename log file failed");
+      return rc;
+    }
   }
 
   // Save time when logFileCurrent was closed
--
2.25.1



_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to