I got burned by logrotate killing something while rotating logs a few years ago, so now I use rsyslog plus a much simpler setup for log rotation.
Rsyslog can use templates to create dated logfiles, so I restart rsyslog at midnight and hard-link new /var/log/YYYY/MMDD files to the same names under /var/log:
me% ls -liF /var/log /var/log/2026/0419 /var/log: 78649 drwxr-s--- 111 root wheel 111 19-Apr-2026 00:00:00 2026/ 137805 -rw-r----- 2 root wheel 168267 19-Apr-2026 07:04:00 cron 137810 -rw-r----- 2 root wheel 101 19-Apr-2026 00:01:00 daemon 137822 -rw-r----- 2 root wheel 37 19-Apr-2026 00:00:00 debug.log 137814 -rw-r----- 2 root wheel 37 19-Apr-2026 00:00:00 local0log 137815 -rw-r----- 2 root wheel 37 19-Apr-2026 00:00:00 local1log 137816 -rw-r----- 2 root wheel 37 19-Apr-2026 00:00:00 local2log 137817 -rw-r----- 2 root wheel 37 19-Apr-2026 00:00:00 local3log 137818 -rw-r----- 2 root wheel 37 19-Apr-2026 00:00:00 local4log 137819 -rw-r----- 2 root wheel 37 19-Apr-2026 00:00:00 local5log 137820 -rw-r----- 2 root wheel 83366 19-Apr-2026 06:36:20 local6log 137821 -rw-r----- 2 root wheel 194 19-Apr-2026 00:02:00 local7log 137811 -rw-r----- 2 root wheel 3951 19-Apr-2026 03:04:00 maillog 137813 -rw-r----- 2 root wheel 140 19-Apr-2026 06:22:28 ntplog 137809 -rw-r----- 2 root wheel 359 19-Apr-2026 06:49:33 secure 137806 -rw-r----- 2 root wheel 8880 19-Apr-2026 07:00:00 syslog /var/log/2026/0419: 137805 -rw-r----- 2 root wheel 168267 19-Apr-2026 07:04:00 cron 137810 -rw-r----- 2 root wheel 101 19-Apr-2026 00:01:00 daemon 137822 -rw-r----- 2 root wheel 37 19-Apr-2026 00:00:00 debug.log 137814 -rw-r----- 2 root wheel 37 19-Apr-2026 00:00:00 local0log 137815 -rw-r----- 2 root wheel 37 19-Apr-2026 00:00:00 local1log 137816 -rw-r----- 2 root wheel 37 19-Apr-2026 00:00:00 local2log 137817 -rw-r----- 2 root wheel 37 19-Apr-2026 00:00:00 local3log 137818 -rw-r----- 2 root wheel 37 19-Apr-2026 00:00:00 local4log 137819 -rw-r----- 2 root wheel 37 19-Apr-2026 00:00:00 local5log 137820 -rw-r----- 2 root wheel 83366 19-Apr-2026 06:36:20 local6log 137821 -rw-r----- 2 root wheel 194 19-Apr-2026 00:02:00 local7log 137811 -rw-r----- 2 root wheel 3951 19-Apr-2026 03:04:00 maillog 137813 -rw-r----- 2 root wheel 140 19-Apr-2026 06:22:28 ntplog 137809 -rw-r----- 2 root wheel 359 19-Apr-2026 06:49:33 secure 137806 -rw-r----- 2 root wheel 8880 19-Apr-2026 07:00:00 syslog
At midnight today (19 Apr 2026) this happened:
a: Stop rsyslogd
b: Create the /var/log/2026/0419 directory with new logfiles
c: Since the corresponding /var/log files are linked to the previous day, I can delete them and link to the new ones (basic code without error checks):
cd /var/log || exit 1
mkdir -p /var/log/2026/0419 || exit 2
for file in cron daemon local0log local1log local2log local3log \
local4log local5log local6log local7log maillog ntplog \
secure syslog
do
rm $file
touch 2026/0419/$file
ln 2026/0419/$file
done
d: Restart rsyslogd
Trimmed version of my FreeBSD /usr/local/etc/rsyslog.conf:
#### MODULES =====================================================
#
module(load="immark" interval="3600") # Write MARK messages hourly
module(load="imuxsock") # Local system logging (logger, etc)
module(load="imklog") # Kernel logging (previously done by rklogd)
#module(load="imudp") # Provides UDP syslog reception
#$UDPServerRun 514
#module(load="imtcp") # Provides TCP syslog reception
#$InputTCPServerRun 514
#### GLOBAL DIRECTIVES ===========================================
# Enable rsyslogd writing all mark messages
$ActionWriteAllMarkMessages on
:programname, isequal, "rsyslogd"
# Use short timestamp format
## $ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
$ActionFileDefaultTemplate ShortForm
# Use high-precision timestamps and timezone information
## $ActionFileDefaultTemplate RSYSLOG_FileFormat
# File syncing capability is disabled by default. This feature is
# usually not required, not useful and an extreme performance hit
## $ActionFileEnableSync on
#### TEMPLATES ===================================================
$template DYNauth,"/var/log/%$YEAR%/%$MONTH%%$DAY%/secure"
$template DYNcron,"/var/log/%$YEAR%/%$MONTH%%$DAY%/cron"
$template DYNdaemon,"/var/log/%$YEAR%/%$MONTH%%$DAY%/daemon"
...
# This is identical to traditional format, without the hostname.
$template ShortForm,"%timegenerated% %syslogtag%%msg%\n"
#### RULES =======================================================
# ----------------------------------------------------------------
# Daemon messages.
if ($syslogfacility-text == 'daemon') then {
?DYNdaemon
stop
}
# ----------------------------------------------------------------
# The auth and security files have restricted access.
## authpriv.* /var/log/secure
## auth.* /var/log/secure
## security.* /var/log/secure
if ($syslogseverity <= '6') then {
if ($syslogfacility-text == 'auth' or
$syslogfacility-text == 'authpriv' or
$syslogfacility-text == 'security')
then {
?DYNauth
stop
}
}
# ----------------------------------------------------------------
# Log cron stuff
## cron.* /var/log/cron
if ($syslogseverity <= '6' and
$syslogfacility-text == 'cron') then {
?DYNcron
stop
}
The complete rsyslog.conf file is located here.
The "DYNcron" template stores 19 Apr 2026 cron entries in /var/log/2026/0419/cron. You don't actually have to create the directories (rsyslog does it), but it won't put anything in the new logfiles until there's an explicit call to "logger" or the equivalent -- since I'm restarting logging anyways, it's simpler to just do it myself.
Hope this is useful.
Feel free to send comments.
Generated from article.t2t by
txt2tags
$Revision: 1.2 $
$UUID: cff22cb1-2dcb-3eb9-9b69-e9f023df87b6 $