From: Jim Jagielski Date: Mon, 26 Nov 2007 13:50:03 +0000 (+0000) Subject: super cool rotatelogs enhancements X-Git-Tag: 2.2.7~193 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=69186eacce5cb136236849a6f1ab7619b1a3684a;p=thirdparty%2Fapache%2Fhttpd.git super cool rotatelogs enhancements git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@598272 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 6860af1b1a0..d7d49aea519 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,10 @@ -*- coding: utf-8 -*- Changes with Apache 2.2.7 + *) rotatelogs: Change command-line parsing to report more types + of errors. Allow local timestamps to be used when rotating based + on file size. [Jeff Trawick] + *) mod_proxy: Canonicalisation improvements. Add "nocanon" keyword to ProxyPass, to suppress URI-canonicalisation in a reverse proxy. Also, don't escape/unescape forward-proxied URLs. diff --git a/STATUS b/STATUS index ae07be2d247..29b55df6aa4 100644 --- a/STATUS +++ b/STATUS @@ -79,18 +79,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * rotatelogs: Change command-line parsing to report more types - of errors. Allow local timestamps to be used when rotating based - on file size. - trunk: - http://svn.apache.org/viewvc?view=rev&revision=596698 - http://svn.apache.org/viewvc?view=rev&revision=596796 - http://svn.apache.org/viewvc?view=rev&revision=596830 - http://svn.apache.org/viewvc?view=rev&revision=596884 - 2.2.x: - Trunk patches apply, but here is a consolidated patch: - http://people.apache.org/~trawick/rotatelogs.txt - +1: trawick, rpluem, jim PATCHES PROPOSED TO BACKPORT FROM TRUNK: [ New proposals should be added at the end of the list ] diff --git a/docs/manual/programs/rotatelogs.xml b/docs/manual/programs/rotatelogs.xml index 86ebb94476a..acfae444f58 100644 --- a/docs/manual/programs/rotatelogs.xml +++ b/docs/manual/programs/rotatelogs.xml @@ -27,33 +27,8 @@

rotatelogs is a simple program for use in - conjunction with Apache's piped logfile feature. For example:

- - - CustomLog "|bin/rotatelogs /var/logs/logfile 86400" common - - -

This creates the files /var/logs/logfile.nnnn where nnnn is - the system time at which the log nominally starts (this time - will always be a multiple of the rotation time, so you can - synchronize cron scripts with it). At the end of each rotation - time (here after 24 hours) a new log is started.

- - - CustomLog "|bin/rotatelogs /var/logs/logfile 5M" common - - -

This configuration will rotate the logfile whenever it reaches - a size of 5 megabytes.

- - - ErrorLog "|bin/rotatelogs /var/logs/errorlog.%Y-%m-%d-%H_%M_%S 5M" - -

This configuration will rotate the error logfile whenever it - reaches a size of 5 megabytes, and the suffix to the logfile name - will be created of the form - errorlog.YYYY-mm-dd-HH_MM_SS.

- + conjunction with Apache's piped logfile feature. It supports + rotation based on a time interval or maximum size of the log.

Synopsis @@ -61,8 +36,8 @@

rotatelogs [ -l ] logfile - [ rotationtime [ offset ]] | - [ filesizeM ]

+ rotationtime|filesizeM + [ offset ]

