diff options
-rw-r--r-- | CHANGES | 4 | ||||
-rw-r--r-- | docs/manual/programs/rotatelogs.xml | 28 | ||||
-rw-r--r-- | support/rotatelogs.c | 25 |
3 files changed, 46 insertions, 11 deletions
@@ -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; |