summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES4
-rw-r--r--docs/manual/programs/rotatelogs.xml28
-rw-r--r--support/rotatelogs.c25
3 files changed, 46 insertions, 11 deletions
diff --git a/CHANGES b/CHANGES
index a0b86985ae..d592d3fdf6 100644
--- 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.
diff --git a/docs/manual/programs/rotatelogs.xml b/docs/manual/programs/rotatelogs.xml
index 789a71afa6..7c7443a37b 100644
--- a/docs/manual/programs/rotatelogs.xml
+++ b/docs/manual/programs/rotatelogs.xml
@@ -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>
diff --git a/support/rotatelogs.c b/support/rotatelogs.c
index 2cf2549e27..a295ad0a7b 100644
--- a/support/rotatelogs.c
+++ b/support/rotatelogs.c
@@ -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;