Options @@ -71,8 +46,10 @@
-l
Causes the use of local time rather than GMT as the base for the -interval. Note that using -l in an environment which changes the -GMT offset (such as for BST or DST) can lead to unpredictable results!
+interval or for strftime(3) formatting with size-based +rotation. Note that using -l in an environment which +changes the GMT offset (such as for BST or DST) can lead to unpredictable +results!
logfile
@@ -81,26 +58,73 @@ includes any '%' characters, it is treated as a format string for strftime(3). Otherwise, the suffix .nnnnnnnnnn is automatically added and is the time in seconds. Both formats compute the start time from the beginning of -the current period. +the current period. For example, if a rotation time of 86400 is +specified, the hour, minute, and second fields created by +strftime(3) format will all be zero, referring to the +beginning of the current 24-hour period (midnight).
rotationtime
-
The time between log file rotations in seconds.
+
The time between log file rotations in seconds. The rotation +occurs at the beginning of this interval. For example, if the +rotation time is 3600, the log file will be rotated at the beginning +of every hour; if the rotation time is 86400, the log file will be +rotated every night at midnight. (If no data is logged during an +interval, no file will be created.)
+ +
filesizeM
+ +
The maximum file size in megabytes followed by the letter +M to specify size rather than time.
offset
The number of minutes offset from UTC. If omitted, zero is assumed and UTC is used. For example, to use local time in the zone -UTC -5 hours, specify a value of -300 for this argument.
- -
filesizeM
+UTC -5 hours, specify a value of -300 for this argument. +In most cases, -l should be used instead of specifying +an offset. -
The maximum file size in megabytes followed by the letter -M to specify size rather than time. Use this parameter -in place of both rotationtime and offset.
+
Examples + + + CustomLog "|bin/rotatelogs /var/logs/logfile 86400" common + + +

This creates the files /var/logs/logfile.nnnn where nnnn is + the system time at which the log nominally starts (this time + will always be a multiple of the rotation time, so you can + synchronize cron scripts with it). At the end of each rotation + time (here after 24 hours) a new log is started.

+ + + CustomLog "|bin/rotatelogs -l /var/logs/logfile.%Y.%m.%d 86400" common + + +

This creates the files /var/logs/logfile.yyyy.mm.dd where + yyyy is the year, mm is the month, and dd is the day of the month. + Logging will switch to a new file every day at midnight, local time.

+ + + CustomLog "|bin/rotatelogs /var/logs/logfile 5M" common + + +

This configuration will rotate the logfile whenever it reaches + a size of 5 megabytes.

+ + + ErrorLog "|bin/rotatelogs /var/logs/errorlog.%Y-%m-%d-%H_%M_%S 5M" + +

This configuration will rotate the error logfile whenever it + reaches a size of 5 megabytes, and the suffix to the logfile name + will be created of the form + errorlog.YYYY-mm-dd-HH_MM_SS.

+ +
+
Portability

