]> granicus.if.org Git - apache/commitdiff
support/rotatelogs: Support the simplest log rotation case, log
authorGraham Leggett <minfrin@apache.org>
Tue, 16 Feb 2010 22:01:21 +0000 (22:01 +0000)
committerGraham Leggett <minfrin@apache.org>
Tue, 16 Feb 2010 22:01:21 +0000 (22:01 +0000)
truncation. Useful when the log is being processed in real time
using a command like tail.

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

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

diff --git a/CHANGES b/CHANGES
index a0b86985aef79ba9502d70c9051284d4ca14479f..d592d3fdf67ee42a39ceb83a15e427f3b662445d 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,10 @@
 
 Changes with Apache 2.3.7
 
+  *) support/rotatelogs: Support the simplest log rotation case, log
+     truncation. Useful when the log is being processed in real time
+     using a command like tail. [Graham Leggett]
+
   *) support/htcacheclean: Teach it how to write a pid file (modelled on
      httpd's writing of a pid file) so that it becomes possible to run
      more than one instance of htcacheclean on the same machine.
index 789a71afa64461e79b612946c83247d492dfec1f..7c7443a37b5d9254817ca7b0d800a20a299f0060 100644 (file)
@@ -62,6 +62,14 @@ 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>-t</code></dt>
+<dd>Causes the logfile to be truncated instead of rotated. This is
+useful when a log is processed in real time by a command like tail,
+and there is no need for archived data. No suffix will be added to
+the filename, however format strings containing '%' characters
+will be respected.
+</dd>
+
 <dt><code>-v</code></dt>
 <dd>Produce verbose output on STDERR. The output contains
 the result of the configuration parsing, and all file open and
@@ -73,11 +81,12 @@ close actions.</dd>
 includes any '%' characters, it is treated as a format string for
 <code>strftime(3)</code>.  Otherwise, the suffix
 <var>.nnnnnnnnnn</var> 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
-<code>strftime(3)</code> format will all be zero, referring to the
-beginning of the current 24-hour period (midnight).</dd>
+seconds (unless the -t option is used). 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 <code>strftime(3)</code> format will
+all be zero, referring to the beginning of the current 24-hour
+period (midnight).</dd>
 
 <dt><code><var>rotationtime</var></code></dt>
 
@@ -145,6 +154,15 @@ an offset.</dd>
      will be created of the form
      <code>errorlog.YYYY-mm-dd-HH_MM_SS</code>.</p>
  
+<example>
+     CustomLog "|bin/rotatelogs -t /var/logs/logfile 86400" common
+</example>
+
+     <p>This creates the file /var/logs/logfile, truncating the file at
+     startup and then truncating the file once per day. It is expected
+     in this scenario that a separate process (such as tail) would
+     process the file in real time.</p>
+
 </section>
 
 <section id="portability"><title>Portability</title>
index 2cf2549e27922a92b7191d44e0e40ba3c04c97f4..a295ad0a7bcb8f267407eb4e8c1663c31bbeb35f 100644 (file)
@@ -88,6 +88,7 @@ struct rotate_config {
     int force_open;
     int verbose;
     const char *szLogRoot;
+    int truncate;
 };
 
 typedef struct rotate_status rotate_status_t;
@@ -114,7 +115,7 @@ static void usage(const char *argv0, const char *reason)
         fprintf(stderr, "%s\n", reason);
     }
     fprintf(stderr,
-            "Usage: %s [-v] [-l] [-f] <logfile> "
+            "Usage: %s [-v] [-l] [-f] [-t] <logfile> "
             "{<rotation time in seconds>|<rotation size>(B|K|M|G)} "
             "[offset minutes from UTC]\n\n",
             argv0);
@@ -135,7 +136,10 @@ static void usage(const char *argv0, const char *reason)
             "starts (N.B. if using a rotation time,\nthe time will always "
             "be a multiple of the rotation time, so you can synchronize\n"
             "cron scripts with it). At the end of each rotation time or "
-            "when the file size\nis reached a new log is started.\n");
+            "when the file size\nis reached a new log is started. If the "
+            "-t option is specified, the specified\nfile will be truncated "
+            "instead of rotated, and is useful where tail is used to\n"
+            "process logs in real time.\n");
     exit(1);
 }
 
@@ -296,14 +300,20 @@ static void doRotate(rotate_config_t *config, rotate_status_t *status)
         apr_strftime(status->filename, &rs, sizeof(status->filename), config->szLogRoot, &e);
     }
     else {
-        sprintf(status->filename, "%s.%010d", config->szLogRoot, tLogStart);
+        if (config->truncate) {
+            snprintf(status->filename, sizeof(status->filename), "%s", config->szLogRoot);
+        }
+        else {
+            snprintf(status->filename, sizeof(status->filename), "%s.%010d", config->szLogRoot,
+                    tLogStart);
+        }
     }
     apr_pool_create(&status->pfile, status->pool);
     if (config->verbose) {
         fprintf(stderr, "Opening file %s\n", status->filename);
     }
-    rv = apr_file_open(&status->nLogFD, status->filename, APR_WRITE | APR_CREATE | APR_APPEND,
-                       APR_OS_DEFAULT, status->pfile);
+    rv = apr_file_open(&status->nLogFD, status->filename, APR_WRITE | APR_CREATE | APR_APPEND
+                       | (config->truncate ? APR_TRUNCATE : 0), APR_OS_DEFAULT, status->pfile);
     if (rv != APR_SUCCESS) {
         char error[120];
 
@@ -430,7 +440,7 @@ int main (int argc, const char * const argv[])
 
     apr_pool_create(&status.pool, NULL);
     apr_getopt_init(&opt, status.pool, argc, argv);
-    while ((rv = apr_getopt(opt, "lfv", &c, &optarg)) == APR_SUCCESS) {
+    while ((rv = apr_getopt(opt, "lftv", &c, &optarg)) == APR_SUCCESS) {
         switch (c) {
         case 'l':
             config.use_localtime = 1;
@@ -438,6 +448,9 @@ int main (int argc, const char * const argv[])
         case 'f':
             config.force_open = 1;
             break;
+        case 't':
+            config.truncate = 1;
+            break;
         case 'v':
             config.verbose = 1;
             break;