From a71d8fea48fd248a69e38718bba49d64d53a0512 Mon Sep 17 00:00:00 2001 From: Jim Jagielski Date: Mon, 9 Apr 2018 15:36:59 +0000 Subject: [PATCH] Merge r1533810, r1533935, r1666417 from trunk: Add an option to autocreate directories to rotatelogs. * support/rotatelogs.c (rotate_config): Remove const from szLogRoot since we'll be passing it to apr_filepath_merge. Add create_path member. (usage, dumpConfig): Update to reflect new -d option. (doRotate): Add code that knows how to create the directories a log file is going to go into. (main): Add the -d option and canonicalize the incoming path with apr_filepath_merge() so that the code in doRotate can work properly. * docs/man/rotatelogs.8, docs/manual/programs/rotatelogs.html.en: Update for -d option. PR: 46669 Submitted by: Philippe Lantin (which was actually a patch written by myself when I worked there) Tweaked by: breser (ported to trunk and changed option from -p to -d) Followup to r1533810: Put the rotatelogs docs in the right place. * docs/man/rotatelogs.8, docs/manual/programs/rotatelogs.html.en: Remove changes from r1533810. * docs/manual/programs/rotatelogs.xml: Adjust docs for new -d option. Choose "-D" instead of "-d" for the rotatelogs option that creates the path to the log file. I want to use "-d" for another directory related option next where (I think) the "directory" "d" makes more sense. "-d" has not yet been backported, so changing to "-D" is not a real compatibility issue. Submitted by: breser, rjung Reviewed by: rjung, ylavic, niq git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1828738 13f79535-47bb-0310-9956-ffa450edef68 --- STATUS | 25 ------------------ docs/man/rotatelogs.8 | 7 ++++-- docs/manual/programs/rotatelogs.xml | 6 +++++ support/rotatelogs.c | 39 ++++++++++++++++++++++++----- 4 files changed, 44 insertions(+), 33 deletions(-) diff --git a/STATUS b/STATUS index ac221544df..69a4dd9172 100644 --- a/STATUS +++ b/STATUS @@ -138,31 +138,6 @@ PATCHES ACCEPTED TO BACKPORT FROM TRUNK: 2.4.x patch: svn merge -c 1826973 ^/httpd/httpd/trunk . +1: rjung, ylavic, jim - *) rotatelogs: Add an option to autocreate directories to rotatelogs. - PR: 46669 - trunk patch: http://svn.apache.org/r1533810 - http://svn.apache.org/r1533935 - 2.4.x patch: https://home.apache.org/~rjung/patches/httpd-2.4.x-rotatelogs-create-directories-v2.patch - plus CHANGES for new "-d" flag (see svn log for credits). - Merge only fails due to small docs conflicts. - +1: rjung, ylavic, niq - jung: I'll wait a bit whether the below remaining rotatelogs patch makes it to apply in order. - - *) rotatelogs: Choose "-D" instead of "-d" for the rotatelogs - option that creates the path to the log file. - I want to use "-d" for another directory related - option next where (I think) the "directory" "d" - makes more sense. - "-d" has not yet been backported, so changing - to "-D" is not a real compatibility issue. - This brings 2.4.x rotatelogs in sync with trunk. - trunk patch: http://svn.apache.org/r1666417 - 2.4.x patch: https://home.apache.org/~rjung/patches/httpd-2.4.x-rotatelogs-create-directories-rename-flag.patch - plus CHANGES change from "-d" to "-D" - Merge only fails due to small docs conflicts. - +1: rjung, ylavic, niq - jung: I'll wait a bit whether the below remaining rotatelogs patch makes it to apply in order. - *) Some easy proposals: - mod_logio, mod_ssl: Remove pointless static in optional fn pointer variable declaration diff --git a/docs/man/rotatelogs.8 b/docs/man/rotatelogs.8 index 9b66c61655..b2970631e6 100644 --- a/docs/man/rotatelogs.8 +++ b/docs/man/rotatelogs.8 @@ -19,7 +19,7 @@ .el .ne 3 .IP "\\$1" \\$2 .. -.TH "ROTATELOGS" 8 "2015-01-01" "Apache HTTP Server" "rotatelogs" +.TH "ROTATELOGS" 8 "2018-03-15" "Apache HTTP Server" "rotatelogs" .SH NAME rotatelogs \- Piped logging program to rotate Apache logs @@ -27,7 +27,7 @@ rotatelogs \- Piped logging program to rotate Apache logs .SH "SYNOPSIS" .PP -\fBrotatelogs\fR [ -\fBl\fR ] [ -\fBL\fR \fIlinkname\fR ] [ -\fBp\fR \fIprogram\fR ] [ -\fBf\fR ] [ -\fBt\fR ] [ -\fBv\fR ] [ -\fBe\fR ] [ -\fBc\fR ] [ -\fBn\fR \fInumber-of-files\fR ] \fIlogfile\fR \fIrotationtime\fR|\fIfilesize\fR(B|K|M|G) [ \fIoffset\fR ] +\fBrotatelogs\fR [ -\fBl\fR ] [ -\fBL\fR \fIlinkname\fR ] [ -\fBp\fR \fIprogram\fR ] [ -\fBf\fR ] [ -\fBD\fR ] [ -\fBt\fR ] [ -\fBv\fR ] [ -\fBe\fR ] [ -\fBc\fR ] [ -\fBn\fR \fInumber-of-files\fR ] \fIlogfile\fR \fIrotationtime\fR|\fIfilesize\fR(B|K|M|G) [ \fIoffset\fR ] .SH "SUMMARY" @@ -52,6 +52,9 @@ If given, rotatelogs will execute the specified program every time a new log fil -f Causes the logfile to be opened immediately, as soon as rotatelogs starts, instead of waiting for the first logfile entry to be read (for non-busy sites, there may be a substantial delay between when the server is started 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) .TP +-D +Creates the parent directories of the path that the log file will be placed in if they do not already exist\&. This allows strftime(3) formatting to be used in the path and not just the filename\&. +.TP -t 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\&. .TP diff --git a/docs/manual/programs/rotatelogs.xml b/docs/manual/programs/rotatelogs.xml index 79aa84eba3..eb472c1d99 100644 --- a/docs/manual/programs/rotatelogs.xml +++ b/docs/manual/programs/rotatelogs.xml @@ -38,6 +38,7 @@ [ -L linkname ] [ -p program ] [ -f ] + [ -D ] [ -t ] [ -v ] [ -e ] @@ -84,6 +85,11 @@ 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) +
-D
+
Creates the parent directories of the path that the log file will be +placed in if they do not already exist. This allows strftime(3) +formatting to be used in the path and not just the filename.
+
-t
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, diff --git a/support/rotatelogs.c b/support/rotatelogs.c index 75cf587055..26e8b47fe1 100644 --- a/support/rotatelogs.c +++ b/support/rotatelogs.c @@ -64,7 +64,7 @@ struct rotate_config { int force_open; int verbose; int echo; - const char *szLogRoot; + char *szLogRoot; int truncate; const char *linkfile; const char *postrotate_prog; @@ -72,6 +72,7 @@ struct rotate_config { int create_empty; #endif int num_files; + int create_path; }; typedef struct rotate_status rotate_status_t; @@ -110,9 +111,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] [-t] [-e] [-c] [-n number] " + "Usage: %s [-v] [-l] [-L linkname] [-p prog] [-f] [-D] [-t] [-e] [-c] [-n number] " #else - "Usage: %s [-v] [-l] [-L linkname] [-p prog] [-f] [-t] [-e] [-n number] " + "Usage: %s [-v] [-l] [-L linkname] [-p prog] [-f] [-D] [-t] [-e] [-n number] " #endif "{|(B|K|M|G)} " "[offset minutes from UTC]\n\n", @@ -144,6 +145,7 @@ static void usage(const char *argv0, const char *reason) " -L path Create hard link from current log to specified path.\n" " -p prog Run specified program after opening a new log file. See below.\n" " -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" " -e Echo log to stdout for further processing.\n" #if APR_FILES_AS_SOCKETS @@ -208,6 +210,7 @@ static void dumpConfig (rotate_config_t *config) fprintf(stderr, "Rotation based on localtime: %12s\n", config->use_localtime ? "yes" : "no"); fprintf(stderr, "Rotation file date pattern: %12s\n", config->use_strftime ? "yes" : "no"); fprintf(stderr, "Rotation file forced open: %12s\n", config->force_open ? "yes" : "no"); + fprintf(stderr, "Create parent directories: %12s\n", config->create_path ? "yes" : "no"); fprintf(stderr, "Rotation verbose: %12s\n", config->verbose ? "yes" : "no"); #if APR_FILES_AS_SOCKETS fprintf(stderr, "Rotation create empty logs: %12s\n", config->create_empty ? "yes" : "no"); @@ -438,6 +441,23 @@ static void doRotate(rotate_config_t *config, rotate_status_t *status) } } apr_pool_create(&newlog.pool, status->pool); + if (config->create_path) { + char *ptr = strrchr(newlog.name, '/'); + if (ptr && ptr > newlog.name) { + char *path = apr_pstrmemdup(newlog.pool, newlog.name, ptr - newlog.name); + if (config->verbose) { + fprintf(stderr, "Creating directory tree %s\n", path); + } + rv = apr_dir_make_recursive(path, APR_FPROT_OS_DEFAULT, newlog.pool); + if (rv != APR_SUCCESS) { + char error[120]; + + apr_strerror(rv, error, sizeof error); + fprintf(stderr, "Could not create directory '%s' (%s)\n", path, error); + exit(2); + } + } + } if (config->verbose) { fprintf(stderr, "Opening file %s\n", newlog.name); } @@ -568,9 +588,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:ftvecn:", &c, &opt_arg)) == APR_SUCCESS) { + while ((rv = apr_getopt(opt, "lL:p:fDtvecn:", &c, &opt_arg)) == APR_SUCCESS) { #else - while ((rv = apr_getopt(opt, "lL:p:ftven:", &c, &opt_arg)) == APR_SUCCESS) { + while ((rv = apr_getopt(opt, "lL:p:fDtven:", &c, &opt_arg)) == APR_SUCCESS) { #endif switch (c) { case 'l': @@ -589,6 +609,9 @@ int main (int argc, const char * const argv[]) case 'f': config.force_open = 1; break; + case 'D': + config.create_path = 1; + break; case 't': config.truncate = 1; break; @@ -623,7 +646,11 @@ int main (int argc, const char * const argv[]) usage(argv[0], "Incorrect number of arguments"); } - config.szLogRoot = argv[opt->ind++]; + rv = apr_filepath_merge(&config.szLogRoot, "", argv[opt->ind++], + APR_FILEPATH_TRUENAME, status.pool); + if (rv != APR_SUCCESS && rv != APR_EPATHWILD) { + usage(argv[0], "Invalid filename given"); + } /* Read in the remaining flags, namely time, size and UTC offset. */ for(; opt->ind < argc; opt->ind++) { -- 2.40.0