The following logfile format string substitutions should be diff --git a/support/rotatelogs.c b/support/rotatelogs.c index c6f99049385..a408540a1b6 100644 --- a/support/rotatelogs.c +++ b/support/rotatelogs.c @@ -42,6 +42,7 @@ #include "apr_file_info.h" #include "apr_general.h" #include "apr_time.h" +#include "apr_getopt.h" #if APR_HAVE_STDLIB_H #include @@ -60,6 +61,37 @@ #define MAX_PATH 1024 #endif +static void usage(const char *argv0, const char *reason) +{ + if (reason) { + fprintf(stderr, "%s\n", reason); + } + fprintf(stderr, + "Usage: %s [-l] " + "{|} " + "[offset minutes from UTC]\n\n", + argv0); +#ifdef OS2 + fprintf(stderr, + "Add this:\n\nTransferLog \"|%s.exe /some/where 86400\"\n\n", + argv0); +#else + fprintf(stderr, + "Add this:\n\nTransferLog \"|%s /some/where 86400\"\n\n", + argv0); + fprintf(stderr, + "or \n\nTransferLog \"|%s /some/where 5M\"\n\n", argv0); +#endif + fprintf(stderr, + "to httpd.conf. The generated name will be /some/where.nnnn " + "where nnnn is the\nsystem time at which the log nominally " + "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"); + exit(1); +} + int main (int argc, const char * const argv[]) { char buf[BUFSIZE], buf2[MAX_PATH], errbuf[ERRMSGSZ]; @@ -73,71 +105,58 @@ int main (int argc, const char * const argv[]) const char *szLogRoot; apr_file_t *f_stdin, *nLogFD = NULL, *nLogFDprev = NULL; apr_pool_t *pool; + apr_getopt_t *opt; + apr_status_t rv; + char c; + const char *optarg; char *ptr = NULL; - int argBase = 0; - int argFile = 1; - int argIntv = 2; - int argOffset = 3; apr_app_initialize(&argc, &argv, NULL); atexit(apr_terminate); apr_pool_create(&pool, NULL); - if ((argc > 2) && (strcmp(argv[1], "-l") == 0)) { - argBase++; - argFile += argBase; - argIntv += argBase; - argOffset += argBase; - use_localtime = 1; + apr_getopt_init(&opt, pool, argc, argv); + while ((rv = apr_getopt(opt, "l", &c, &optarg)) == APR_SUCCESS) { + switch (c) { + case 'l': + use_localtime = 1; + break; + } } - if (argc < (argBase + 3) || argc > (argBase + 4)) { - fprintf(stderr, - "Usage: %s [-l] " - "[offset minutes from UTC] or \n\n", - argv[0]); -#ifdef OS2 - fprintf(stderr, - "Add this:\n\nTransferLog \"|%s.exe /some/where 86400\"\n\n", - argv[0]); -#else - fprintf(stderr, - "Add this:\n\nTransferLog \"|%s /some/where 86400\"\n\n", - argv[0]); - fprintf(stderr, - "or \n\nTransferLog \"|%s /some/where 5M\"\n\n", argv[0]); -#endif - fprintf(stderr, - "to httpd.conf. The generated name will be /some/where.nnnn " - "where nnnn is the\nsystem time at which the log nominally " - "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"); - exit(1); + + if (rv != APR_EOF) { + usage(argv[0], NULL /* specific error message already issued */ ); + } + + if (opt->ind + 2 != argc && opt->ind + 3 != argc) { + usage(argv[0], "Incorrect number of arguments"); } - szLogRoot = argv[argFile]; + szLogRoot = argv[opt->ind++]; - ptr = strchr(argv[argIntv], 'M'); - if (ptr) { + ptr = strchr(argv[opt->ind], 'M'); + if (ptr) { /* rotation based on file size */ if (*(ptr+1) == '\0') { - sRotation = atoi(argv[argIntv]) * 1048576; + sRotation = atoi(argv[opt->ind]) * 1048576; } if (sRotation == 0) { - fprintf(stderr, "Invalid rotation size parameter\n"); - exit(1); + usage(argv[0], "Invalid rotation size parameter"); } } - else { - if (argc >= (argBase + 4)) { - utc_offset = atoi(argv[argOffset]) * 60; - } - tRotation = atoi(argv[argIntv]); + else { /* rotation based on elapsed time */ + tRotation = atoi(argv[opt->ind]); if (tRotation <= 0) { - fprintf(stderr, "Rotation time must be > 0\n"); - exit(6); + usage(argv[0], "Invalid rotation time parameter"); } } + opt->ind++; + + if (opt->ind < argc) { /* have UTC offset */ + if (use_localtime) { + usage(argv[0], "UTC offset parameter is not valid with -l"); + } + utc_offset = atoi(argv[opt->ind]) * 60; + } use_strftime = (strchr(szLogRoot, '%') != NULL); if (apr_file_open_stdin(&f_stdin, pool) != APR_SUCCESS) { @@ -194,7 +213,16 @@ int main (int argc, const char * const argv[]) tLogStart = (now / tRotation) * tRotation; } else { - tLogStart = (int)apr_time_sec(apr_time_now()); + if (use_localtime) { + /* Check for our UTC offset before using it, since it might + * change if there's a switch between standard and daylight + * savings time. + */ + apr_time_exp_t lt; + apr_time_exp_lt(<, apr_time_now()); + utc_offset = lt.tm_gmtoff; + } + tLogStart = (int)apr_time_sec(apr_time_now()) + utc_offset; } if (use_strftime) {