]> granicus.if.org Git - apache/commitdiff
Add in new option for rotatelogs: -f
authorJim Jagielski <jim@apache.org>
Fri, 29 Feb 2008 15:32:38 +0000 (15:32 +0000)
committerJim Jagielski <jim@apache.org>
Fri, 29 Feb 2008 15:32:38 +0000 (15:32 +0000)
This forces rotatelogs to create the logfile as soon
as started not as soon as it sees it's first line
of input.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@632355 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
docs/man/rotatelogs.8
docs/manual/programs/rotatelogs.xml
support/rotatelogs.c

diff --git a/CHANGES b/CHANGES
index aba838238738b0457152e9a045984f1c013a6d66..931724f3986a3bdfdbb2c057c593aec4e9f19fcc 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,10 @@
 Changes with Apache 2.3.0
 [ When backported to 2.2.x, remove entry from this file ]
 
+  *) rotatelogs: Added '-f' option to force rotatelogs to create the
+     logfile as soon as started, and not wait until it reads the
+     first entry. [Jim Jagielski]
+
   *) mod_proxy: Do not try a direct connection if the connection via a
      remote proxy failed before and the request has a request body.
      [Ruediger Pluem]
index 5b95a1fa89c1c29777fb32485033abe32fd22556..ae1a052bb30ddf9acf82290bb2415fe5966fbb24 100644 (file)
@@ -27,7 +27,7 @@ rotatelogs \- Piped logging program to rotate Apache logs
 .SH "SYNOPSIS"
  
 .PP
-\fBrotatelogs\fR [ -\fBl\fR ] \fIlogfile\fR \fIrotationtime\fR|\fIfilesize\fRM [ \fIoffset\fR ]
+\fBrotatelogs\fR [ -\fBl\fR ] [ -\fBf\fR ] \fIlogfile\fR \fIrotationtime\fR|\fIfilesize\fRM [ \fIoffset\fR ]
  
 
 .SH "SUMMARY"
@@ -43,6 +43,9 @@ rotatelogs is a simple program for use in conjunction with Apache's piped logfil
 -l
 Causes the use of local time rather than GMT as the base for the interval or for strftime(3) formatting with size-based rotation\&. Note that using -l in an environment which changes the GMT offset (such as for BST or DST) can lead to unpredictable results!  
 .TP
+-f
+Causes the logfile to be immediately opened as soon as rotatelogs starts (instead of waiting for the first log entry)  
+.TP
 \fIlogfile\fR
 The path plus basename of the logfile\&. If \fIlogfile\fR includes any '%' characters, it is treated as a format string for strftime(3)\&. Otherwise, the suffix \fI\&.nnnnnnnnnn\fR is automatically added and is the time in seconds\&. Both formats compute the start time from the beginning of the current period\&. For example, if a rotation time of 86400 is specified, the hour, minute, and second fields created from the strftime(3) format will all be zero, referring to the beginning of the current 24-hour period (midnight)\&.  
 .TP
index 833fbdd2bf3ecd802adb5b54a0c7627607e02324..25f855edf7601f03d47e41e895ec8a4afbfac26d 100644 (file)
@@ -35,6 +35,7 @@
 
      <p><code><strong>rotatelogs</strong>
      [ -<strong>l</strong> ]
+     [ -<strong>f</strong> ]
      <var>logfile</var>
      <var>rotationtime</var>|<var>filesize</var>M 
      [ <var>offset</var> ]</code></p>
@@ -51,6 +52,15 @@ rotation.  Note that using <code>-l</code> in an environment which
 changes the GMT offset (such as for BST or DST) can lead to unpredictable
 results!</dd>
 
+<dt><code>-f</code></dt>
+<dd>Causes the logfile to be opened immediately, as soon as
+<code>rotatelogs</code> starts, instead of waiting for the
+first logfile entry to be read (for non-busy sites, there may be
+a substantial delay between when the server is started
+and when the first request is handled, meaning that the
+associated logfile does not "exist" until then, which
+causes problems from some automated logging tools)</dd>
+
 <dt><code><var>logfile</var></code></dt>
 
 <dd>The path plus basename of the logfile.  If <var>logfile</var>
