maintain system log files to manageable sizes

anacron even newer version anticapates system not being on when logs are supposed to be rotated.

sudo newsyslog [-CFNnrsv] [-R tagname] [-a directory] [-d directory] [-f config_file] [logfile]

Run periodically by cron ( or launchd in Mac OSX) to archive log files as desired.
Creates generations so that logfile is initalized, logfile.0̸ has the previous's contents, logfile.1
The archived logs can be compressed.

    A log can be archived because:
  1. It is large    OR   (if time is specified, size is not checked. Consider including 2 entries in config)
  2. it's a good time
  3. manually, -F or -R caused it.

-v verbose.
-n Do not cutover logs. Display what it would happen(example). For testing config file.
-r run even if not root. Don't send HUP to syslogd. Used in testing. ( does not violate file premissions!)
-f config_file default /etc/newsyslog.conf
-d directory log files are to be relative to directory.
Allows archiving of logs outside the root preventing / volume for filling up.
-a directory for archive. May be relative to the path of log file
If any component of the path directory does not exist, it will be created -a directories are unaffected.
-C create files which do not exist with C in their config file entry.
syslog may not write to logfiles if they don't exist.
-CC create log files which do not exist.
If files are given on the command-line, -C or -CC only apply to those files.

Intended for programs to trigger a cutover.
Rules such as permissins, number of archive generations, compression … are kept.
When a daemon executes newsyslog -R tag , files must be are closed first and re-opened after newsyslog returns.
Usually the calling process will also want to specify -s , so newsyslog will not send a signal to the process which called it to force the rotate. Skipping the signal step will also mean that newsyslog will return faster by avoiding normally introduced wait.

-N no cutovers. useful with the -C or -CC
-F Force trim. For diagnosing problems by providing fresh logs that contain only most recent entries.
-R tagname rotate a list of files.
tagname used in the messages written to the log files which are cutover.
One or more logs must be specified
-s supress sending signals to daemons. May inhibit compression.
Useful with -R

If logsfiles are specified on then command line, only they will be processed.

The granularity is dependent on how often it is to run, i.e. if not often enough a log may exceed size


Initial configuration refers to syslog files located in /var/log but can be used with any files.

N.B. symbolic links (like from /var/log ) will end up in their "logfilename" location and become unlinked on the first rotation. i.e. don't use sym links for /var/log files, however it's OK for subdirectories of /var/log like DiagnosticMessages, asl, Accounts, apache2!


Each line has five required fields and optional fields, separated with whitespace.
A # causes the rest of the line to be ignored, unless escaped with \ .

The default entry is used when a log is given as a command line argument and that log is not matched by any other line.
owner:group Names from /etc/passwd : /etc/group or numeric ID. Default: root:admin.
ugo file mode (permissions) in octal. Example 640(see chmod).
n number of archive generations in addition to the current log
KB maximun size before cutover occurs.
Rather than using a large size, consider retaining more generations.

If KB is an asterisk (*) the log file will not be cutover based on size.

when interval, time, or both.
An optional interval in hours, followed by an @ (at-sign) and a time.

$ day of once a day, once a week, or once a month.

If a time is specified, the log file will only be cutover if newsyslog is run within one hour of the specified time.
If an interval is specified, the log file will be cutover if that many hours have passed since the last rotation.
When both a time and an interval are specified then both conditions must be satisfied for the rotation to take place.

For time, the lead-in character is an @ at-sign.

Optional date fields default to the appropriate component of the current date; Optional time fields default to midnight; (not the best as many other things will trigger then as well)
For example if today is January 22, 1999, these are equivalent:

Day, week, and month time format:
The lead-in character $.
$[Dhh], [Ww[Dhh]], and [Mdd[Dhh]] .
Optional time fields default to midnight.
  • hh hours, 0..23
  • w day of week, 0..6, 0 = Sunday
  • dd day of month, 1..31, or L or l the last day of the month.


                   $D0     daily at midnight (same as @T00)
                   $D23    daily at 23:00 (same as @T23)
                   $W0D23  weekly on Sunday at 23:00
                   $W5D16  weekly on Friday at 16:00
                   $M1D0   first day of every month at midnight (i.e., the start of the day; same as @01T00)
                   $M5D6   every 5th day of month at 6:00 (same as @05T06)

If when contains an asterisk (*), log rotation will not depend on a time.

B the log is a binary or has special format.
Usually newsyslog inserts an ASCII message into a log to indicate when, and sometimes why the log file was rotated.
With B that informational message will not be inserted.
C create log if -C was specified on the command line.
D set the UF_NODUMP flag when creating log file which affects how dump treats the log file when making a file system backup.
G the file_name is a shell pattern, and that all filenames matching that pattern. See glob(3) for details on syntax and matching rules.
J compress the rotated log file using bzip2
Z compress the rotated log file using gzip
N there is no process which needs to be signaled when this log file is rotated.
U the file specified by path_to_pid_file will contain the ID for a process group instead of a process.
Requires that the first line in that file be a negative value to distinguish it from a process ID.
/path_to_pid_file optional file containing a daemon's process ID or to find a group process ID if U was specified.
If this field is present, a signal_number is sent the process ID contained in this file.
If this field is not present, then SIGHUP will be sent to syslogd, unless N has been specified.
This field must start with /
signal_number sent to the daemon process (or to all processes in a process group, if U was specified). default SIGHUP
- a minus sign a placeholder

See also

bzip2, gzip, syslog, newsyslog.conf, chown, syslogd

Example of config file

#Contents of maillog, messages, and lpd-errs may be confidential.   (not logrotate no longer comes with MacOSX)

#   sudo newsyslog -vn|egrep -v "skip|will"    # show only actions expected to be taken

