/etc/logrotate.d
--------------------------------------------------------------------------------
Setting up and verifying system logging: syslog and klog; /etc/syslog.conf;
remote logging; monitoring logs using swatch; managing logs using log rotate.
It is possible to force log rotation to test new configuration.
{
dbw comment: invalid entries in logrotate.conf - such as logs for customer
web directories since deleted, can cause logrotate to fail completely! You
_can_ force a log rotation checking your logrotate.conf file for validity.
syntax: logrotate -f /etc/logrotate.conf
}
man logrotate
--------------------------------------------------------------------------------
#note: endscript should appear only in the last entry if in logrotate.d
# and should not appear at all if in logrotate.conf
--------------------------------------------------------------------------------
How logrotate is invoked from cron.
On one of my RedHat 5.2 systems, `crond' is started from the script
/etc/rc.d/init.d/crond. The manual `man cron' says that cron
searches for /etc/crontab and the files in the /etc/cron.d/ directory.
My /etc/crontab file contains the following.
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# run-parts
01 * * * * root run-parts /etc/cron.hourly
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
0 0 1 * * root run-parts /etc/cron.monthly
And the /etc/cron.d directory contains nothing.
So clearly, any logrotate commands are being run out of one or more of the
/etc/cron.* files. The manual `man 5 crontab' indicates that the above
commands mean that the program `run-parts' will be run as user `root' for
each of the scripts.
The command `run-parts' turns out to be the script /usr/bin/run-parts, which
is very short, as follows.
#!/bin/bash
# run-parts - concept taken from Debian
# keep going when something fails
set +e
if [ $# -lt 1 ]; then
echo "Usage: run-parts <dir>"
exit 1
fi
if [ ! -d $1 ]; then
echo "Not a directory: $1"
exit 1
fi
for i in $1/* ; do
[ -d $i ] && continue
if [ -x $i ]; then
$i
fi
done
exit 0
In essence, this just runs all of the scripts in the specified directory.
E.g. each hour, the executable plain files in /etc/cron.hourly are run.
It turns out that the `logrotate' program is invoked from /etc/cron.daily.
This is the contents of the file /etc/cron.daily/logrotate.
#!/bin/sh
/usr/sbin/logrotate /etc/logrotate.conf
This means that the only file that `logrotate' gets its instructions from
directly is /etc/logrotate.conf, which contains the following lines.
# see "man logrotate" for details
# rotate log files weekly
weekly
# keep 8 weeks worth of backlogs
rotate 8
# send errors to root
errors root
# create new (empty) log files after rotating old ones
create
# uncomment this if you want your log files compressed
#compress
# RPM packages drop log rotation information into this directory
include /etc/logrotate.d
# no packages own lastlog or wtmp -- we'll rotate them here
/var/log/wtmp {
monthly
rotate 1
}
# system-specific logs may be configured here
This is all explained in the manual `man logrotate'.
Operation of logrotate.
The directory /etc/logrotate.d contains the following files.
-rw-r--r-- 1 root root 354 Oct 13 1998 apache
-rw-r--r-- 1 root root 108 Aug 28 1999 cron
-rw-r--r-- 1 root root 188 Oct 14 1998 linuxconf
-rw-r--r-- 1 root root 156 Oct 13 1998 mgetty
-rw-r--r-- 1 root root 327 Aug 12 1998 syslog
-rw-r--r-- 1 root root 457 Sep 10 1998 uucp
The file /etc/logrotate.d/apache is the one I'm interested in for this
exercise. This file contains the following.
/var/log/httpd/access_log {
postrotate
/usr/bin/killall -HUP httpd
endscript
}
/var/log/httpd/agent_log {
postrotate
/usr/bin/killall -HUP httpd
endscript
}
/var/log/httpd/error_log {
postrotate
/usr/bin/killall -HUP httpd
endscript
}
/var/log/httpd/referer_log {
postrotate
/usr/bin/killall -HUP httpd
endscript
}
When I installed the latest version of Apache to get the PHP3 and
PostgreSQL to work (around 20 March 2000) on my web server machine,
I installed Apache so that the log files were in /home2/apache/logs
instead of /var/log/httpd.
Therefore what I need to do now is to modify the
/etc/logrotate.d/apache file so that the files referred to are all
in the directory /home2/apache/logs instead. My new
/etc/logrotate.d/apache script is as follows, and I saved the old
one in directory /etc/logrotate.d/old1.
# The new improved logrotate script for apache on fox.
/home2/apache/logs/*-access_log {
rotate 9
monthly
errors akenning@fox.topology.org
create
ifempty
olddir /home2/apache/logs/oldlogs
postrotate
/usr/bin/killall -HUP httpd
endscript
}
/home2/apache/logs/*-combref_log {
rotate 9
monthly
errors akenning@fox.topology.org
create
ifempty
olddir /home2/apache/logs/oldlogs
postrotate
/usr/bin/killall -HUP httpd
endscript
}
/home2/apache/logs/*-error_log {
rotate 9
monthly
errors akenning@fox.topology.org
create
ifempty
olddir /home2/apache/logs/oldlogs
postrotate
/usr/bin/killall -HUP httpd
endscript
}
--------------------------------------------------------------------------------
Now on Sunday 30 September 2001, it's time to get `logrotate' going on my new
SuSE 7.1 web server `dog'. The problem is that SuSE 7.1 does not come with
logrotate software on it. So I had to go and look for it. The link at redhat
was
wrong, but by looking around a bit, I finally found it at
ftp://ftp.redhat.com/pub/redhat/linux/code/logrotate/
I downloaded this file: logrotate-3.3.tar.gz. This can be compiled very simply
with `make' and `make install'. There's a manual logrotate.8 with it too. The
binary is installed as /usr/sbin/logrotate. So now all I have to do is write a
configuration file for the logrotate program and then write a cron script for
it.
(Note that since my main initial consideration is to rotate the httpd logs for
the beginning of October 2001, I could just use the Apache tool for this
purpose,
which is /usr/local/apache/bin/rotatelogs on my system. However, I can't
understand the documentation for this. So I'm playing safe and using the more
flexible redhat `logrotate' tool instead.)
On my SuSE 7.1 machine `dog', the manual says that after reading the per-user
crontab files in /var/spool/cron/tabs on start-up, the cron process reads the
file /etc/crontab. On my machine as configured, I find the following.
root@dog# more /etc/crontab
SHELL=/bin/sh
PATH=/usr/bin:/usr/sbin:/sbin:/bin:/usr/lib/news/bin
MAILTO=root
#-* * * * * root test -x /usr/sbin/atrun && /usr/sbin/atrun
0 21 * * * root test -x /usr/sbin/faxqclean && /usr/sbin/faxqclean
5 22 * * * root test -x /usr/sbin/texpire && /usr/sbin/texpire
25 23 * * * root test -e /usr/sbin/faxcron && sh /usr/sbin/faxcron | mail
FaxMaster
#
# check scripts in cron.hourly, cron.daily, cron.weekly, and cron.monthly
#
-*/15 * * * * root test -x /usr/lib/cron/run-crons &&
/usr/lib/cron/run-crons
59 * * * * root rm -f /var/spool/cron/lastrun/cron.hourly
14 0 * * * root rm -f /var/spool/cron/lastrun/cron.daily
29 0 * * 6 root rm -f /var/spool/cron/lastrun/cron.weekly
44 0 1 * * root rm -f /var/spool/cron/lastrun/cron.monthly
There's nothing here to help me with initiating my daily script. (By the way,
the fax commands are a bit worrying. I'll get rid of those when I understand
exactly what they do. They obviously produce many meaningless message which
root receives every day!)
So my next step is to look at the files in /etc/cron.d, because the cron
manual
says that all scripts in this directory are read next. On my machine the only
file in /etc/cron.d is a script `seccheck', which produces copious useless
messages to root every day and week. (I'll see if I can get rid of that some
day too!)
The directory /etc/cron.daily contains a script `aaa_base_rotate_logs' which
contains a complex set of rotation rules, but how are the scripts in this
directory invoked? Hmmm... Maybe they're invoked from that
`/usr/lib/cron/run-crons' script. Yes!! That's where it's invoked from. Yet
another big, incomprehensible script. The core of that script is the following
Bourne-shell loop.
SPOOL=/var/spool/cron/lastrun
for CRONDIR in /etc/cron.{hourly,daily,weekly,monthly} ; do
test -d $CRONDIR || continue
BASE=${CRONDIR##*/}
test -e $SPOOL/$BASE && {
case $BASE in
cron.hourly) TIME="-cmin +60 -or -cmin 60" ;;
cron.daily) TIME="-ctime +1 -or -ctime 1" ;;
cron.weekly) TIME="-ctime +7 -or -ctime 7" ;;
cron.monthly) TIME="-ctime +`date -u +%d`" ;;
esac
eval find $SPOOL/$BASE $TIME | xargs -r rm -f
}
if test ! -e $SPOOL/$BASE ; then
touch $SPOOL/$BASE
# keep going when something fails
set +e
for SCRIPT in $CRONDIR/*[^~,] ; do
test -d $SCRIPT && continue
test -x $SCRIPT || continue
case "$SCRIPT" in
*.rpm*) continue ;;
*.swap) continue ;;
*.bak) continue ;;
*.orig) continue ;;
\#*) continue ;;
esac
/sbin/checkproc $SCRIPT && continue
nice -15 $SCRIPT
done
fi
done
Now what does this mean?
The command `BASE=${CRONDIR##*/}' means that BASE is set to the `longest
substring of $CRONDIR which matches pattern "*/"', according to my Bash
reference card. This just means that the leading path components are removed.
(This is done more simply in C-shell!) In the case of the daily cron job, if
there is a file /var/spool/cron/lastrun/cron.daily (which is true), then the
following command is run.
eval find /var/spool/cron/lastrun/cron.daily -ctime +1 -or -ctime 1 | xargs -r
rm -f
The `xargs' command (which I have never seen before) builds and executes a
command line from standard input. Wierd! The `xargs' manual says this.
If the standard input does not contain any non-blanks,
do not run the command. Normally, the command is run once
even if there is no input.
So in this case, the command `rm -f' is executed for each of the files with
modification times within 24 hours of the current time. I don't really
understand this.
It looks like the file removal commands in the file /etc/crontab are designed
to synchronise the operation of the quarter-hour operations. The commands are
only executed if the files in /var/spool/cron/lastrun have been removed. What
a convoluted way of achieving a simple objective!!
Next any file in the directory /etc/cron.daily which do not end in the
characters `~' or `,' (presumed to be edited files) are executed if they are
executable and do not have the endings .rpm, .swap, .bak or .orig as follows.
/sbin/checkproc $SCRIPT && continue
nice -15 $SCRIPT
The loop continues is the process is already running. Otherwise it is run with
nice level 15.
What this all means finally is that any script in the directory
/etc/cron.daily
will be run at 00:00 on each day. More to the point, the /etc/cron.monthly
scripts are run at 00:00 at the beginning of each month. It all looks a bit
dodgy because the `date' test is `date -u', which gives the current UTC day.
But this should work, although the motivation for the `-u' is not quite clear.
All I have to do now is write a script and put it in /etc/cron.monthly. No
problem!
--------------------------------------------------------------------------------
sample methods:
# system-specific logs may be configured here
## rotate apache logs weekly, keeping 8 rotations
/www/apache/var/logs/*log {
rotate 8
postrotate
kill -HUP `cat /www/apache/var/logs/httpd.pid`
endscript
}
## rotate rembo logs weekly, keeping 4 rotations
/opt/rembo/logs/*.log {
rotate 4
postrotate
/etc/rc.d/init.d/rembo stop
/etc/rc.d/init.d/rembo start
endscript
}
--------------------------------------------------------------------------------
the roach method (for virtual hosting):
I have many virtual hosts. I feared that apache would be start/stop
frequently,
once per virtual host, during the rotation process. Therefore, I decided to
use
the 'copytruncate' option. With this option the apache web server does not
require a restart. -roach
/usr/apache/log/*log {
weekly
rotate 52
notifempty
missingok
copytruncate
}
/usr/apache/log/dynahost.dbw.org/*log {
weekly
rotate 52
notifempty
missingok
copytruncate
}
--------------------------------------------------------------------------------
Configure the new /etc/logrotate.d/apache file
Now Apache logs files residing in the /chroot/var/log/httpd directory instead
of
/var/log/httpd and for this reason we need to modify the
/etc/logrotate.d/httpd
file to point to the new chrooted directory. Also, we've compiled Apache with
mod_ssl, so we'll add one more line to permit the logrotate program to rotate
the ssl_request_log and ssl_engine_log files. Configure your
/etc/logrotate.d/apache file to rotate your log files each week automatically.
Create the apache file, touch /etc/logrotate.d/apache and add:
/chroot/httpd/var/log/httpd/access_log {
missingok
postrotate
/usr/bin/killall -HUP /chroot/httpd/usr/sbin/httpd
endscript
}
/chroot/httpd/var/log/httpd/error_log {
missingok
postrotate
/usr/bin/killall -HUP /chroot/httpd/usr/sbin/httpd
endscript
}
/chroot/httpd/var/log/httpd/ssl_request_log {
missingok
postrotate
/usr/bin/killall -HUP /chroot/httpd/usr/sbin/httpd
endscript
}
/chroot/httpd/var/log/httpd/ssl_engine_log {
missingok
postrotate
/usr/bin/killall -HUP /chroot/httpd/usr/sbin/httpd
endscript
}
--------------------------------------------------------------------------------
Credits and Quasi-bibliography:
The majority of this text is from:
http://www.topology.org/linux/logrotate.html
Reference: Alan Kennington's
Some information was gathered from:
http://misc.epfl.ch/rembo/logrotate_conf.html
Reference: Unknown
Securing and Optimizing Linux: RedHat Edition -A Hands on Guide
http://www.tldp.org/LDP/solrhe/Securing-Optimizing-Linux-RH-Edition-v1.3/chap29sec258.html
Anything else was created by:
roach
date: Sun May 12 18:03:33 CDT 2002
--------------------------------------------------------------------------------
Logrotate: error reading top line of /var/lib/logrotate.status
If you get an error saying
/etc/cron.daily/logrotate:
error: error reading top line of /var/lib/logrotate.status
delete /var/lib/logrotate.status, and then run logrotate once with -f flag,
like
#> logrotate -f /etc/logrorate.d/syslog
This should initialize the status file and the error should not be repeating.
Last modified on 25 June 2007, at 19:18