|
|
fe23ba |
From 7cb2dde2b3423158f5cba06df0df078ab3bee09b Mon Sep 17 00:00:00 2001
|
|
|
fe23ba |
From: Kamil Dudka <kdudka@redhat.com>
|
|
|
fe23ba |
Date: Wed, 7 Dec 2016 16:34:13 +0100
|
|
|
fe23ba |
Subject: [PATCH] weekly: trigger the rotation more predictably
|
|
|
fe23ba |
|
|
|
fe23ba |
... by ignoring the exact time. If the (absolute) day counter
|
|
|
fe23ba |
advances by 7+ days since the last rotation, a new rotation is
|
|
|
fe23ba |
triggered.
|
|
|
fe23ba |
|
|
|
fe23ba |
Additionally, introduce an optional argument of the 'weekly' directive
|
|
|
fe23ba |
to trigger the rotation on a selected day of the week. If the argument
|
|
|
fe23ba |
is omitted, default to Sunday to preserve backward compatibility.
|
|
|
fe23ba |
|
|
|
fe23ba |
Closes #93
|
|
|
fe23ba |
|
|
|
fe23ba |
Upstream-commit: bd2638856dbbb6c0a47beb85fe8a8a628160772e
|
|
|
fe23ba |
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
|
fe23ba |
---
|
|
|
fe23ba |
config.c | 19 +++++++++++++++++++
|
|
|
fe23ba |
logrotate.8 | 12 ++++++------
|
|
|
fe23ba |
logrotate.c | 39 +++++++++++++++++++++++++++++----------
|
|
|
fe23ba |
logrotate.h | 3 ++-
|
|
|
fe23ba |
4 files changed, 56 insertions(+), 17 deletions(-)
|
|
|
fe23ba |
|
|
|
fe23ba |
diff --git a/config.c b/config.c
|
|
|
fe23ba |
index 5e7951e..700ad85 100644
|
|
|
fe23ba |
--- a/config.c
|
|
|
fe23ba |
+++ b/config.c
|
|
|
fe23ba |
@@ -410,6 +410,7 @@ static void copyLogInfo(struct logInfo *to, struct logInfo *from)
|
|
|
fe23ba |
if (from->oldDir)
|
|
|
fe23ba |
to->oldDir = strdup(from->oldDir);
|
|
|
fe23ba |
to->criterium = from->criterium;
|
|
|
fe23ba |
+ to->weekday = from->weekday;
|
|
|
fe23ba |
to->threshhold = from->threshhold;
|
|
|
fe23ba |
to->minsize = from->minsize;
|
|
|
fe23ba |
to->maxsize = from->maxsize;
|
|
|
fe23ba |
@@ -1050,7 +1051,25 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
|
|
|
fe23ba |
} else if (!strcmp(key, "monthly")) {
|
|
|
fe23ba |
newlog->criterium = ROT_MONTHLY;
|
|
|
fe23ba |
} else if (!strcmp(key, "weekly")) {
|
|
|
fe23ba |
+ unsigned weekday;
|
|
|
fe23ba |
+ char tmp;
|
|
|
fe23ba |
newlog->criterium = ROT_WEEKLY;
|
|
|
fe23ba |
+ free(key);
|
|
|
fe23ba |
+ key = isolateLine(&start, &buf, length);
|
|
|
fe23ba |
+ if (key == NULL || key[0] == '\0') {
|
|
|
fe23ba |
+ /* default to Sunday if no argument was given */
|
|
|
fe23ba |
+ newlog->weekday = 0;
|
|
|
fe23ba |
+ continue;
|
|
|
fe23ba |
+ }
|
|
|
fe23ba |
+
|
|
|
fe23ba |
+ if (1 == sscanf(key, "%u%c", &weekday, &tmp) && weekday <= 7) {
|
|
|
fe23ba |
+ /* use the selected weekday, 7 means "once per week" */
|
|
|
fe23ba |
+ newlog->weekday = weekday;
|
|
|
fe23ba |
+ continue;
|
|
|
fe23ba |
+ }
|
|
|
fe23ba |
+ message(MESS_ERROR, "%s:%d bad weekly directive '%s'\n",
|
|
|
fe23ba |
+ configFile, lineNum, key);
|
|
|
fe23ba |
+ goto error;
|
|
|
fe23ba |
} else if (!strcmp(key, "yearly")) {
|
|
|
fe23ba |
newlog->criterium = ROT_YEARLY;
|
|
|
fe23ba |
} else if (!strcmp(key, "rotate")) {
|
|
|
fe23ba |
diff --git a/logrotate.8 b/logrotate.8
|
|
|
fe23ba |
index 2db6f65..468ba0e 100644
|
|
|
fe23ba |
--- a/logrotate.8
|
|
|
fe23ba |
+++ b/logrotate.8
|
|
|
fe23ba |
@@ -526,12 +526,12 @@ is replaced. At startup, the taboo extension list
|
|
|
fe23ba |
contains .rpmsave, .rpmorig, ~, .disabled, .dpkg\-old, .dpkg\-dist, .dpkg\-new, .cfsaved, .ucf\-old, .ucf\-dist, .ucf\-new, .rpmnew, .swp, .cfsaved, .rhn\-cfg\-tmp\-*
|
|
|
fe23ba |
|
|
|
fe23ba |
.TP
|
|
|
fe23ba |
-\fBweekly\fR
|
|
|
fe23ba |
-Log files are rotated if the current weekday is less than the weekday
|
|
|
fe23ba |
-of the last rotation or if more than a week has passed since the last
|
|
|
fe23ba |
-rotation. This is normally the same as rotating logs on the first day
|
|
|
fe23ba |
-of the week, but it works better if \fIlogrotate\fR is not run every
|
|
|
fe23ba |
-night.
|
|
|
fe23ba |
+\fBweekly\fR [\fIweekday\fR]
|
|
|
fe23ba |
+Log files are rotated once each \fIweekday\fR, or if the date is advanced by at
|
|
|
fe23ba |
+least 7 days since the last rotation (while ignoring the exact time). The
|
|
|
fe23ba |
+\fIweekday\fR intepretation is following: 0 means Sunday, 1 means Monday, ...,
|
|
|
fe23ba |
+6 means Saturday; the special value 7 means each 7 days, irrespectively of
|
|
|
fe23ba |
+weekday. Defaults to 0 if the \fIweekday\fR argument is omitted.
|
|
|
fe23ba |
|
|
|
fe23ba |
.TP
|
|
|
fe23ba |
\fByearly\fR
|
|
|
fe23ba |
diff --git a/logrotate.c b/logrotate.c
|
|
|
fe23ba |
index d5da299..e056ccd 100644
|
|
|
fe23ba |
--- a/logrotate.c
|
|
|
fe23ba |
+++ b/logrotate.c
|
|
|
fe23ba |
@@ -842,6 +842,27 @@ static int copyTruncate(char *currLog, char *saveLog, struct stat *sb,
|
|
|
fe23ba |
return 0;
|
|
|
fe23ba |
}
|
|
|
fe23ba |
|
|
|
fe23ba |
+/* return value similar to mktime() but the exact time is ignored */
|
|
|
fe23ba |
+static time_t mktimeFromDateOnly(const struct tm *src)
|
|
|
fe23ba |
+{
|
|
|
fe23ba |
+ /* explicit struct copy to retain C89 compatibility */
|
|
|
fe23ba |
+ struct tm tmp;
|
|
|
fe23ba |
+ memcpy(&tmp, src, sizeof tmp);
|
|
|
fe23ba |
+
|
|
|
fe23ba |
+ /* abstract out (nullify) fields expressing the exact time */
|
|
|
fe23ba |
+ tmp.tm_hour = 0;
|
|
|
fe23ba |
+ tmp.tm_min = 0;
|
|
|
fe23ba |
+ tmp.tm_sec = 0;
|
|
|
fe23ba |
+ return mktime(&tmp);
|
|
|
fe23ba |
+}
|
|
|
fe23ba |
+
|
|
|
fe23ba |
+/* return by how many days the date was advanced but ignore exact time */
|
|
|
fe23ba |
+static int daysElapsed(const struct tm *now, const struct tm *last)
|
|
|
fe23ba |
+{
|
|
|
fe23ba |
+ const time_t diff = mktimeFromDateOnly(now) - mktimeFromDateOnly(last);
|
|
|
fe23ba |
+ return diff / (24 * 3600);
|
|
|
fe23ba |
+}
|
|
|
fe23ba |
+
|
|
|
fe23ba |
int findNeedRotating(struct logInfo *log, int logNum, int force)
|
|
|
fe23ba |
{
|
|
|
fe23ba |
struct stat sb;
|
|
|
fe23ba |
@@ -924,18 +945,16 @@ int findNeedRotating(struct logInfo *log, int logNum, int force)
|
|
|
fe23ba |
state->lastRotated.tm_mon != now.tm_mon ||
|
|
|
fe23ba |
state->lastRotated.tm_mday != now.tm_mday ||
|
|
|
fe23ba |
state->lastRotated.tm_hour != now.tm_hour) {
|
|
|
fe23ba |
+ int days;
|
|
|
fe23ba |
switch (log->criterium) {
|
|
|
fe23ba |
case ROT_WEEKLY:
|
|
|
fe23ba |
- /* rotate if:
|
|
|
fe23ba |
- 1) the current weekday is before the weekday of the
|
|
|
fe23ba |
- last rotation
|
|
|
fe23ba |
- 2) more then a week has passed since the last
|
|
|
fe23ba |
- rotation */
|
|
|
fe23ba |
- state->doRotate = ((now.tm_wday < state->lastRotated.tm_wday)
|
|
|
fe23ba |
- ||
|
|
|
fe23ba |
- ((mktime(&now) -
|
|
|
fe23ba |
- mktime(&state->lastRotated)) >
|
|
|
fe23ba |
- (7 * 24 * 3600)));
|
|
|
fe23ba |
+ days = daysElapsed(&now, &state->lastRotated);
|
|
|
fe23ba |
+ /* rotate if date is advanced by 7+ days (exact time is ignored) */
|
|
|
fe23ba |
+ state->doRotate = (days >= 7)
|
|
|
fe23ba |
+ /* ... or if we have not yet rotated today */
|
|
|
fe23ba |
+ || (days >= 1
|
|
|
fe23ba |
+ /* ... and the selected weekday is today */
|
|
|
fe23ba |
+ && now.tm_wday == log->weekday);
|
|
|
fe23ba |
if (!state->doRotate) {
|
|
|
fe23ba |
message(MESS_DEBUG, " log does not need rotating "
|
|
|
fe23ba |
"(log has been rotated at %d-%d-%d %d:%d, "
|
|
|
fe23ba |
diff --git a/logrotate.h b/logrotate.h
|
|
|
fe23ba |
index cf42703..f2d2103 100644
|
|
|
fe23ba |
--- a/logrotate.h
|
|
|
fe23ba |
+++ b/logrotate.h
|
|
|
fe23ba |
@@ -36,8 +36,9 @@ struct logInfo {
|
|
|
fe23ba |
char *oldDir;
|
|
|
fe23ba |
enum { ROT_HOURLY, ROT_DAYS, ROT_WEEKLY, ROT_MONTHLY, ROT_YEARLY, ROT_SIZE
|
|
|
fe23ba |
} criterium;
|
|
|
fe23ba |
+ int weekday; /* used by ROT_WEEKLY only */
|
|
|
fe23ba |
unsigned long long threshhold;
|
|
|
fe23ba |
- unsigned long long maxsize;
|
|
|
fe23ba |
+ unsigned long long maxsize;
|
|
|
fe23ba |
unsigned long long minsize;
|
|
|
fe23ba |
int rotateCount;
|
|
|
fe23ba |
int rotateAge;
|
|
|
fe23ba |
--
|
|
|
fe23ba |
2.13.5
|
|
|
fe23ba |
|