I am trying to configure logrotate in RHEL for tomcat6 logs. Currently, logrotate works fine for catalina.out log, it is rotated and compressed properly.
The problem is with the files with date in them like:
catalina.2012-01-20.log
catalina.2012-01-21.log
catalina.2012-01-22.log
These files are not being rotated. I understand that I have to configure these in /etc/logrotate.d/tomcat6 file where rotation for catalina.out is configured. But I am not able to configure it.
All I want is these older files to be compressed daily, except the current date log file.
Can anybody help me out on this, please!!
Thanks Noman A.
The sharedscripts means that the postrotate script will only be run once (after the old logs have been compressed), not once for each log which is rotated. Note that the double quotes around the first filename at the beginning of this section allows logrotate to rotate logs with spaces in the name.
To verify if a particular log is indeed rotating or not and to check the last date and time of its rotation, check the /var/lib/logrotate/status file. This is a neatly formatted file that contains the log file name and the date on which it was last rotated. You'll find this file as /var/lib/logrotate.
Postrotate. Logrotate runs the postrotate script each time it rotates a log specified in a configuration block. You usually want to use this script to restart an application after the log rotation so that the app can switch to a new log.
logrotate maxsize <MAX-SIZE> no logrotate maxsize. Description. Specifies the maximum allowed log file size. The no form of this command resets the size of the log file to the default (100 MB).
(First post ever so if it looks like a drunk spider has formatted it then sorry)
After using our friend Google, here and I can't remember where else I managed to achieve something using logrotate (rather than cron or some other equivalent).
I have a the following in /var/log/rsync/:
-rw-r--r-- 1 root root 1.1M Apr 9 08:13 2014-04-09 07:48:18.log
-rw-r--r-- 1 root root 1.4M Apr 11 15:20 2014-04-11 15:02:52.log
-rw-r--r-- 1 root root 1.6M Apr 11 15:42 2014-04-11 15:22:04.log
-rw-r--r-- 1 root root 1.8M Apr 12 08:01 2014-04-12 07:45:31.log
-rw-r--r-- 1 root root 2.0M Apr 13 08:10 2014-04-13 07:53:38.log
-rw-r--r-- 1 root root 2.2M Apr 14 08:19 2014-04-14 07:51:09.log
-rw-r--r-- 1 root root 2.5M Apr 15 08:05 2014-04-15 07:37:38.log
-rw-r--r-- 1 root root 2.7M Apr 16 08:11 2014-04-16 07:43:14.log
and the following logrotate file:
/var/log/rsync/*.log {
daily
rotate 7
compress
delaycompress
notifempty
missingok
}
which I thought was perfectly reasonable. But after it refused to work and on finding out that it would never work (courtesy of this post) I wondered if it could be fudged to make it work.
After much testing and tweaking I managed to fudge it the following way:
/var/log/rsync/dummy {
daily
rotate 0
create
ifempty
lastaction
/usr/bin/find /var/log/rsync/ -mtime +7 -delete
/usr/bin/find /var/log/rsync/ -mtime +1 -exec gzip -q {} \;
endscript
}
into a logrotate config file called /etc/logrotate.d/local-rsync. Then create the dummy log file:
touch /var/log/rsync/dummy
then force a logrotate with:
logrotate -fv /etc/logrotate.d/local-rsync
which gives:
-rw-r--r-- 1 root root 71K Apr 9 08:13 2014-04-09 07:48:18.log.gz
-rw-r--r-- 1 root root 88K Apr 11 15:20 2014-04-11 15:02:52.log.gz
-rw-r--r-- 1 root root 82K Apr 11 15:42 2014-04-11 15:22:04.log.gz
-rw-r--r-- 1 root root 84K Apr 12 08:01 2014-04-12 07:45:31.log.gz
-rw-r--r-- 1 root root 87K Apr 13 08:10 2014-04-13 07:53:38.log.gz
-rw-r--r-- 1 root root 92K Apr 14 08:19 2014-04-14 07:51:09.log.gz
-rw-r--r-- 1 root root 2.5M Apr 15 08:05 2014-04-15 07:37:38.log
-rw-r--r-- 1 root root 2.7M Apr 16 08:11 2014-04-16 07:43:14.log
-rw-r--r-- 1 root root 0 Apr 16 12:11 dummy
Now just wait for tomorrow morning...
I realise that cron would be tidier however I have another element in the logrotate config file and wanted to keep the two together.
Bonus with the dummy file is that it doesn't take up any space!
You may find that it does not appear to have rotated anything one day. It took me while to work out why but then it twigged. find -mtime +1 is whole days (i.e. 24*60 minutes) and if the daily logrotate kicked in less than 24 hours since the last time/time the logs were created then it sometimes appears not to have worked. If it bothers you then using 23 hours with find -mmin +1380 might be more appropriate.
I spent a quite a while reading a lot of documentation. Logrotate does not seem to be able to group the different files with dates included in the name of the file. Logrotate can not do what we need it to do.
You have two options change the logging facility provided by java / tomcat to not include the date in the file name. http://tomcat.apache.org/tomcat-6.0-doc/logging.html
The second and quicker way is to use your own little script to do the work for you, using find
. https://serverfault.com/questions/256218/logrotation-when-filenames-includes-date, https://serverfault.com/a/256231/71120
find /pathtologs/* -mtime +5 -exec rm {} \;
I went with the second option, because our developers have coded for dates in the files names. So it needs to stay that way.
The -mtime +5
sets find to only look for files who are older then 5 days.
From find
's documentation.
File's data was last modified n*24 hours ago. See the comments for -atime to understand how rounding affects the interpretation of file modification times.
Updated as per comment
find /pathtologs/* -mtime +5 -delete
If you specifically want to delete, this is a quick way to do it.
If you need to some other command you can always replace the exec rm {} \;
with something else.
Something like this in /etc/cron.d/rotate_tomcat_logs:
# delete every log file over 100 days old, and compress every log file over 1 day old.
00 1 * * * root ( find /opt/tomcat/logs -name \*log\* -name \*.gz -mtime +100 -exec rm -f {} \; >/dev/null 2>&1 )
05 1 * * * root ( find /opt/tomcat/logs -name \*log\* ! -name \*.gz -mtime +1 -exec gzip {} \; >/dev/null 2>&1 )
/path/to/logs/*.log { missingok compress rotate 7 }
this type of thing doesn't work normally because as others point out tomcat has its own log rotation. You can either use a simple cron to delete old files or turn off rotation on the access log valve. By turning off log rotation (and possible changing the filename patter), the above logrotate and other similar configs will work fine.
The bottom line is you should use logrotate or the built in log rotation in tomcat but not both at the same time.
To include a date in the rotated file, you can probably use 'dateext' option.
$ cat logrotate.conf
/var/nginx/logs/access.log {
size 10k
copytruncate
dateext
rotate 10
compress
}
The rotated file should get created similar to below
root@nitpc:~# ls -lrt /var/nginx/logs/access.*
-rw-r--r-- 1 nginx root 5422 May 31 08:26 access.log
-rw-r--r-- 1 nginx root 466 May 31 08:26 access.log-20180531.gz
The only downside is you won't be able to run it more than once per day as the file would have a definite name for that date.
The above example is from my Nginx docker container running in k8s on GC. The logrotate version is 3.11.0.
Hope that helps!
Update: From man pages https://linux.die.net/man/8/logrotate
dateformat format string
Specify the extension for dateext using the notation similar to strftime(3) function. Only %Y %m %d and %s specifiers are allowed. The default value is -%Y%m%d. Note that also the character separating log name from the extension is part of the dateformat string. The system clock must be set past Sep 9th 2001 for %s to work correctly. Note that the datestamps generated by this format must be lexically sortable (i.e., first the year, then the month then the day. e.g., 2001/12/01 is ok, but 01/12/2001 is not, since 01/11/2002 would sort lower while it is later). This is because when using the rotate option, logrotate sorts all rotated filenames to find out which logfiles are older and should be removed.
Also, you can add crons instead hardcode logrotate.
1 0 * * * /usr/bin/find /var/log/tomcat/ -mtime +30 -delete
2 0 * * * /usr/bin/find /var/log/tomcat/ -mtime +1 -exec gzip -q {} \;
In this way, you will delete the logs older than 30 days, and zip the logs older than 1.
Probably you can remove the date from the log file names as described in How to remove the date pattern from tomcat logs to be able to use logrotate rules.
This worked for me at least for localhost access log.
Well, I was not fully satisfied with any of the answers, even though the ones stating that the logrotate
doesn't support this (i. e. just to remove files rotated by some other application) scenario are surely correct (raise a feature request on that tool, maybe?).
So, I would like to share an alternative approach I've come to. Unlike the "find /path/to/logs -mtime +7 -delete
" solution, this one won't remove all the old logs after a specified period of time. So here it comes, an example one-liner bash command which leaves just N last logs on the disk (whenever it is run):
for f in `ls -1r | grep -E "^catalina\.[0-9]{4}-[0-9]{2}-[0-9]{2}\.log$" | tail -n +$((N+1))`; do rm $f; done
Finally, to cover the topic completely, the last alternative solution is not to rotate the log files (e. g. use rotatable=false
in case of Tomcat - see its docs) and use the logrotate
as usually, but don't forget to use it with the 'copytruncate' option.
Suggestions are welcome...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With