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.