.SH "SYNOPSIS"
.PP
-\fBrotatelogs\fR [ -\fBl\fR ] \fIlogfile\fR \fIrotationtime\fR|\fIfilesize\fRM [ \fIoffset\fR ]
+\fBrotatelogs\fR [ -\fBl\fR ] [ -\fBf\fR ] \fIlogfile\fR \fIrotationtime\fR|\fIfilesize\fRM [ \fIoffset\fR ]
.SH "SUMMARY"
-l
Causes the use of local time rather than GMT as the base for the 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!
.TP
+-f
+Causes the logfile to be immediately opened as soon as rotatelogs starts (instead of waiting for the first log entry)
+.TP
\fIlogfile\fR
The path plus basename of the logfile\&. If \fIlogfile\fR includes any '%' characters, it is treated as a format string for strftime(3)\&. Otherwise, the suffix \fI\&.nnnnnnnnnn\fR is automatically added and is the time in seconds\&. Both formats compute the start time from the beginning of the current period\&. For example, if a rotation time of 86400 is specified, the hour, minute, and second fields created from the strftime(3) format will all be zero, referring to the beginning of the current 24-hour period (midnight)\&.
.TP
<p><code><strong>rotatelogs</strong>
[ -<strong>l</strong> ]
+ [ -<strong>f</strong> ]
<var>logfile</var>
<var>rotationtime</var>|<var>filesize</var>M
[ <var>offset</var> ]</code></p>
changes the GMT offset (such as for BST or DST) can lead to unpredictable
results!</dd>
+<dt><code>-f</code></dt>
+<dd>Causes the logfile to be opened immediately, as soon as
+<code>rotatelogs</code> 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)</dd>
+
<dt><code><var>logfile</var></code></dt>
<dd>The path plus basename of the logfile. If <var>logfile</var>
* 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.
*/
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);
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_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;
}
}
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) {
now = get_now(use_localtime, utc_offset);
}
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;
+ 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);
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 */