Re: asl and the console
Re: asl and the console
- Subject: Re: asl and the console
- From: Marc Majka <email@hidden>
- Date: Fri, 02 Jul 2010 11:08:31 -0700
The simple answer is that Debug and Info level messages get filtered out.
The longer answer is how this filtering works. There are filters in two places: on the client's side (your application) and on the server side (the syslogd daemon).
syslogd receives log messages from various sources: from Libc (via the asl(3) and syslog(3) APIs), from the kernel, and - if the UDP listener port is enabled - from network sources. The server filters and files messages by following the rules in two different configuration files: /etc/syslog.conf and /etc/asl.conf.
/etc/syslog.conf is the "legacy" BSD syslog configuration file. It has lines that match facility names and levels. If a message matches the facility and level on the line, the message is formatted in a standard way and written out to a specified flat file. There are also configuration lines that will send matching messages to specified network addresses (and optional UDP port numbers), or that will write to ttys of all or selected users.
The /etc/asl.conf file specifies additional rules for processing messages. Most of the lines in the file are pattern matching rules that determine whether received messages will be saved in the ASL data store. The data store is what you see in the "DATABASE SEARCHES" section of Console.app, and what you see when you run the "syslog" command-line utility.
If you are not seeing Debug or Info level messages when you run Console (or use "syslog"), then it's because those messages are not getting saved in the ASL data store. Why? One reason is that the /etc/asl.conf file may be screening them out. Indeed: if you read through the file, you'll see:
# save kernel [PID 0] and launchd [PID 1] messages
? [<= PID 1] store
# save everything from emergency to notice
? [<= Level notice] store
# save lpr info level and above
? [<= Level info] [= Facility lpr] store
# save all mail, ftp, local0, and local1 messages
? [= Facility mail] store
? [= Facility ftp] store
? [= Facility local0] store
? [= Facility local1] store
Kernel and launchd messages all get saved. Everything from Info to Emergency from the "lpr" facility gets saved. All messages from mail, ftp, local0, and local1 facilities get saved. For everything else, only Notice to Emergency gets saved - Info and Debug messages get filtered out.
We set this up as the default because there are just *way* too many Info and Debug messages. Saving them all fills up disk space too fast, and you have to remember that most of Apple's customers are not really all that techie. Saving all messages would largely just be a waste of energy and disk space.
So, it you want to see all those Info and Debug level messages in Console, then it is necessary* (but not sufficient - see below) to change the config file. Assuming you might want to change the settings back to the original some day, you could just change that main line from
? [<= Level notice] store
to
? [<= Level debug] store
However, you can tailor the rules to meet your needs. The asl.conf man page tells you how.
When I said it was not sufficient to just change the asl.conf file, that's because it only controls whether syslogd saves the messages that it *receives* from clients. There's also filtering in the client-side library code (in Libc) that determines whether or not your process *sends* messages to syslogd. If your client doesn't send it, it won't end up in the data store!
The asl(3) and syslog(3) library both contain API for setting a client-side filter. The filter is a bitmask of message levels. If the bit corresponding to a level is set, the library sends the message to syslogd. If it is zero, the library just drops the message.
The default for the syslog(3) API is to do no filtering - all messages are passed to syslogd.
The default for the asl(3) API is to filter out ASL_LEVEL_INFO and ASL_LEVEL_DEBUG. Aha! If you are using asl_log(), you need to make some adjustments.
If you want to change the client filter in your own code, you can set it using asl_set_filter(). See the asl(3) man page. It's very similar to the setlogmask() API in the syslog(3) library.
* I've saved the best for last. It's not always necessary to change the asl.conf file. There's one more way to control the filtering for a particular application, although it only works while that process is running. There's a remote-control mechanism that you can use to adjust filtering "on-the-fly". For example, if you want all messages from the application named "MyApp" to get saved in the ASL data store, then you can do:
syslog -c MyApp -d
See the syslog(1) man page for specifics, but briefly, this overrides the Library-code bit mask with a remote-control bitmask. "-d" means "everything from emergency to debug".
A great feature of this remote-control mechanism is that it also causes messages from your process to tunnel through any filtering that's in place for the ASL data store. So, if you are debugging your application, just set the remote-control mask using "syslog -c", and it just works! Messages send by your process will all get saved in the data store and appear in Console, even if you still have server-side filtering in /etc/asl.conf. This "tunneling" behavior persists until the process exits,. or you turn it off, e.g.:
syslog -c MyApp off
Final detail: there are actually two remote-control filters. Not only are there per-process remote control filters, but there is a global filter that applies to ALL running processes. The global, or "master" filter as it is sometimes called in the man pages, is normally "off", just like all the per-process remote control filters. If you really want to see a lot of messages, you could set the global bitmask to allow all messages:
syslog -c 0 -d
or, alternatively, if you wanted to tell all processes to stop logging anything except Emergency and Alert level messages:
syslog -c -0 pa
See the syslog(1) man page for details. As with the per-process filter, messages sent from processes which are under control of the global filter will tunnel through /etc/asl.conf filtering.
OK, really the final detail: If you enable the global filter, it overrides the Libc (asl_set_filter or setlogmask) bitmask. However, the per-process remote-control overrides both. So you could, for example, get all processes to log very verbosely, but then tell particular processes to cut down to Emergency to Error:
syslog -c 0 -d
syslog -c LoudMouth -e
or you might want to tell everyone to be quite except for your own application:
syslog -c 0 p
syslog -c MyApp -d
In practice, the global / "master" filter is really not that useful, but it's part of what goes on in the client code.
Hope this helps!
--
Marc Majka
> Hello,
>
> I did not find any list that looked more appropriate, so I am trying my luck here...
>
> When my App is sending messages with asl_log(3) , I only see messages in the Console between the levels of ASL_LEVEL_NOTICE and ASL_LEVEL_EMERG. So far, so good. Normal users should not be swamped with messages of level ASL_LEVEL_INFO or ASL_LEVEL_DEBUG.
>
> But how can I as a developer, or even a user, query the console in such a way that these levels are included? I tried setting up a little query in the Console.app GUI, but still, I got nothing less important than Notice.
>
> I have also tried to RTFM if I can do it in the command line, but did not see anything.
>
> Am I doing something wrong? Did I miss something?
>
> Thanks
>
> Alex
>
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Darwin-dev mailing list (email@hidden)
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden