diff options
author | Rainer Jung <rjung@apache.org> | 2009-01-11 22:45:53 +0000 |
---|---|---|
committer | Rainer Jung <rjung@apache.org> | 2009-01-11 22:45:53 +0000 |
commit | 618c7592fc759ec3ca9b784894c4f40ea0ca087a (patch) | |
tree | 2146e747d26261d39f49c26e8c9a272a2cd5e120 /support | |
parent | fd9690630283497232dba036aeb20aa884d6ce79 (diff) | |
download | httpd-618c7592fc759ec3ca9b784894c4f40ea0ca087a.tar.gz |
Allow size units B, K, M, G and combination of
time and size based rotation for rotatelogs.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@733531 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'support')
-rw-r--r-- | support/rotatelogs.c | 145 |
1 files changed, 116 insertions, 29 deletions
diff --git a/support/rotatelogs.c b/support/rotatelogs.c index 8e60288074..64f7a24d8e 100644 --- a/support/rotatelogs.c +++ b/support/rotatelogs.c @@ -153,6 +153,10 @@ static void usage(const char *argv0, const char *reason) exit(1); } +/* + * Get the unix time with timezone corrections + * given in the config struct. + */ static int get_now(rotate_config_t *config) { apr_time_t tNow = apr_time_now(); @@ -169,6 +173,9 @@ static int get_now(rotate_config_t *config) return (int)apr_time_sec(tNow) + utc_offset; } +/* + * Close a file and destroy the associated pool. + */ static void closeFile(rotate_config_t *config, apr_pool_t *pool, apr_file_t *file) { if (file != NULL) { @@ -186,6 +193,9 @@ static void closeFile(rotate_config_t *config, apr_pool_t *pool, apr_file_t *fil } } +/* + * Dump the configuration parsing result to STDERR. + */ static void dumpConfig (rotate_config_t *config) { fprintf(stderr, "Rotation time interval: %12d\n", config->tRotation); @@ -198,6 +208,22 @@ static void dumpConfig (rotate_config_t *config) fprintf(stderr, "Rotation file name: %21s\n", config->szLogRoot); } +/* + * Check whether we need to rotate. + * Possible reasons are: + * - No log file open (ROTATE_NEW) + * - User forces us to rotate (ROTATE_FORCE) + * - Our log file size is already bigger than the + * allowed maximum (ROTATE_SIZE) + * - The next log time interval expired (ROTATE_TIME) + * + * When size and time constraints are both given, + * it suffices that one of them is fulfilled. + * + * If the method finds a reason for rotation, + * and it hasn't been called while log data is available, + * it will close the open log file as a side effect. + */ static void checkRotate(rotate_config_t *config, rotate_status_t *status) { @@ -207,11 +233,6 @@ static void checkRotate(rotate_config_t *config, rotate_status_t *status) else if (status->checkReason == CHECK_SIG_FORCE) { status->rotateReason = ROTATE_FORCE; } - else if (config->tRotation) { - if (get_now(config) >= status->tLogEnd) { - status->rotateReason = ROTATE_TIME; - } - } else if (config->sRotation) { apr_finfo_t finfo; apr_off_t current_size = -1; @@ -223,6 +244,16 @@ static void checkRotate(rotate_config_t *config, rotate_status_t *status) if (current_size > config->sRotation) { status->rotateReason = ROTATE_SIZE; } + else if (config->tRotation) { + if (get_now(config) >= status->tLogEnd) { + status->rotateReason = ROTATE_TIME; + } + } + } + else if (config->tRotation) { + if (get_now(config) >= status->tLogEnd) { + status->rotateReason = ROTATE_TIME; + } } else { fprintf(stderr, "No rotation time or size specified\n"); @@ -246,6 +277,17 @@ static void checkRotate(rotate_config_t *config, rotate_status_t *status) return; } +/* + * Open a new log file, and if successful + * also close the old one. + * + * The timestamp for the calculation of the file + * name of the new log file will be the actual millisecond + * timestamp, except when a regular rotation based on a time + * interval is configured and the previous interval + * is over. Then the timestamp is the starting time + * of the actual interval. + */ static void doRotate(rotate_config_t *config, rotate_status_t *status) { @@ -343,7 +385,7 @@ static void doRotate(rotate_config_t *config, rotate_status_t *status) static void external_rotate(int signal) { /* - * Set marker for signal triggered rotation + * Set marker for signal triggered rotation check */ if (signal == SIG_FORCE) { status.checkReason = CHECK_SIG_FORCE; @@ -364,6 +406,61 @@ static void external_rotate(int signal) } #endif +/* + * Get a size or time param from a string. + * Parameter 'last' indicates, whether the + * argument is the last commadnline argument. + * UTC offset is only allowed as a last argument + * in order to make is distinguishable from the + * rotation interval time. + */ +static const char *get_time_or_size(rotate_config_t *config, + const char *arg, int last) { + char *ptr = NULL; + /* Byte multiplier */ + unsigned int mult = 1; + if ((ptr = strchr(arg, 'B')) != NULL) { /* Found KB size */ + mult = 1; + } + else if ((ptr = strchr(arg, 'K')) != NULL) { /* Found KB size */ + mult = 1024; + } + else if ((ptr = strchr(arg, 'M')) != NULL) { /* Found MB size */ + mult = 1024 * 1024; + } + else if ((ptr = strchr(arg, 'G')) != NULL) { /* Found GB size */ + mult = 1024 * 1024 * 1024; + } + if (ptr) { /* rotation based on file size */ + if (config->sRotation > 0) { + return "Rotation size parameter allowed only once"; + } + if (*(ptr+1) == '\0') { + config->sRotation = atoi(arg) * mult; + } + if (config->sRotation == 0) { + return "Invalid rotation size parameter"; + } + } + else if ((config->sRotation > 0 || config->tRotation > 0) && last) { + /* rotation based on elapsed time */ + if (config->use_localtime) { + return "UTC offset parameter is not valid with -l"; + } + config->utc_offset = atoi(arg) * 60; + } + else { /* rotation based on elapsed time */ + if (config->tRotation > 0) { + return "Rotation time parameter allowed only once"; + } + config->tRotation = atoi(arg); + if (config->tRotation <= 0) { + return "Invalid rotation time parameter"; + } + } + return NULL; +} + int main (int argc, const char * const argv[]) { char buf[BUFSIZE]; @@ -373,7 +470,7 @@ int main (int argc, const char * const argv[]) apr_status_t rv; char c; const char *optarg; - char *ptr = NULL; + const char *err = NULL; apr_app_initialize(&argc, &argv, NULL); atexit(apr_terminate); @@ -415,37 +512,27 @@ int main (int argc, const char * const argv[]) usage(argv[0], NULL /* specific error message already issued */ ); } - if ((argc - opt->ind < 2) || (argc - opt->ind > 3) ) { + /* + * After the initial flags we need 2 to 4 arguments, + * the file name, either the rotation interval time or size + * or both of them, and optionally the UTC offset. + */ + if ((argc - opt->ind < 2) || (argc - opt->ind > 4) ) { usage(argv[0], "Incorrect number of arguments"); } config.szLogRoot = argv[opt->ind++]; - ptr = strchr(argv[opt->ind], 'M'); - if (ptr) { /* rotation based on file size */ - if (*(ptr+1) == '\0') { - config.sRotation = atoi(argv[opt->ind]) * 1048576; - } - if (config.sRotation == 0) { - usage(argv[0], "Invalid rotation size parameter"); - } - } - else { /* rotation based on elapsed time */ - config.tRotation = atoi(argv[opt->ind]); - if (config.tRotation <= 0) { - usage(argv[0], "Invalid rotation time parameter"); - } - } - opt->ind++; - - if (opt->ind < argc) { /* have UTC offset */ - if (config.use_localtime) { - usage(argv[0], "UTC offset parameter is not valid with -l"); + /* Read in the remaining flags, namely time, size and UTC offset. */ + for(; opt->ind < argc; opt->ind++) { + if ((err = get_time_or_size(&config, argv[opt->ind], + opt->ind < argc - 1 ? 0 : 1)) != NULL) { + usage(argv[0], err); } - config.utc_offset = atoi(argv[opt->ind]) * 60; } config.use_strftime = (strchr(config.szLogRoot, '%') != NULL); + if (apr_file_open_stdin(&f_stdin, status.pool) != APR_SUCCESS) { fprintf(stderr, "Unable to open stdin\n"); exit(1); |