I don’t know about you, but I like to have my system logs split day by day, particularly on busy machines. I also like to have a full timestamp (including year and timezone thank you) in system log files.
The venerable syslog package can not do these things – but syslog-ng can.
On Debian/Ubuntu, the default syslog-ng config file is set up to mimic the old way of logging – dump everything in various files under /var/log/, and let logrotate rotate the logs. That’s understandable from an upgrade path perspective but it does not exploit syslog-ng’s strengths at all.
Here’s how I configure syslog-ng for a machine that logs locally as well as to a remote syslog-ng server:
options {
check_hostname(yes);
keep_hostname(yes);
chain_hostnames(no);
};
source inputs {
internal();
unix-stream("/dev/log");
udp();
};
destination logpile {
file("/var/log/$FACILITY.$YEAR$MONTH$DAY"
template("$ISODATE $MSG\n") template_escape(no)
owner(root) group(root) perm(0600)
create_dirs(yes) dir_perm(0700));
};
destination remote { tcp("the.ip.of.your.very.secure.syslog.server"); };
log { source(inputs); destination(remote); };
log { source(inputs); destination(logpile); };
This config puts logfiles in /var/log but splits them up per day with a filename like syslog.YYYYMMDD. It also makes sure that the first element on each line is a fully qualified timestamp.
I also have a small script that runs from cron
#!/bin/sh
# This script moves log files older than 3 days from /var/log/ to
# /var/log/archive/, in bzip2 format. It assumes you've set up syslog-ng to
# split logs per day and put them in /var/log. The script also maintains a
# symlink to the most recent logfile in /var/log/.
#
# Run this script from cron, ideally as close to midnight as possible so that the
# symlink points to the current logfile, always.
#
# Ward Vandewege, 2008-02-12
THREEDAYSAGO=`date --date='3 days ago' +%Y%m%d`
YEARTHREEDAYSAGO=`date --date='3 days ago' +%Y`
MONTHTHREEDAYSAGO=`date --date='3 days ago' +%m`
TODAY=`date +%Y%m%d`
if [ ! -d /var/log/archive ]; then
mkdir /var/log/archive
fi
if [ ! -d /var/log/archive/$YEARTHREEDAYSAGO/$MONTHTHREEDAYSAGO ]; then
mkdir -p /var/log/archive/$YEARTHREEDAYSAGO/$MONTHTHREEDAYSAGO
fi
for LOG in syslog mail cron daemon auth authpriv; do
if [ -f /var/log/$LOG.$THREEDAYSAGO ]; then
bzip2 /var/log/$LOG.$THREEDAYSAGO
mv /var/log/$LOG.$THREEDAYSAGO.bz2 /var/log/archive/$YEARTHREEDAYSAGO/$MONTHTHREEDAYSAGO
fi
if [ -h /var/log/$LOG ]; then
rm -f /var/log/$LOG
fi
ln -s /var/log/$LOG.$TODAY /var/log/$LOG
done
This script keeps 3 days worth of logs in /var/log. Older logs are compressed and archived under /var/log/archive/YYYY/MM/. The script also maintains a symlink in /var/log for each log file syslog-ng generates, pointing to the current log file. I run this script from cron a few minutes after midnight.
You’ll also want to remove /etc/logrotate.d/syslog-ng, since that file serves no purpose anymore.
The combination of syslog-ng and this maintenance script keeps /var/log in order with log files split up per day. It also keeps the most recent log files available right in /var/log, and the rest only a few keystrokes away.
![[Play OGG]](/blog/wp-content/photos/play_ogg_small.png)