Why ASL?
It occurred to me just a few minutes ago that I should have discussed this first. So, I’m retroactively designating this post as the first in the ASL series. (I’m also forging the timestamp—I actually posted this at about 16:44 PST).
Most of us probably use NSLog
when we want to log some information:
void NSLog(NSString *format, ...);
Those of us unlucky enough to not have access to Cocoa (e.g., working on a UNIX utility) probably use printf
/fprintf
instead:
int printf(const char *restrict format, ...); int fprintf(FILE *restrict file, const char *restrict format, ...);
Both of these are fine, but they lack a couple of things.
First off, they lack any indication of a message’s importance. All messages are just lines in a file (especially with the *printf
functions), and they’re all on equal footing.
That problem is solved by syslog(3):
void syslog(int priority, const char *format, ...);
syslog
lets you specify any of eight different levels of priority for a message:
- Emergency
- Alert
- Critical
- Error
- Warning
- Notice
- Info
- Debug
And that’s great. syslog
and the lesser functions NSLog
and printf
/fprintf
have served all of us well for years.
But, for Mac OS X 10.4, Apple said “we can do better”.
And so they created the Apple System Logger.
ASL redefines a “message” to be more than just text. Now, it’s a bundle of key-value pairs—what Cocoa and CF call a dictionary. All the usual properties of a message (including the timestamp, the priority, the process that sent it, and the message itself) are now simply pairs in the dictionary. This is the other thing that NSLog
and printf
/fprintf
lack.
This has two practical benefits:
- You can make up your own properties. You’re not limited to just the stock properties anymore; you can invent any properties you want.
- You can search the log more easily, now that messages are no longer just text. (This was improved in Leopard, which uses a real database for the log storage; Tiger used a text-based log file.)
And all this is very easy to use—barely more complex than using NSLog. Here’s a taste:
asl_log(NULL, NULL, ASL_LEVEL_NOTICE, "Hello %s!", "world");
I’ll tell more about the task of writing to the log (as well as list all nine of the standard properties) in the next post.
UPDATE 2009-04-24: Corrected use of syslog’s LOG_NOTICE
to ASL’s ASL_LEVEL_NOTICE
.