ASL: Using ASL from the command line

2008-01-26 17:35:57 UTC

Mac OS X comes with a couple of utilities you can use to work with ASL from your nearest shell prompt.

The older of the two is logger(1), a user interface on the older syslog(3) API. This utility is write-only; it only lets you make entries, not review previous entries. (This makes sense: Historically, syslog wrote its output to a text file that you could tail, view, or grep; you didn’t need a separate utility to read it in any way.)

The newer of the two is syslog(1). As I mentioned in the first post, the name is a bit misleading, because it’s actually built on the ASL API, not syslog(3).

Like logger, syslog lets you write (send) to the log. The usage for that is:

syslog -s -k key value

Note the -s flag, for send.

Unlike logger, you can also read from (search) the log. As with asl_set vs. asl_set_query, you can specify a comparison operator, or leave it out and default to equality testing. To search, simply leave out that -s argument.

  • syslog -k key value
  • syslog -k key operator value

In all cases, you can specify multiple key-value pairs. For searching, the criteria are joined by logical AND (just like with the ASL API underneath).

syslog also provides a -w switch that you can use to poll (“watch”) the database repeatedly. As I mentioned above, polling is the only way to do that with the current API.

Finally, syslog also provides a -c switch to configure syslogd’s filter masks:

  • syslog -c process off
  • syslog -c process new_value

The possible values for process are:

0
Master filter
syslogd” or “syslog
Data store filter
Non-zero number
Per-process filter of process with that PID
Anything else
Per-process filter of process with that name


You must be root (or use sudo) to change the master or data store filter, or (as you might have expected) the per-process filter of a process owned by root. Surprisingly, however, you can set the per-process filter of a process you don’t own, as long as it isn’t owned by root. I believe that this is either a bug or something they didn’t consider (for whatever reason), and have filed it as such.

The other argument must be one of:

“off”
Turns the filter off (of course).
A list of numbers, separated by commas (e.g., “0,1,2,4”)
Sets the filter to allow only those levels (bits), identified by number.
A string of characters from the set “pacexwnid” (e.g., “pacw”)
Sets the filter to allow only those levels, identified by name (where ‘p’, standing for “Panic”, is syslog(1)’s name for Emergency, and ‘x’ is a synonym for Error).
A hyphen, followed by one of the aforementioned letters (e.g., “–w”)*
Every level up to and including that level (i.e., ASL_FILTER_MASK_UPTO(…)); for example, “-d”, meaning “everything up to Debug” (equivalent to everything)

* Note that the first two examples (“0,1,2,4” and “pacw”) skip Error, but the third one (“-w”) includes it, since the range syntax cannot exclude any bit within the range.


Next in the ASL series: Test apps!

3 Responses to “ASL: Using ASL from the command line”

  1. Cédric Luthi Says:

    Note that you can’t turn the ASL Data Store filter off. Although sudo syslog -c syslogd off will tell you Set ASL Data Store syslog filter mask: Off, nothing actually happens in syslogd, the old filter mask still stand. If you want to log all levels in the ASL Data Store, you should use instead sudo syslog -c syslogd -d

    Anyway, you probably do not want to do that because launchd (pid 1) produces a ton of debug logs.

  2. Jens Ayton Says:

    Since Leopard, syslog(1) does not actually poll. Instead, it uses the notify.h API to listen for “com.apple.system.logger.message” notifications. This is “documented” in the sense that it has an entry in notify_keys.h.

    notify_register_dispatch(kNotifyASLDBUpdate, &_token, dispatch_get_main_queue(), ^(int token) {
    printf(“Something happened!\n”); // I suggest not using NSLog here.
    });

  3. Jens Ayton Says:

    Complete example: https://github.com/JensAyton/watchlog

Leave a Reply

Do not delete the second sentence.