★ MG_LOG sublogger level handling change
posted Tue 12 May 2015 by Michael Galloy under IDLIf you use subloggers in MG_LOG
(in the dist_tools directory of mglib), I have made a big change in how the priority of a sublogger message is handled.
First, some background: MG_LOG
is a routine that lets you configure log output in an application. For more detailed information, see previous articles I have published about it. But the simplest example is:
IDL> mg_log, 'starting application', /info
2015-04-29 19:45:55 INFO: $MAIN$: starting application
The INFO
keyword indicates the level of the message: critical, error, warning, informational, or debug. The logger’s level (along with many other configuration details such as setting a filename for the output log, formatting the log message, etc.) can also be set. For loggers, there is also a “not set” level indicating that the logger’s level should not be used (this will make sense in a second). Only messages with a priority as high or higher than the logger’s will be printed. For example:
IDL> mg_log, logger=logger
IDL> logger->setProperty, level=3 ; warning
IDL> mg_log, 'this message should be printed', /warning
2015-04-29 19:53:33 WARN: $MAIN$: this message should be printed
IDL> mg_log, 'this message should NOT be printed', /info
IDL>
Furthermore, you can have nested named loggers and configure them independently. The change has been to how the level of the message gets compared to the levels of the nest loggers in this case.
For example, let’s get the logger objects for a named logger and two of its children:
mg_log, name='mg_log_demo', logger=logger
mg_log, name='mg_log_demo/sub1', logger=sub1logger
mg_log, name='mg_log_demo/sub2', logger=sub2logger
Then set their levels in the following manner:
logger->setProperty, level=3 ; warning
sub1logger->setProperty, level=5 ; debug
sub2logger->setProperty, level=1 ; critical
Which messages should now appear? My previous scheme was to use the most restrictive level in the hierarchy. So for example, a message to the “mg_log_demo/sub1” logger would have to have level 3 (warning) or higher to pass. But this made it hard to have a fairly restrictive high level setting, but turn on debug output for the section of the application you were currently working on. So I have reversed the logic: the least restrictive level in the hierarchy is now used. So for our setup:
mg_log, 'should appear', name='mg_log_demo', /warn
mg_log, 'should not appear', name='mg_log_demo', /info
mg_log, 'should appear', name='mg_log_demo/sub1', /debug
mg_log, 'should appear', name='mg_log_demo/sub2', /warn
mg_log, 'should not appear', name='mg_log_demo/sub2', /info
mg_log, 'should appear', name='mg_log_demo/sub3', /warn
mg_log, 'should not appear', name='mg_log_demo/sub3', /info
For the common case of setting your top-level logger to informational and setting a sublogger for the section of code you are working on to debug, this should now work as expected. I also added a “not set” logger level (level 0) which indicates that the logger level should not be used when finding the least restrictive level in the hierarchy. The “not set” level is the default level for loggers. If no loggers have a level set, all messages get logged.
Whew! This seems complicated, but I think it is the natural way to thing about this and the most useful in common situations.