diff options
author | Eric Covener <covener@apache.org> | 2023-03-03 14:20:27 +0000 |
---|---|---|
committer | Eric Covener <covener@apache.org> | 2023-03-03 14:20:27 +0000 |
commit | cb6ad2f13850c3c68f78b233fcfadeac45125201 (patch) | |
tree | fee49f5ad4c7e36cba1a033da0ce371f529bc184 | |
parent | 706538cafe99fac1d07e96d37660c0f655061aaa (diff) | |
download | httpd-cb6ad2f13850c3c68f78b233fcfadeac45125201.tar.gz |
backport 1906428,1906433,1907993 from trunk
add rotatelogs -T to truncate all but the first-opened file.
+ docs tweak for compat
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1908025 13f79535-47bb-0310-9956-ffa450edef68
-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 | 41 |
3 files changed, 56 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 f152721af6..5b31a8af0e 100644 --- a/docs/manual/programs/rotatelogs.xml +++ b/docs/manual/programs/rotatelogs.xml @@ -104,6 +104,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. Available in 2.4.56 and later. +</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 @@ -242,6 +249,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 3227b552fa..e0819da548 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" @@ -380,6 +382,8 @@ static void doRotate(rotate_config_t *config, rotate_status_t *status) apr_status_t rv; 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); @@ -459,8 +463,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. */ @@ -474,6 +487,19 @@ static void doRotate(rotate_config_t *config, rotate_status_t *status) /* New log file is now 'current'. */ status->current = newlog; + + /* The first write to the initial file hasn't checked for size. + * In the normalized timestamp case and the custom strftime case with + * any reasonable accuracy, it's futile as the rotation will pick the + * same filename again. + * For -n, when not truncating, check and rotate. + */ + if (config->num_files > 0 && oldreason == ROTATE_NEW && !config->truncate) { + checkRotate(config, status); + if (status->rotateReason != ROTATE_NONE) { + doRotate(config, status); + } + } } else { char *error = apr_psprintf(newlog.pool, "%pm", &rv); @@ -585,9 +611,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': @@ -612,6 +638,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; |