Quote:
Originally Posted by hattori.hanzo
How can I do log rotation but not drop any syslog events?
|
You already let Rsyslogd handle log rotation by using a per-day, per-host log file name template.
Ergo Rsyslogd will close the old file and open a new one on day start.
So the Rsyslogd part is not what you're having problems with.
Quote:
Originally Posted by hattori.hanzo
I looked at rsyslog's disk queuing but that only applies if the destination is unavaliable but that will never be when it writes to disk.
|
About $MainMsgQueue.*: "In this mode, receiver and output modules are de-coupled via an in-memory queue. This queue buffers messages
when the output modules are not capable to process them as fast as they are received". So it's not availability of the output module but speed that dictates it.
Depending on how many hosts you need to handle, how long log files need to be stored and where they should be stored after processing I would rewrite the template as it IMHO makes no sense duplicating %HOSTNAME and having that much tree depth. With your current directory structure I would rewrite the cronjob this way:
Code:
#!/bin/sh --
# /var/log/rsyslog/%HOSTNAME%/%$YEAR%/%$MONTH%/%$DAY%/%HOSTNAME%.log"
DATE_STRING=$(/bin/date +"%Y/%m/%d" --date="yesterday")
find /var/log/syslog/ -type d -iname \*${DATE_STRING}\* | while read LOG_LOG_DIRNAME; do
# Loop over yesterdays logs:
find "${LOG_LOG_DIRNAME}" -type f | while read OLD_LOG_FILENAME; do
# Superfluous now but loop only over closed files anyway:
/sbin/fuser "${OLD_LOG_FILENAME}" >/dev/null 2>&1
# Check if you want reporting else uncomment and add " || bzip2 "${OLD_LOG_FILENAME}"" to the line above
case $? in
0) /usr/bin/logger -t logrotate.custom "In use: "${OLD_LOG_FILENAME}".";;
1) bzip2 "${OLD_LOG_FILENAME}";;
*) /usr/bin/logger -t logrotate.custom "Unknown problem: "${OLD_LOG_FILENAME}". Investigate.";;
esac
done
done
exit 0
Yes it's convoluted but looping only over yesterdays logs and checking if they're not in use IMHO is the safest way to rotate these logs.