diff options
-rw-r--r-- | changes-entries/rotatlogs_truncate_rotated.txt | 2 | ||||
-rw-r--r-- | docs/manual/programs/rotatelogs.xml | 19 | ||||
-rw-r--r-- | support/rotatelogs.c | 27 |
3 files changed, 42 insertions, 6 deletions
diff --git a/changes-entries/rotatlogs_truncate_rotated.txt b/changes-entries/rotatlogs_truncate_rotated.txt new file mode 100644 index 0000000000..2cc69366ea --- /dev/null +++ b/changes-entries/rotatlogs_truncate_rotated.txt @@ -0,0 +1,2 @@ + *) rotatelogs: Add -T flag to allow subsequent rotated logfiles to be + truncated without the initial logfile being truncated. [Eric Covener] diff --git a/docs/manual/programs/rotatelogs.xml b/docs/manual/programs/rotatelogs.xml index df5956cb09..ed3d9aa908 100644 --- a/docs/manual/programs/rotatelogs.xml +++ b/docs/manual/programs/rotatelogs.xml @@ -111,6 +111,13 @@ the filename, however format strings containing '%' characters will be respected. </dd> +<dt><code>-T</code></dt> +<dd>Causes all but the initial logfile to be truncated when opened. +This is useful when the format string contains something that will +loop around, such as the day of the month. +</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 @@ -263,6 +270,18 @@ an offset.</dd> in this scenario that a separate process (such as tail) would process the file in real time.</p> +<example> +<highlight language="config"> + CustomLog "|bin/rotatelogs -T /var/log/logfile.%d 86400" common +</highlight> +</example> + +<p>If the server is started (or restarted) on the first of the month, this +appends to <code>/var/log/logfile.01</code>. When a log entry is written on the +second of the month, <code>/var/log/logfile.02</code> is truncated and new entries +will be added to the top. This example keeps approximately 1 months worth of +logs without external maintenance.</p> + </section> <section id="portability"><title>Portability</title> diff --git a/support/rotatelogs.c b/support/rotatelogs.c index 5430f9e2e3..fb48ae789c 100644 --- a/support/rotatelogs.c +++ b/support/rotatelogs.c @@ -65,6 +65,7 @@ struct rotate_config { int echo; char *szLogRoot; int truncate; + int truncate_rotated_only; const char *linkfile; const char *postrotate_prog; #if APR_FILES_AS_SOCKETS @@ -109,9 +110,9 @@ static void usage(const char *argv0, const char *reason) } fprintf(stderr, #if APR_FILES_AS_SOCKETS - "Usage: %s [-v] [-l] [-L linkname] [-p prog] [-f] [-D] [-t] [-e] [-c] [-n number] <logfile> " + "Usage: %s [-vlfDtTec] [-L linkname] [-p prog] [-n number] <logfile> " #else - "Usage: %s [-v] [-l] [-L linkname] [-p prog] [-f] [-D] [-t] [-e] [-n number] <logfile> " + "Usage: %s [-vlfDtTe] [-L linkname] [-p prog] [-n number] <logfile> " #endif "{<rotation time in seconds>|<rotation size>(B|K|M|G)} " "[offset minutes from UTC]\n\n", @@ -145,6 +146,7 @@ static void usage(const char *argv0, const char *reason) " -f Force opening of log on program start.\n" " -D Create parent directories of log file.\n" " -t Truncate logfile instead of rotating, tail friendly.\n" + " -T Truncate logfiles opened for rotation, but not the initial logfile.\n" " -e Echo log to stdout for further processing.\n" #if APR_FILES_AS_SOCKETS " -c Create log even if it is empty.\n" @@ -379,6 +381,7 @@ static void doRotate(rotate_config_t *config, rotate_status_t *status) struct logfile newlog; int thisLogNum = -1; int oldreason = status->rotateReason; + int truncate = config->truncate; /* Retrieve local-time-adjusted-Unix-time. */ now = get_now(config, &offset); @@ -458,8 +461,17 @@ static void doRotate(rotate_config_t *config, rotate_status_t *status) if (config->verbose) { fprintf(stderr, "Opening file %s\n", newlog.name); } - rv = apr_file_open(&newlog.fd, newlog.name, APR_WRITE | APR_CREATE | APR_APPEND - | (config->truncate || (config->num_files > 0 && status->current.fd) ? APR_TRUNCATE : 0), + + if (!truncate) { + /* -n and -T truncate subsequent files only. */ + if (status->current.fd && + (config->num_files > 0 || config->truncate_rotated_only)) { + truncate = 1; + } + } + rv = apr_file_open(&newlog.fd, newlog.name, + APR_WRITE | APR_CREATE | APR_APPEND + | (truncate ? APR_TRUNCATE : 0), APR_OS_DEFAULT, newlog.pool); if (rv == APR_SUCCESS) { /* Handle post-rotate processing. */ @@ -597,9 +609,9 @@ int main (int argc, const char * const argv[]) apr_pool_create(&status.pool, NULL); apr_getopt_init(&opt, status.pool, argc, argv); #if APR_FILES_AS_SOCKETS - while ((rv = apr_getopt(opt, "lL:p:fDtvecn:", &c, &opt_arg)) == APR_SUCCESS) { + while ((rv = apr_getopt(opt, "lL:p:fDtTvecn:", &c, &opt_arg)) == APR_SUCCESS) { #else - while ((rv = apr_getopt(opt, "lL:p:fDtven:", &c, &opt_arg)) == APR_SUCCESS) { + while ((rv = apr_getopt(opt, "lL:p:fDtTven:", &c, &opt_arg)) == APR_SUCCESS) { #endif switch (c) { case 'l': @@ -624,6 +636,9 @@ int main (int argc, const char * const argv[]) case 't': config.truncate = 1; break; + case 'T': + config.truncate_rotated_only = 1; + break; case 'v': config.verbose = 1; break; |