Here's a plug for ASL, and a hopefully not-too-long-winded description of the system.
It's useful to start with the architecture. At the center of ASL is a server process. Since ASL is in many ways a replacement for the old BSD syslogd server, we've re-used the name "syslogd" for it, even though it is actually completely new code. Since it's open source: http://darwinsource.opendarwin.org/10.4.4.ppc/syslog-13.1/syslogd.tproj/ you can follow along with your Web browser! :-)
syslogd is organized around a central run loop (syslogd.c and daemon.c). A set of input "modules" (asl_in.c, bsd_in.c, klog_in.c, udp_in.c) collect log messages from a number of sources: /var/run/syslog (the UNIX Domain socket that the syslog(3) library supports), /dev/klog (kernel messages), /var/run/asl_input (the socket supported by the asl(3) API), the traditional syslog network port, and potentially others. Each input module adds one or more sockets to the run loop, and is called to read messages when there's activity on their sockets.
On the other side of the run loop is a set of output modules (bsd_out.c, asl_action.c, and asl_in.c which is also an output module). Each module registers a query (see the asl(3) man page) with the run loop. Whenever a message is received, the run loop compares the message with each query. If the message matches the query, the output module is called with the message. The output module, in turn, can do anything it wants. The bsd_out.c module compares the log priority and facility of the message with the configuration parameters it reads from /etc/syslog.conf, and writes messages in the corresponding log files. Another output module (asl_action.c) will post notifications (see notify(3)), and will perform other actions in future Mac OS X releases.
On the output side, asl_in.c writes messages into a data store (/var/log/asl.log). The data store acts as a long-lived, searchable repository for log messages. A goal in the design of ASL was to reduce the number of log files scattered all over the system. We have a great many of them, and more appear all the time. Over time, we plan to phase out the traditional log files, and emphasize the data store (and the tools that access it).
I should mention that the data store is undergoing a large amount of change after Mac OS X 10.4 (Tiger). The initial implementation is a fairly primitive flat file. The next version of ASL will use store that is much more of a real database. It will support better searching, have better performance, and improve security. This by itself should make you immediately want to go stand in line at the nearest Apple store to wait to buy a copy of Mac OS X 10.5. :-)
Let's move on to using ASL. A design goal for ASL was to support better structure in log messages. An ASL message is an open-ended key/value dictionary. You can add attribute keys and values arbitrarily. This is much nicer than the old syslog API, which limited you to only a few message attributes.
The API is a bit more complex than the old syslog API, mostly to allow this open-ended message structure. The asl(3) man page has a fair bit of sample code, so I won't bore you with any here. The most important point in creating and sending ASL message is that you can add any attributes you want. If it's useful for your messages to have a "Flavor" attribute, you can add one:
m = asl_new(ASL_TYPE_MSG); asl_set(m, "Flavor", "Strawberry");
If you want to set your "Facility" to "Foobar", all you need to add is:
asl_set(m, "Facility", "Foobar");
Astute users of the syslog(3) APIs should, at this point, suddenly sit up straight. Be careful not to knock over your coffee cup. Yes indeed, the "Facility" for log messages is now just an arbitrary string. You don't need to change <sys/syslog.h> to add a new facility code. You don't need to overload LOG_LOCAL1 or whatever. While this is actually a very nice feature of ASL, let me just add one note about facility names:
We All Need To Play Nicely And Share The Namespace.
My example - "Foobar" - is actually a very bad one. We strongly encourage you to use the now-commonly-used reverse-ICANN style convention. For example, "com.foobar.killerapp". The 10.4 syslogd server doesn't enforce any policy restrictions on the Facility namespace, but please try to choose names that make sense and don't step on other developers' toes.
As I mentioned above, one of the goals was to reduce the number of log files. syslogd now saves messages in a data store. So how do you get to see your messages? One way to retrieve messages from the datastore is to use some search API in the asl(3) library. The asl(3) man page has lots of example code, so once again I won't bore you with it here.
While it's just dandy to be able to write an application that can dredge up old log messages using the asl(3) API, most of the time we just want to go look at messages from a shell. You can do this using the "syslog" command line utility. The simplest usage is:
syslog
which prints all the messages in the datastore. Another popular variation provides the same functionality as "tail -f":
syslog -w
This "watches" the main output stream from the daemon. It prints messages as they arrive. If you want to only see messages from your application:
syslog -w -k Sender Foobar
Once again, this watches the output stream, but it only prints messages when the value associated with the "Sender" key is "Foobar". Each "-k" option is followed by a key/value query of some sort. The simplest is shown above. It does an equality test. It's actually a short form of:
syslog -k Sender eq Foobar
To view messages from any Sender *except* Foobar:
syslog -k Sender ne Foobar
The operators like "eq", "ne", "lt", and so on are described in the syslog(1) man page. You can do case-folding, substring matching, numerical comparisons, and even regular _expression_ matching. You can chain a bunch of these together:
syslog -k Sender Foobar -k Level Nle 5 -k Time ge -2h
To see all messages from Foobar with Level numerically less than or equal to 5 (LOG_NOTICE / ASL_LEVEL_NOTICE and higher priorities), which were sent in the last 2 hours (-2h means 2 hours before the current time).
The syslog command is a swiss-army-knife tool for the ASL system, so it has a lot of options. The man page is good reading, although it didn't make it as an Oprah Book Club selection. Have a look as the man pages for asl(3), syslogd(8), and syslog(1). They should provide a pretty good picture of what ASL is all about.
-- Marc Majka
|