Changes with Apache 2.0.15-dev
+
+ *) Enhance rotatelogs so that a UTC offset can be specified, and
+ the logfile name can be formatted using strftime(3). (Brought
+ forward from 1.3.) [Ken Coar]
+
*) Reimplement the Windows MPM (mpm_winnt.c) to eliminate calling
DuplicateHandle on an IOCompletionPort (a practice which
MS "discourages"). The new model does not rely on associating
-.TH rotatelogs 8 "March 1998"
+.TH rotatelogs 8 "March 2001"
.\" The Apache Software License, Version 1.1
.\"
.\" Copyright (c) 2000-2001 The Apache Software Foundation. All rights
.B rotatelogs
.I logfile
.I rotationtime
+.I [offset]
.PP
.SH DESCRIPTION
.B rotatelogs
feature which can be used like this:
.fi
- TransferLog "|rotatelogs /path/to/logs/access_log 86400"
+ TransferLog "| rotatelogs /path/to/logs/access_log 86400"
.mf
This creates the files /path/to/logs/access_log.nnnn where nnnn is the system
of each rotation time (here after 24 hours) a new log is started.
.SH OPTIONS
.IP \fB\fIlogfile\fP
-The path plus basename of the logfile. The suffix .nnnn is automatically
-added.
+The path plus basename of the logfile. If \fBlogfile\fP includes any
+'%' characters, it is treated as a format string for \fIstrftime(3)\fP.
+Otherwise, the suffix .nnnn is automatically added and is the time at which
+the logfile was created.
.IP \fB\fIrotationtime\fP
The rotation time in seconds.
+.IP \fB\fIoffset\fP
+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 \fI-300\fP for this argument.
.PD
.SH SEE ALSO
.BR httpd(8)
-.
char buf[BUFSIZE], buf2[MAX_PATH], errbuf[ERRMSGSZ];
time_t tLogEnd = 0, tRotation;
int nLogFD = -1, nLogFDprev = -1, nMessCount = 0, nRead, nWrite;
+ int utc_offset = 0;
+ int use_strftime = 0;
+ time_t now;
char *szLogRoot;
- if (argc != 3) {
+ if (argc < 3) {
fprintf(stderr,
- "%s <logfile> <rotation time in seconds>\n\n",
+ "Usage: %s <logfile> <rotation time in seconds> "
+ "[offset minutes from UTC]\n\n",
argv[0]);
#ifdef OS2
fprintf(stderr,
}
szLogRoot = argv[1];
+ if (argc >= 4) {
+ utc_offset = atoi(argv[3]) * 60;
+ }
tRotation = atoi(argv[2]);
if (tRotation <= 0) {
fprintf(stderr, "Rotation time must be > 0\n");
exit(6);
}
+ use_strftime = (strstr(szLogRoot, "%") != NULL);
for (;;) {
nRead = read(0, buf, sizeof buf);
+ now = time(NULL) + utc_offset;
if (nRead == 0)
exit(3);
if (nRead < 0)
if (errno != EINTR)
exit(4);
- if (nLogFD >= 0 && (time(NULL) >= tLogEnd || nRead < 0)) {
+ if (nLogFD >= 0 && (now >= tLogEnd || nRead < 0)) {
nLogFDprev = nLogFD;
nLogFD = -1;
}
if (nLogFD < 0) {
- time_t tLogStart = (time(NULL) / tRotation) * tRotation;
- sprintf(buf2, "%s.%010d", szLogRoot, (int) tLogStart);
+ time_t tLogStart = (now / tRotation) * tRotation;
+ if (use_strftime) {
+ struct tm *tm_now;
+ tm_now = gmtime(&tLogStart);
+ strftime(buf2, sizeof(buf2), szLogRoot, tm_now);
+ }
+ else {
+ sprintf(buf2, "%s.%010d", szLogRoot, (int) tLogStart);
+ }
tLogEnd = tLogStart + tRotation;
nLogFD = open(buf2, O_WRONLY | O_CREAT | O_APPEND, 0666);
if (nLogFD < 0) {