Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
Logrotate weekly rotation rotates too late!
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Other Things Gentoo
View previous topic :: View next topic  
Author Message
Boris27
Guru
Guru


Joined: 05 Nov 2003
Posts: 562
Location: Almelo, The Netherlands

PostPosted: Sun Oct 02, 2005 10:32 am    Post subject: Logrotate weekly rotation rotates too late! Reply with quote

I have logrotate setup to run every sunday morning at 00:10 AM. It should rotate my /var/log/messages and my /var/log/squid/*.log then. It also runs every 1st of the month to rotate my apache logs.

The problem is this:

-rw------- 1 root root 2767362 Oct 2 12:19 messages
-rw------- 1 root root 315400 Sep 25 00:10 messages.1.gz
-rw------- 1 root root 248755 Sep 11 00:10 messages.2.gz

It actually rotates every two weeks! Rotation should have occured at Oct 2 00:10, but it didn't.

I found out that is because when a log is rotated at say 1st of January at 00:10, then on the 8th of January 00:10 it will not see the log fit for rotating.
Checking again at 00:11 and it will flag it as needing rotating.

So it's rotating after a week has passed, not every week! And I really would like it to just rotate it every week. Setting it to run once a week with the -f option is not a good solution, as my Apache log would be rotated too.

So what I would want is the monthly behaviour in a weekly fashion.
monthly
Log files are rotated the first time logrotate is run in a month (this is normally on the first day of the month).

weekly
Log files are rotated if the current weekday is less then the weekday of the last rotation or if more then a week has passed since the last rotation. This is normally the same as rotating
logs on the first day of the week, but if logrotate is not being run every night a log rotation will happen at the first valid opportunity.

I checked, but there is no "day" option in logrotate. So I can't specify "rotate on sunday". Or "rotate on wednesday". That would also solve my problem.

Here's my logrotate.status file:

Code:
logrotate state -- version 2
"/var/log/apache2/access_log" 2005-10-1
"/var/log/apache2/deflate.log" 2005-10-1
"/var/log/apache2/error_log" 2005-10-1
"/var/log/apache2/suexec_log" 2005-8-1
"/var/log/squid/access.log" 2005-9-25
"/var/log/squid/cache.log" 2005-9-25
"/var/log/squid/store.log" 2005-9-25
"/var/log/messages" 2005-9-25

_________________
we are microsoft, lower your firewalls and surrender your pc's. we will add your biological and technological distinctiveness to our own. your culture will adapt and service us. resistance is futile.
Back to top
View user's profile Send private message
Boris27
Guru
Guru


Joined: 05 Nov 2003
Posts: 562
Location: Almelo, The Netherlands

PostPosted: Sun Oct 02, 2005 4:04 pm    Post subject: Reply with quote

I looked at the source.

I noticed that in logrotate.c line 431 it said
Code:
            state->doRotate = ((now.tm_wday < state->lastRotated.tm_wday) ||
                ((mktime(&now) - mktime(&state->lastRotated)) >
            (7 * 24 * 3600)));

This means that the log will be rotated if the current weekday is less than the last rotation's weekday. (weekdays are 0 to 6 with 0 being Sunday), or when the log is more than 7 * 24 * 3600 seconds old (thats one week's amount of seconds).

I figured I could solve it by changing either of the 2 options. I could change the week's amount of seconds to something less so the log will be rotated if its more than 6 days old, instead of seven.
Or I could change the first option. I went for the first option, as I figured the second option is a fallback for when the machine has been down for a long while and the log is very old and needs rotating. Also changing 7 days to 6 days and a bit is an ugly hack.

I don't understand what the original programmer tried to do with the 1st option. Why rotate if the weekday is less than the last rotated weekday? I mean, I rotate on sundays, so there is no lesser weekday. The first option will never come in to effect for me. Thats why mine rotated every 2 weeks, as the second option would kick in at the second week. Also, say I rotated on saturday, which is weekday 6. Now the next day would be sunday. If logrotate ran then, it would find that the current weekday is less than the last rotated weekday and rotate my log, after only 1 day!

So the first option had to change. I figured that the log should be rotated on the same weekday. But that would mean that if logrotate ran twice on a day (some people like to rotate their logs after a size has been met and thus run it every hour, I assume), it would rotate again. So I added the second check that ensured that the day of the year is not the same day as the last rotation. This, I think, ensures that the log is rotated the same day every week. This also works when the year wraps (which is also a concern of the original author, when looking at the monthly rotation code).

Here's the new code:
Code:
            state->doRotate = ((now.tm_wday == state->lastRotated.tm_wday &&
            now.tm_yday != state->lastRotated.tm_yday) ||
            ((mktime(&now) - mktime(&state->lastRotated)) >
            (7 * 24 * 3600)));


I made a patch. This is my first patch ever, and I had to look at the kernel documentation to make it. If it's wrong, please say how it should be done instead.

Portage says the homepage of logrotate is www.gentoo.org, and I don't know who the original author is (some names are in the CHANGES file, but nothing definitive), so I figured I'd post here. I'll also post it to bugs.gentoo.org.

Code:
--- logrotate-3.7.1-old/logrotate.c     2004-10-19 23:41:24.000000000 +0200
+++ logrotate-3.7.1-new/logrotate.c     2005-10-02 17:29:22.380767321 +0200
@@ -424,12 +424,15 @@ int findNeedRotating(logInfo * log, int
         switch (log->criterium) {
           case ROT_WEEKLY:
             /* rotate if:
-                  1) the current weekday is before the weekday of the
-                     last rotation
+                  1) the day of the week is the same as the day of the week of
+                     the previous rotation but not the same day of the year
+                     this will rotate it on the same day every week, but not
+                     twice a day.
                   2) more then a week has passed since the last
                      rotation */
-            state->doRotate = ((now.tm_wday < state->lastRotated.tm_wday) ||
-                              ((mktime(&now) - mktime(&state->lastRotated)) >
+            state->doRotate = ((now.tm_wday == state->lastRotated.tm_wday &&
+                               now.tm_yday != state->lastRotated.tm_yday) ||
+                               ((mktime(&now) - mktime(&state->lastRotated)) >
                                (7 * 24 * 3600)));
             break;
           case ROT_MONTHLY:

_________________
we are microsoft, lower your firewalls and surrender your pc's. we will add your biological and technological distinctiveness to our own. your culture will adapt and service us. resistance is futile.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Other Things Gentoo All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum