Saturday, December 27, 2008

Apple System Logger

Despite appearances, the system logging facility is unique on OS X 10.4 and newer. The syslogd daemon used on most Unix-like operating systems was replaced with the Apple System Logger (ASL).

Instead of using a new program name, Apple just used the traditional Unix system logger name. I think this can be a source of confusion and was not a great decision.

Binary Logs, then Text Logs

Instead of logging everything to text log files in /var/log, ASL logs all messages to a binary database file, /var/log/asl.db. From there, certain messages are written to the more familiar text based logs based on settings in /etc/syslog.conf.

In a way, Apple hacked the syslogd process, but did so in a way that maintains some level of backward compatibility with the knowledge and tools of system administrators coming from other Unix-like systems. I admit I was quite surprised to find out how this mechanism has been implemented by Apple.

The binary asl.db database is cleaned periodically, removing older messages from the database and keeping it from growing indefinately. The text based logs are still compressed and rotated as usual.

Reading log files

You can use the GUI utility, Console.app, to browse the Apple binary log database. It has a nice case insensitive search ability.

The command line interface to the Apple binary log is syslog.

Entering syslog with no parameters dumps the entire database. You can pipe the output through a grep command looking for a text string. For example,

syslog | grep Error

returned a large number of errors showing someone trying to login to my system via SSH as root:

Sat Dec 20 16:18:42 white com.apple.SecurityServer[22] : checkpw() returned -2; failed to authenticate user root (uid 0).

Yikes! Not to worry, when remote logins (SSH) are enabled, the default configuration does not allow root logins. According to the man page, you can also search for particular keys in the database using the -k option. Unfortunately, the list of valid keys is not in the man page.

Logging from a script

Finally, you can send a message to the log file using the -s parameter. Messages in the traditional syslog system are categorized by severity, or log level:

Emergency (level 0)
Alert (level 1)
Critical (level 2)
Error (level 3)
Warning (level 4)
Notice (level 5)
Info (level 6)
Debug (level 7)

To send a Warning message, use:

syslog -s -l 4 "this is a warning"

produces this in the log:

Sat Dec 20 18:42:29 white syslog[40323] : this is a warning