#                                                       @ interval, $ day...
#                                                                         J:Compress; B:dont add "new" message
# logfilename                       [owner:group] mode count size when  flags [/pid_file] [sig_num]
/var/log/01_alert.log                 root:staff  640  3     100    *      J
/var/log/02_crit.log                  root:staff  640  3     100    *      J
/var/log/03_err.log                   root:staff  640  3     100    *      J
/var/log/04_warn.log                  root:staff  640  3     100    *      J
/var/log/appfirewall.log              root:staff  640  3     100    *      J
/var/log/install.log                  root:staff  640  3     100    *      J
/var/log/mail.log                     root:staff  640  1     100    *      J
/var/log/secure.log                   root:staff  640  5     100    *      J
# seems that if both  size and time are specified, size is ignored! so here's 2 entries
# which confuses newsyslog which rotates logs assigning odd numbers and only compressing sometimes
/var/log/system.log                   root:staff  640  7     200    *      J
/var/log/system.log                   root:staff  640  7     200    @T0007 J
# added 7/31/13 after 165KB
/var/log/kernel.log                   root:staff  640  5     200    *      J
# wtmp doesn;t exist ??!!
/var/log/wtmp                         root:staff  644  3     *      @01T05 B

# added 7/31/13 ; previously listed as secret recently growing FAST trim Previously expected 00:00 8/31/13
/var/log/wifi.log                     root:staff  640  3     100    *      J

#added 6/23/13:
/var/log/opendirectoryd.log           root:staff  644  3     100    *      J

/Volumes/DATA/log/05_notice.log       root:staff  644  3     200    *      J
/Volumes/DATA/log/06_info.log         root:staff  644  3     200    *      J
/Volumes/DATA/log/07_debug.log        root:staff  644  3     200    *      J

/var/log/apache2/access_log           root:staff  644  3     *    $W6D23   J  #Saturday night
/var/log/apache2/error_log            root:staff  644  3     *    $W6D23   J


sudo newsyslog -vn  # test new configuration
/var/log/01_alert.log <3J>: size (Kb): 4 [100] --> skipping
/var/log/02_crit.log <3J>: size (Kb): 4 [100] --> skipping
/var/log/03_err.log <3J>: size (Kb): 24 [100] --> skipping
/var/log/04_warn.log <3J>: size (Kb): 16 [100] --> skipping
/var/log/appfirewall.log <3J>: size (Kb): 8 [100] --> skipping
/var/log/install.log <3J>: size (Kb): 68 [100] --> skipping
/var/log/mail.log <1J>: size (Kb): 24 [100] --> skipping
/var/log/secure.log <5J>: size (Kb): 80 [100] --> skipping
/var/log/system.log <7J>: size (Kb): 8 [200] --> skipping
/var/log/system.log <7J>: --> will trim at Thu Aug  1 00:07:00 2013
/var/log/kernel.log <5J>: size (Kb): 164 [200] --> skipping
/var/log/wtmp <3>: does not exist, skipped.
/var/log/wifi.log <3J>: size (Kb): 20 [100] --> skipping
/var/log/opendirectoryd.log <3J>: size (Kb): 4 [100] --> skipping
/Volumes/DATA/log/05_notice.log <3J>: size (Kb): 184 [200] --> skipping
/Volumes/DATA/log/06_info.log <3J>: size (Kb): 152 [200] --> skipping
/Volumes/DATA/log/07_debug.log <3J>: size (Kb): 160 [200] --> skipping
/var/log/apache2/access_log <3J>: --> will trim at Sat Aug  3 23:00:00 2013
/var/log/apache2/error_log <3J>: --> will trim at Sat Aug  3 23:00:00 2013
/Library/Logs/slapconfig.log <10J>: does not exist, skipped.
/var/log/kernel.log <5J>: size (Kb): 164 [1000] --> skipping
/Library/Logs/named.log <5J>: does not exist, skipped.
/var/log/wifi.log <3J>: --> will trim at Thu Aug  1 00:00:00 2013
newsyslog -vF # Force in preparation for new activities

/var/log/appfirewall.log <3J>: size (Kb): 20 [100] --> trimming log....
/var/log/ftp.log <1J>: does not exist, skipped.
/var/log/hwmond.log <3J>: does not exist, skipped.
/var/log/install.log <3J>: size (Kb): 12 [100] --> trimming log....
/var/log/ipfw.log <3J>: does not exist, skipped.
/var/log/lookupd.log <1J>: does not exist, skipped.
/var/log/lpr.log <1J>: does not exist, skipped.
/var/log/mail.log <1J>: size (Kb): 4 [100] --> trimming log....
/var/log/ppp.log <1J>: does not exist, skipped.
/var/log/secure.log <5J>: size (Kb): 4 [100] --> trimming log....
/var/log/system.log <7J>: --> trimming log....
/var/log/wtmp <3>: does not exist, skipped.
/Library/Logs/slapconfig.log <10J>: does not exist, skipped.
/var/log/kernel.log <5J>: size (Kb): 512 [1000] --> trimming log....
/Library/Logs/named.log <5J>: does not exist, skipped.
/var/log/wifi.log <3J>: does not exist, skipped.
Signal all daemon process(es)...
Notified daemon pid 20 = /var/run/
Pause 10 seconds to allow daemon(s) to close log file(s)
Compress all rotated log file(s)...

Launchctl file


rearranged by DGG for clarity

   <key>Label</key> <string></string>
    <key>ProgramArguments</key> <array> <string>/usr/sbin/newsyslog</string> </array>
    <key>LowPriorityIO</key> <true/>
    <key>Nice</key> <integer>1</integer>
    <key>StartCalendarInterval</key> <dict> <key>Minute</key> <integer>30</integer> </dict>

see also

Apple Syslog Manager