You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by tr...@apache.org on 2008/05/09 15:43:25 UTC
svn commit: r654811 - in /httpd/httpd/branches/2.2.x: CHANGES STATUS
support/rotatelogs.c
Author: trawick
Date: Fri May 9 06:43:24 2008
New Revision: 654811
URL: http://svn.apache.org/viewvc?rev=654811&view=rev
Log:
rotatelogs: sync with trunk to pick up
enhanced error logging:
http://svn.apache.org/viewvc?view=rev&revision=646845
-f option to create logfile ASAP:
http://svn.apache.org/viewvc?view=rev&revision=632355
PR 40183. Don't leak memory when reopening the logfile:
http://svn.apache.org/viewvc?view=rev&revision=615901
avoid extra apr_time_now() calls and code bloat:
http://svn.apache.org/viewvc?view=rev&revision=600154
Reviewed by: wrowe, covener, trawick
Modified:
httpd/httpd/branches/2.2.x/CHANGES
httpd/httpd/branches/2.2.x/STATUS
httpd/httpd/branches/2.2.x/support/rotatelogs.c
Modified: httpd/httpd/branches/2.2.x/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/CHANGES?rev=654811&r1=654810&r2=654811&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/CHANGES [utf-8] (original)
+++ httpd/httpd/branches/2.2.x/CHANGES [utf-8] Fri May 9 06:43:24 2008
@@ -1,6 +1,19 @@
-*- coding: utf-8 -*-
Changes with Apache 2.2.9
+ *) rotatelogs: Log the current file size and error code/description
+ when failing to write to the log file. [Jeff Trawick]
+
+ *) rotatelogs: Added '-f' option to force rotatelogs to create the
+ logfile as soon as started, and not wait until it reads the
+ first entry. [Jim Jagielski]
+
+ *) rotatelogs: Don't leak memory when reopening the logfile.
+ PR 40183 [Ruediger Pluem, Takashi Sato <serai lans-tv.com>]
+
+ *) rotatelogs: Improve atomicity when using -l and cleaup code.
+ PR 44004 [Rainer Jung]
+
*) mod_authn_dbd: Disambiguate and tidy database authentication
error messages. PR 43210. [Chris Darroch, Phil Endecott
<spam_from_apache_bugzilla chezphil.org>]
Modified: httpd/httpd/branches/2.2.x/STATUS
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/STATUS?rev=654811&r1=654810&r2=654811&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/STATUS (original)
+++ httpd/httpd/branches/2.2.x/STATUS Fri May 9 06:43:24 2008
@@ -198,19 +198,6 @@
need to do a DNS query each time) when we only want to prevent that
this connection is kept alive?
- * rotatelogs: sync with trunk to pick up
- . enhanced error logging:
- http://svn.apache.org/viewvc?view=rev&revision=646845
- . -f option to create logfile ASAP:
- http://svn.apache.org/viewvc?view=rev&revision=632355
- . PR 40183. Don't leak memory when reopening the logfile:
- http://svn.apache.org/viewvc?view=rev&revision=615901
- . avoid extra apr_time_now() calls and code bloat:
- http://svn.apache.org/viewvc?view=rev&revision=600154
- Backport version for 2.2.x:
- http://people.apache.org/~trawick/rotatelogs_sync.txt
- +1: trawick, covener, wrowe
-
PATCHES/ISSUES THAT ARE STALLED
* beos MPM: Create pmain pool and run modules' child_init hooks when
Modified: httpd/httpd/branches/2.2.x/support/rotatelogs.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/support/rotatelogs.c?rev=654811&r1=654810&r2=654811&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/support/rotatelogs.c (original)
+++ httpd/httpd/branches/2.2.x/support/rotatelogs.c Fri May 9 06:43:24 2008
@@ -31,6 +31,9 @@
* interval. NB: Using -l in an environment which changes the GMT offset
* (such as for BST or DST) can lead to unpredictable results!
*
+ * -f option added Feb, 2008. This causes rotatelog to open/create
+ * the logfile as soon as it's started, not as soon as it sees
+ * data.
*/
@@ -55,7 +58,7 @@
#endif
#define BUFSIZE 65536
-#define ERRMSGSZ 128
+#define ERRMSGSZ 256
#ifndef MAX_PATH
#define MAX_PATH 1024
@@ -67,7 +70,7 @@
fprintf(stderr, "%s\n", reason);
}
fprintf(stderr,
- "Usage: %s [-l] <logfile> "
+ "Usage: %s [-l] [-f] <logfile> "
"{<rotation time in seconds>|<rotation size in megabytes>} "
"[offset minutes from UTC]\n\n",
argv0);
@@ -92,6 +95,21 @@
exit(1);
}
+static int get_now(int use_localtime, int utc_offset)
+{
+ apr_time_t tNow = 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(<, tNow);
+ utc_offset = lt.tm_gmtoff;
+ }
+ return (int)apr_time_sec(tNow) + utc_offset;
+}
+
int main (int argc, const char * const argv[])
{
char buf[BUFSIZE], buf2[MAX_PATH], errbuf[ERRMSGSZ];
@@ -101,10 +119,13 @@
apr_size_t nRead, nWrite;
int use_strftime = 0;
int use_localtime = 0;
+ int bypass_io = 0;
int now = 0;
const char *szLogRoot;
apr_file_t *f_stdin, *nLogFD = NULL, *nLogFDprev = NULL;
apr_pool_t *pool;
+ apr_pool_t *pfile = NULL;
+ apr_pool_t *pfile_prev = NULL;
apr_getopt_t *opt;
apr_status_t rv;
char c;
@@ -116,11 +137,14 @@
apr_pool_create(&pool, NULL);
apr_getopt_init(&opt, pool, argc, argv);
- while ((rv = apr_getopt(opt, "l", &c, &optarg)) == APR_SUCCESS) {
+ while ((rv = apr_getopt(opt, "lf", &c, &optarg)) == APR_SUCCESS) {
switch (c) {
case 'l':
use_localtime = 1;
break;
+ case 'f':
+ bypass_io = 1;
+ break;
}
}
@@ -166,21 +190,20 @@
for (;;) {
nRead = sizeof(buf);
- if (apr_file_read(f_stdin, buf, &nRead) != APR_SUCCESS) {
- exit(3);
+ /*
+ * Bypass reading stdin if we are forcing the logfile
+ * to be opened as soon as we start. Since we won't be
+ * writing anything, we just want to open the file.
+ * First time through is the only time we do this
+ * since we reset bypass_io after the 1st loop
+ */
+ if (!bypass_io) {
+ if (apr_file_read(f_stdin, buf, &nRead) != APR_SUCCESS) {
+ exit(3);
+ }
}
if (tRotation) {
- /*
- * Check for our UTC offset every time through the loop, since
- * it might change if there's a switch between standard and
- * daylight savings time.
- */
- if (use_localtime) {
- apr_time_exp_t lt;
- apr_time_exp_lt(<, apr_time_now());
- utc_offset = lt.tm_gmtoff;
- }
- now = (int)(apr_time_now() / APR_USEC_PER_SEC) + utc_offset;
+ now = get_now(use_localtime, utc_offset);
if (nLogFD != NULL && now >= tLogEnd) {
nLogFDprev = nLogFD;
nLogFD = NULL;
@@ -213,16 +236,7 @@
tLogStart = (now / tRotation) * tRotation;
}
else {
- 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;
+ tLogStart = get_now(use_localtime, utc_offset);
}
if (use_strftime) {
@@ -237,8 +251,10 @@
sprintf(buf2, "%s.%010d", szLogRoot, tLogStart);
}
tLogEnd = tLogStart + tRotation;
+ pfile_prev = pfile;
+ apr_pool_create(&pfile, pool);
rv = apr_file_open(&nLogFD, buf2, APR_WRITE | APR_CREATE | APR_APPEND,
- APR_OS_DEFAULT, pool);
+ APR_OS_DEFAULT, pfile);
if (rv != APR_SUCCESS) {
char error[120];
@@ -253,6 +269,8 @@
}
else {
nLogFD = nLogFDprev;
+ apr_pool_destroy(pfile);
+ pfile = pfile_prev;
/* Try to keep this error message constant length
* in case it occurs several times. */
apr_snprintf(errbuf, sizeof errbuf,
@@ -269,26 +287,58 @@
}
else if (nLogFDprev) {
apr_file_close(nLogFDprev);
+ if (pfile_prev) {
+ apr_pool_destroy(pfile_prev);
+ }
}
nMessCount = 0;
}
- nWrite = nRead;
- apr_file_write(nLogFD, buf, &nWrite);
- if (nWrite != nRead) {
- nMessCount++;
- sprintf(errbuf,
- "Error writing to log file. "
- "%10d messages lost.\n",
- nMessCount);
- nWrite = strlen(errbuf);
- apr_file_trunc(nLogFD, 0);
- if (apr_file_write(nLogFD, errbuf, &nWrite) != APR_SUCCESS) {
- fprintf(stderr, "Error writing to the file %s\n", buf2);
+ /*
+ * If we just bypassed reading stdin, due to bypass_io,
+ * then we have nothing to write, so skip this.
+ */
+ if (!bypass_io) {
+ nWrite = nRead;
+ rv = apr_file_write(nLogFD, buf, &nWrite);
+ if (rv == APR_SUCCESS && nWrite != nRead) {
+ /* buffer partially written, which for rotatelogs means we encountered
+ * an error such as out of space or quota or some other limit reached;
+ * try to write the rest so we get the real error code
+ */
+ apr_size_t nWritten = nWrite;
+
+ nRead = nRead - nWritten;
+ nWrite = nRead;
+ rv = apr_file_write(nLogFD, buf + nWritten, &nWrite);
+ }
+ if (nWrite != nRead) {
+ char strerrbuf[120];
+ apr_off_t cur_offset;
+
+ cur_offset = 0;
+ if (apr_file_seek(nLogFD, APR_CUR, &cur_offset) != APR_SUCCESS) {
+ cur_offset = -1;
+ }
+ apr_strerror(rv, strerrbuf, sizeof strerrbuf);
+ nMessCount++;
+ apr_snprintf(errbuf, sizeof errbuf,
+ "Error %d writing to log file at offset %" APR_OFF_T_FMT ". "
+ "%10d messages lost (%s)\n",
+ rv, cur_offset, nMessCount, strerrbuf);
+ nWrite = strlen(errbuf);
+ apr_file_trunc(nLogFD, 0);
+ if (apr_file_write(nLogFD, errbuf, &nWrite) != APR_SUCCESS) {
+ fprintf(stderr, "Error writing to the file %s\n", buf2);
exit(2);
+ }
+ }
+ else {
+ nMessCount++;
}
}
else {
- nMessCount++;
+ /* now worry about reading 'n writing all the time */
+ bypass_io = 0;
}
}
/* Of course we never, but prevent compiler warnings */