trafficserver-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From shinr...@apache.org
Subject [trafficserver] branch master updated: TS-5084 Make logcat follow file rotation
Date Thu, 05 Jan 2017 21:28:33 GMT
This is an automated email from the ASF dual-hosted git repository.

shinrich pushed a commit to branch master
in repository https://git-dual.apache.org/repos/asf/trafficserver.git

The following commit(s) were added to refs/heads/master by this push:
       new  f4416da   TS-5084 Make logcat follow file rotation
f4416da is described below

commit f4416da3bebd067c83be3f3a85b213e6b432c3de
Author: Daniel Xu <dlxu2@yahoo.com>
AuthorDate: Wed Dec 7 14:48:42 2016 -0600

    TS-5084 Make logcat follow file rotation
    
    This patch makes `traffic_logcat -f` follow squid.blog even when
    squid.blog is rotated. Previously, the tool did not do this at all.
    
    This is implemented by keeping track of the _most_previous_ inode #
    of squid.blog and comparing it with the most up to date value of
    the inode # every now and then. If there is ever a difference, then
    we close and reopen the log file.
---
 proxy/logcat.cc | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/proxy/logcat.cc b/proxy/logcat.cc
index 836ca82..590804e 100644
--- a/proxy/logcat.cc
+++ b/proxy/logcat.cc
@@ -70,6 +70,50 @@ static const ArgumentDescription argument_descriptions[] = {
   HELP_ARGUMENT_DESCRIPTION(),
   VERSION_ARGUMENT_DESCRIPTION()};
 
+/*
+ * Gets the inode number of a given file
+ *
+ * @param filename name of the file
+ * @returns -1 on failure, otherwise inode number
+ */
+static ino_t
+get_inode_num(const char *filename)
+{
+  struct stat sb;
+
+  if (stat(filename, &sb) != 0) {
+    perror("stat");
+    return -1;
+  }
+
+  return sb.st_ino;
+}
+
+/*
+ * Checks if a log file has been rotated, and if so, opens the rotated file
+ * and returns the new file descriptor
+ *
+ * @param input_file name of log file we want to follow
+ * @param old_inode_num the most recently known inode number of `input_name`
+ * @returns -1 on failure, 0 on noop, otherwise the open fd of rotated file
+ */
+static int
+follow_rotate(const char *input_file, ino_t old_inode_num)
+{
+  // check if file has been rotated
+  if (get_inode_num(input_file) != old_inode_num) {
+    int new_fd = open(input_file, O_RDONLY);
+    if (new_fd < 0) {
+      fprintf(stderr, "Error while trying to follow rotated input file %s: %s\n", input_file,
strerror(errno));
+      return -1;
+    }
+
+    return new_fd;
+  } else { // file has not been rotated
+    return 0;
+  }
+}
+
 static int
 process_file(int in_fd, int out_fd)
 {
@@ -295,6 +339,7 @@ main(int /* argc ATS_UNUSED */, const char *argv[])
           lseek(in_fd, 0, SEEK_END);
         }
 
+        ino_t inode_num = get_inode_num(file_arguments[i]);
         while (true) {
           if (process_file(in_fd, out_fd) != 0) {
             error = DATA_PROCESSING_ERROR;
@@ -304,6 +349,25 @@ main(int /* argc ATS_UNUSED */, const char *argv[])
             break;
           } else {
             usleep(10000); // This avoids burning CPU, using poll() would have been nice,
but doesn't work I think.
+
+            // see if the file we're following has been rotated
+            if (access(file_arguments[i], F_OK) == 0) { // Sometimes there's a gap between
logfile rotation and the actual presence
+                                                        // of a fresh file on disk. We must
make sure we don't get caught in that
+                                                        // gap.
+              int fd = follow_rotate(file_arguments[i], inode_num);
+              if (fd == -1) {
+                error = DATA_PROCESSING_ERROR;
+                break;
+              } else if (fd > 0) {
+                // we got a new fd to use
+                Debug("logcat", "Detected logfile rotation. Following to new file");
+                close(in_fd);
+                in_fd = fd;
+
+                // update the inode number for the log file
+                inode_num = get_inode_num(file_arguments[i]);
+              }
+            }
           }
         }
       }

-- 
To stop receiving notification emails like this one, please contact
['"commits@trafficserver.apache.org" <commits@trafficserver.apache.org>'].

Mime
View raw message