index 3bd958decd705096818e900486b9496ef0b1411c..80fa86bfd95aa200e18d32b59ebe191a932a2e62 100644 (file)
@@ -31,6 +31,9 @@
  * interval.  NB: Using -l in an environment which changes the GMT offset
  * (such as for BST or DST) can lead to unpredictable results!
  *
+ * -f option added Feb, 2008. This causes rotatelog to open/create
+ *    the logfile as soon as it's started, not as soon as it sees
+ *    data.
  */
 
 
@@ -67,7 +70,7 @@ static void usage(const char *argv0, const char *reason)
         fprintf(stderr, "%s\n", reason);
     }
     fprintf(stderr,
-            "Usage: %s [-l] <logfile> "
+            "Usage: %s [-l] [-f] <logfile> "
             "{<rotation time in seconds>|<rotation size in megabytes>} "
             "[offset minutes from UTC]\n\n",
             argv0);
@@ -116,6 +119,7 @@ int main (int argc, const char * const argv[])
     apr_size_t nRead, nWrite;
     int use_strftime = 0;
     int use_localtime = 0;
+    int bypass_io = 0;
     int now = 0;
     const char *szLogRoot;
     apr_file_t *f_stdin, *nLogFD = NULL, *nLogFDprev = NULL;
@@ -133,11 +137,14 @@ int main (int argc, const char * const argv[])
 
     apr_pool_create(&pool, NULL);
     apr_getopt_init(&opt, pool, argc, argv);
-    while ((rv = apr_getopt(opt, "l", &c, &optarg)) == APR_SUCCESS) {
+    while ((rv = apr_getopt(opt, "lf", &c, &optarg)) == APR_SUCCESS) {
         switch (c) {
         case 'l':
             use_localtime = 1;
             break;
+        case 'f':
+            bypass_io = 1;
+            break;
         }
     }
 
@@ -183,8 +190,17 @@ int main (int argc, const char * const argv[])
 
     for (;;) {
         nRead = sizeof(buf);
-        if (apr_file_read(f_stdin, buf, &nRead) != APR_SUCCESS) {
-            exit(3);
+        /*
+         * Bypass reading stdin if we are forcing the logfile
+         * to be opened as soon as we start. Since we won't be
+         * writing anything, we just want to open the file.
+         * First time through is the only time we do this
+         * since we reset bypass_io after the 1st loop
+         */
+        if (!bypass_io) {
+            if (apr_file_read(f_stdin, buf, &nRead) != APR_SUCCESS) {
+                exit(3);
+            }
         }
         if (tRotation) {
             now = get_now(use_localtime, utc_offset);
@@ -277,23 +293,33 @@ int main (int argc, const char * const argv[])
             }
             nMessCount = 0;
         }
-        nWrite = nRead;
-        apr_file_write(nLogFD, buf, &nWrite);
-        if (nWrite != nRead) {
-            nMessCount++;
-            sprintf(errbuf,
-                    "Error writing to log file. "
-                    "%10d messages lost.\n",
-                    nMessCount);
-            nWrite = strlen(errbuf);
-            apr_file_trunc(nLogFD, 0);
-            if (apr_file_write(nLogFD, errbuf, &nWrite) != APR_SUCCESS) {
-                fprintf(stderr, "Error writing to the file %s\n", buf2);
+        /*
+         * If we just bypassed reading stdin, due to bypass_io,
+         * then we have nothing to write, so skip this.
+         */
+        if (!bypass_io) {
+            nWrite = nRead;
+            apr_file_write(nLogFD, buf, &nWrite);
+            if (nWrite != nRead) {
+                nMessCount++;
+                sprintf(errbuf,
+                        "Error writing to log file. "
+                        "%10d messages lost.\n",
+                        nMessCount);
+                nWrite = strlen(errbuf);
+                apr_file_trunc(nLogFD, 0);
+                if (apr_file_write(nLogFD, errbuf, &nWrite) != APR_SUCCESS) {
+                    fprintf(stderr, "Error writing to the file %s\n", buf2);
                 exit(2);
+                }
+            }
+            else {
+                nMessCount++;
             }
         }
         else {
-            nMessCount++;
+           /* now worry about reading 'n writing all the time */
+           bypass_io = 0;
         }
     }
     /* Of course we never, but prevent compiler warnings */