logging revision dafcb997e390efa4423883dafd100c975c4095d6
1121N/ACopyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
1121N/ACopyright (C) 1999-2001 Internet Software Consortium.
1121N/ASee COPYRIGHT in the source root or http://isc.org/copyright.html for terms.
1121N/A
1121N/A$Id: logging,v 1.10 2004/03/05 05:04:46 marka Exp $
1121N/A
1121N/AOVERVIEW
1121N/A
1121N/AThe ISC logging system is designed to provide a flexible, extensible
1121N/Amethod of writing messages. Messages can be sent to the system's
1121N/Alogging facility, directly to a file, or into the bitbucket, usually
1121N/Aconfigured per the desires of the users of the program. Each message
1121N/Ais associated with a particular category (eg, "security" or
1121N/A"database") that reflects its nature, and a particular module (such as
1121N/Athe library's source file) that reflects its origin. Messages are
1121N/Aalso each assigned a priority level which states how remarkable the
1121N/Amessage is, so that too can be configured by the program's user to
1121N/Acontrol how much detail is desired.
1121N/A
1121N/ALibraries which use the ISC logging system can be linked against each
1121N/Aother without fear of conflict. A program is able to select which, if
1121N/Aany, libraries will write log messages.
1121N/A
1121N/AFUNDAMENTALS
5086N/A
5855N/AThis section describes the basics of how the system works, introduces
1121N/Aterms and defines C preprocessor symbols used in conjuction with
1182N/Alogging functions. Actual uses of functions are demonstrated in the
1121N/Afollowing two sections.
5414N/A
1689N/ALog messages are associated with three pieces of information that are
1689N/Aused to determine their disposition: a category, a module, and a
1689N/Alevel (aka "priority").
1689N/A
1689N/AA category describes the conceptual nature of the message, that is,
1280N/Awhat general aspect of the code it is concerned with. For example,
1689N/Athe DNS library defines categories that include the workings of the
1689N/Adatabase as well security issues. Macros for naming categories are
2086N/Atypically provided in the library's log header file, such as
2086N/ADNS_LOGCATEGORY_DATABASE and DNS_LOGCATEGORY_SECURITY in <dns/log.h>
1689N/Afor the two categories in the previous sentence. The special category
1121N/AISC_LOGCATEGORY_DEFAULT is associated with any message that does not
1121N/Amatch a particular category (or matches a category but not a module,
1121N/Aas seen in the next paragraph).
1121N/A
1121N/AA module is loosely the origin of a message. Though there not be a
1823N/Aone-to-one correspondence of source files with modules, it is typical
1121N/Athat a module's name reflect the source file in which it is used. So,
1823N/Afor example, the module identifier DNS_LOGMODULE_RBT would be used by
1823N/Amessages coming from within the dns/rbt.c source file.
1823N/A
1121N/AThe specification of the combination of a category and a module for a
2350N/Amessage are called the message's "category/module pair".
1121N/A
1121N/AThe level of a message is an indication of its severity. There are
1121N/Asix standard logging levels, in order here from most to least severe
1689N/A(least to most common):
1121N/A ISC_LOG_CRITICAL -- An error so severe it causes the program to exit.
1689N/A ISC_LOG_ERROR -- A very notable error, but the program can go on.
2086N/A ISC_LOG_WARNING -- Something is probably not as it should be.
2086N/A ISC_LOG_NOTICE -- Notable events that occur while the program runs.
2086N/A ISC_LOG_INFO -- Statistics, typically.
1121N/Aand finally:
1121N/A ISC_LOG_DEBUG(unsigned int level) -- detailed debugging messages.
3988N/A
5086N/AISC_LOG_DEBUG is not quite like the others in that it takes an
3988N/Aargument the defines roughly how detailed the message is; a higher
3853N/Alevel means more copious detail, so that values near 0 would be used
3853N/Aat places like the entry to major sections of code, while greater
3853N/Anumbers would be used inside loops.
3853N/A
3853N/ASo, ok, technically there are five + at least 4,294,967,296 levels.
3853N/APicky picky. In any event, the six levels correspond with similar
3853N/Alevels used by Unix's syslog, and when messages using one of those
1182N/Alevels is sent to syslog, the equivalent syslog level is used. (Note
1689N/Athat this means that any debugging messages go to the singular
1191N/ALOG_DEBUG priority in syslog, regardless of their level internal to
1121N/Athe ISC logging system.)
1121N/A
1121N/AThe next building block of the logging system is a channel. A channel
1121N/Aspecifies where a message of a particular priority level should go, as
1121N/Awell as any special options for that destination. There are four
1121N/Abasic destinations, as follows:
1121N/A
2832N/A ISC_LOG_TOSYSLOG -- Send it to syslog.
5414N/A ISC_LOG_TOFILE -- Write to a file.
3853N/A ISC_LOG_TOFILEDESC -- Write to a (previously opened) file descriptor.
1121N/A ISC_LOG_TONULL -- Do not write the message when selected.
1121N/A
1121N/AA file destination names a path to a log file. It also specifies the
1121N/Amaximum allowable byte size of the file before it is closed (where 0
1121N/Ameans no limit) and the number of versions of a file to keep (where
1177N/AISC_LOG_ROLLNEVER means the logging system never renames the log file,
1121N/Aand ISC_LOG_ROLLINFINITE means no cap on the number of versions).
1121N/AVersion control is done just before a file is opened, so a program
1121N/Athat used it would start with a fresh log file (unless using
1177N/AISC_LOG_ROLLNEVER) each time it ran. If you want to use an external
1121N/Arolling method, use ISC_LOG_ROLLNEVER and ensure that your program has
1177N/Aa mechanism for calling isc_log_closefilelogs().
1177N/A
1121N/A(ISC_LOG_ROLLINFINITE is not truly infinite; it will stop at INT_MAX.
1121N/AOn 32 bit machines that means the logs would need to roll once per
1121N/Asecond for more than sixty years before exhausting the version number
1121N/Aspace.)
1121N/A
1177N/AA file descriptor destination is simply associated with a previously
1177N/Aopened stdio file descriptor. This is mostly used for associating
1177N/Astdout or stderr with log messages, but could also be used, for
1121N/Aexample, to send logging messages down a pipe that has been opened by
1121N/Athe program. File descriptor destinations are never closed, have no
1121N/Amaximum size limit, and do not do version control.
1183N/A
1823N/ASyslog destinations are associated with the standard syslog facilities
1400N/Aavailable on your system. They too have no maximum size limit and do
1400N/Ano version control.
1400N/A
1400N/ASince null channels go nowhere, no additional destination
1400N/Aspecification is necessary.
1121N/A
1121N/AThe words "destination" and "channel" can be used interchangably in
1121N/Asome contexts. Referring to a file channel, for example, means a
1121N/Achannel that has a file destination.
1121N/A
1121N/AChannels have string names that are their primary external reference.
1121N/AThere are four predefined logging channels:
1121N/A
1121N/A "default_stderr" -- Descriptor channel to stderr at priority ISC_LOG_INFO
1177N/A "default_debug" -- Descriptor channel to stderr at priority ISC_LOG_DYNAMIC
1121N/A "default_syslog" -- Syslog channel to LOG_DAEMON at priority ISC_LOG_INFO
1121N/A "null" -- Null channel
1121N/A
1121N/AWhat's ISC_LOG_DYNAMIC? That's how you tell the logging system that
4802N/Ayou want debugging messages, but only at the current debugging level
4802N/Aof the program. The debugging level is controlled as described near
4802N/Athe end of the next section. When the debugging level is 0 (turned
4802N/Aoff), then no debugging messages are written to the channel. If the
4802N/Adebugging level is raised, only debugging messages up to its level are
4802N/Awritten to the channel.
1177N/A
3853N/AYou can reuse a channel name. If you define a channel with the same
3853N/Aname as an existing channel, the new definition is used by all future
2350N/Areferences to the name. The old definition is still used by anything
3853N/Athat was pointing to the name before the redefinition. This even
1121N/Aapplies to redefinitions of the predefined channels, with one
1191N/Aexception: redefining default_stderr will change the default
1823N/Adestination of messages, as explained in more detail in a few paragraphs.
1191N/A
1191N/AChannels can additionally have any of five options associated with
1823N/Athem. The following options are listed in the order which their
1121N/Acorresponding print strings appear in a log message:
3988N/A
1121N/A ISC_LOG_PRINTTIME -- The date and time.
5086N/A ISC_LOG_PRINTCATEGORY -- The category name.
5086N/A ISC_LOG_PRINTMODULE -- The module name.
1121N/A ISC_LOG_PRINTLEVEL -- The level.
1121N/A
5086N/AYou can set all four of those options with ISC_LOG_PRINTALL.
2089N/A
1121N/ASyslog channels do not need ISC_LOG_PRINTTIME, but it is usally a good
1121N/Aidea for file and file descriptor feeds.
1400N/A
1121N/AThe additional option does not affect formatting. It is
1121N/AISC_LOG_DEBUGONLY, and marks a channel as only being eligible for
1121N/Amessages when the debugging level is non-zero. It acts like the
1121N/Anull channel when the debugging level is zero.
1177N/A
1121N/ANow with these objects -- the category, module, and channel -- you can
1177N/Aactually direct messages to your desired destinations. As shown in
1121N/Athe next section, you associate the category/module pair with a
1121N/Achannel. It is possible to use one function call to say "all modules
1121N/Acoupled with this category" and vice versa, but conceptually the
1121N/Amatching is still referred to as applying to category/module pairs,
1121N/Asince that is what comes in from functions writing messages.
1121N/A
1121N/ASpeaking of functions writing messages, here's what happens when a
5855N/Afunction wants to write a message through the logging system. First
1121N/Athe function calls isc_log_write(), specifying a category, module and
1121N/Alevel.
3853N/A
3853N/AIn isc_log_write(), the logging system first looks up a list that
1121N/Aconsists of all of the channels associated with a particular category.
1177N/AIt walks down the list looking for each channel that also has the
1121N/Aindicated module associated with it, and writes the message to each
3853N/Achannel it encounters. If no match is found in the list for the
3853N/Amodule, the default channel is used. Similarly, the default is used
3853N/Aif no channels have been specified for the category at all.
3853N/A
3853N/AWhat is the default? It is ISC_LOGCATEGORY_DEFAULT -- sort of. You
3853N/Acan specify an association of the channel ISC_LOGCATEGORY_DEFAULT with
3853N/Aany particular module, or more usually all of them, and that's what
3988N/Awill be used for any category/module pair for which you have not
1121N/Aspecified a channel. If you do not associate ISC_LOGCATGORY_DEFAULT
5086N/Aand the indicated module, then the internal default of using the
5086N/Adefault_stderr channel is used. This brings us back to the statement
1121N/Amade a few paragraphs ago about redefining the predefined channels --
1121N/Aif you redefine default_stderr, and a messages comes in for a
1177N/Acategory/module pair that has had neither its original pair or
1121N/Athe ISC_LOGCATEGORY_DEFAULT/module pair configured for it, then the
1121N/Amessage will go to the _new_ definition of default_stderr.
1121N/A
3988N/AHere are some other ways to think about how category/module pairs get
1121N/Amatched with regard to using the defaults:
1121N/A
1121N/A If a channel is is specified for a category as applying to all modules
1121N/A which use that category, then the default channel will be used for no
1121N/A combination of that category with any module.
1121N/A
1121N/A If a category is specified with one or more explicit modules, any
4306N/A modules _not_ using that category still use the default.
3853N/A
1121N/AAs with the BIND 8 logging code, when a log message is not written
1121N/Abecause the of the severity level of the channel, the default is _not_
1121N/Aused, because the category and module are considered to have matched.
1121N/AThe default is only used when a category/module pair has not been
1121N/Aspecified. If you want to use the default for some messages but also
1121N/Asend higher (lower?) priority messages someplace else, then you will
1121N/Aneed to specify both the default channel and a custom channel for that
1121N/Acategory/module pair.
4306N/A
3853N/AIt is important to note that specifying a null destination for a
1121N/Acategory/module pair has no effect on any other destinations
1121N/Aassociated with that pair, regardless of ordering. For example,
1121N/Athough it seems reasonable, you cannot say "for category A and all
1121N/Amodules, log to stderr, but for category A and module 2 don't show any
1121N/Amessages." You would need to specify stderr for category A with all
1121N/Amodules except module 2, and then specify null for A/2. This could be
1121N/Ainconvenient, especially if you do not know all of the modules
1121N/Aassociated with a particular category but you know the one you want to
4306N/Ashut up. Because of this, it is likely that specifying a null
3853N/Adestination _will_ block other channels that also specify a particular
1121N/Acategory/module pair, but the exact mechanism has not yet been
1121N/Adetermined.
1121N/A
1121N/ANo attempt is made to filter out duplicate destinations, so it is
1121N/Acertainly possible to define things such that a single log gets more
1177N/Athan one copy of the same message. This may change in the future.
1121N/A
1121N/AEXTERNALLY VISIBLE STRUCTURE
1177N/A
1121N/ATwo of the fundamental types used by programs for configuring log
1177N/Amessage destinations are isc_log_t and isc_logconfig_t. The isc_log_t
1121N/Atype is normally created only once by a program, to hold the (relatively)
1121N/Astatic information about what categories and modules exist in the program
3853N/Aand some other housekeeping information. isc_logconfig_t is used to
3853N/Astore the configurable specification of message destinations, which
1177N/Acan be changed during the course of the program.
1121N/A
1121N/AA starting configuration (isc_logconfig_t) is created implicitly when
1121N/Athe context (isc_log_t) is created. The pointer to this configuration
1121N/Ais returned via a parameter to isc_log_create so that it can then be
1121N/Aconfigurated. A new configuration can be established by creating
1121N/Ait with isc_logconfig_create, configuring it, then installing it as
1121N/Athe active configuration with isc_logconfig_use.
1121N/A
1121N/AMULTITHREADED PROGRAMS
1121N/A
1121N/AThe entire logging context is thread locked for most of duration of
1121N/Athe isc_log_write. However, isc_log_write does avoid the delays
1121N/Acaused by locking when it is clear that there are no possible outputs
1121N/Afor a message based on its debugging level --- this is so that a
1121N/Aprogram can have debugging messages sprinkled liberally throughout it
1121N/Abut not incur any locking penalty when debugging is not enabled.
1121N/A
1121N/AThe logging context is locked when a new configuration is installed
1121N/Aby isc_logconfig_use.
1121N/A
1121N/AUSING LIBRARIES THAT USE THE LOGGING SYSTEM
1121N/A
1121N/ATo enable the messages from a library that uses the logging system,
1121N/Athe following steps need to be taken to initialize it.
1121N/A
1121N/A1) Include the main logging header file as well as the logging header
1121N/Afile for any additional library you are using. For example, when
1121N/Ausing the DNS library, include the following:
1121N/A
1121N/A #include <isc/log.h>
1121N/A #include <dns/log.h>
1177N/A
1121N/A2) Initialize a logging context. A logging context needs a valid
1121N/Amemory context in order to work, so the following code snippet shows a
1121N/Arudimentary initialization of both.
1177N/A
1432N/A isc_mem_t *mctx;
1121N/A isc_log_t *lctx;
1121N/A isc_logconfig_t *lcfg;
1121N/A
3853N/A if (isc_mem_create(0, 0, &mctx) != ISC_R_SUCCESS) ||
1121N/A isc_log_create(mctx, &lctx, &lcfg) != ISC_R_SUCCESS))
3853N/A oops_it_didnt_work();
1121N/A
1177N/A3) Initalize any additional libraries. The convention for the name of
1121N/Athe initialization function is {library}_log_init, with just a pointer
1121N/Ato the logging context as an argument. The function can only be
5086N/Acalled once in a program or it will generate an assertion error.
1121N/A
1121N/A dns_log_init(lctx);
1121N/A
1177N/AIf you do not want a library to write any log messages, simply do not
1121N/Acall its the initialization function.
1121N/A
1121N/A4) Create any channels you want in addition to the internal channels
1121N/Aof default_syslog, default_stderr, default_debug and null. A
1121N/Adestination structure needs to be filled for any destination other
1121N/Athan null. The following examples show use of a file log, a file
1121N/Adescriptor log, and syslog.
1121N/A
1121N/A isc_logdestination_t destination;
1121N/A
1121N/A destination.file.name = "/var/log/example";
1121N/A destination.file.maximum_size = 0; /* No byte limit. */
1121N/A destination.file.versions = ISC_LOG_ROLLNEVER; /* External rolling. */
1121N/A if (isc_log_createchannel(lcfg, "sample1" ISC_LOG_TOFILE, ISC_LOG_DYNAMIC,
1121N/A &destination, ISC_LOG_PRINTTIME) != ISC_R_SUCCESS)
1121N/A oops_it_didnt_work();
1121N/A
1121N/A destination.file.stream = stdout;
1121N/A if (isc_log_createchannel(lcfg, "sample2" ISC_LOG_TOFILEDESC, ISC_LOG_INFO,
1121N/A &destination, ISC_LOG_PRINTTIME) != ISC_R_SUCCESS)
1121N/A oops_it_didnt_work();
1121N/A
1121N/A destination.facility = LOG_ERR;
1121N/A if (isc_log_createchannel(lcfg, "sample3" ISC_LOG_SYSLOG, ISC_LOG_ERROR,
1121N/A &destination, 0) != ISC_R_SUCCESS)
1121N/A oops_it_didnt_work();
1121N/A
1121N/ANote that ISC_LOG_DYNAMIC is used to define a channel that wants any
1121N/Aof the messages up to the current debugging level of the program
1121N/A(described below). ISC_LOG_DEBUG(level) can define a channel that
1121N/A_always_ gets messages up to the debug level specified, regardless of
1121N/Athe debugging state of the server.
1121N/A
1121N/ARemember that you can redefine these internal channels, and that in
3988N/Aparticular redefining default_stderr will change the default logging
1121N/Amethod.
1121N/A
1121N/A5) Direct the various log categories and modules to the desired
1121N/Adestination. This step is not necessary if the normal behavior of
1121N/Asending all messages to default_stderr is acceptable. The following
1121N/Aexamples sends DNS security messages to stderr, DNS database messages
1121N/Ato null, and all other messages to syslog.
1121N/A
1121N/A if (isc_log_usechannel(lcfg, "default_stderr", DNS_LOGCATEGORY_SECURITY,
1121N/A NULL) != ISC_R_SUCCESS)
1121N/A oops_it_didnt_work();
1121N/A
1121N/A if (isc_log_usechannel(lcfg, "null", DNS_LOGCATEGORY_DATABASE, NULL)
1121N/A != ISC_R_SUCCESS)
1121N/A oops_it_didnt_work();
1121N/A
1121N/A if (isc_log_usechannel(lcfg, "default_syslog", ISC_LOGCATEGORY_DEFAULT,
1121N/A NULL) != ISC_R_SUCCESS)
1121N/A oops_it_didnt_work();
1121N/A
1121N/AProviding a NULL argument for the category means "associate the
1121N/Achannel with the indicated module in all known categories" ---
1121N/Aincluding ISC_CATEGORY_DEFAULT. Providing a NULL argument for the
1121N/Amodule means "associate the channel with all modules that use this
1121N/Acategory."
1121N/A
5855N/A6) If you are sending any messages to syslog, call
1121N/Aisc_log_opensyslog(). Currently the arguments to this function are
1121N/Aexactly the same as to syslog's openlog() function, but it is expected
1121N/Athat this will change when the logging library is made to work with the
1121N/Asystem logging facility on Windows NT.
1121N/A
1121N/A isc_log_opensyslog(NULL, LOG_PID, LOG_DAEMON);
1121N/A
1121N/ANow the libraries used by your program will write messages according
1121N/Ato your specifications.
1121N/A
1121N/A7) If you want to swap in a new configuration to replace the existing
1121N/Aconfiguration, first create the new configuration with:
1177N/A
1177N/A result = isc_logconfig_create(lctx, &newlcfg);
1121N/A
1121N/Aand then configure newlcfg with isc_log_createchannel() and
1121N/Aisc_log_usechannel(). When it is all ready:
1121N/A
1121N/A result = isc_logconfig_use(lctx, newlcfg);
1121N/A
1121N/AIf the new configration is successfully installed, then the old one
1121N/Awill be destroyed, freeing all memory it used.
1177N/A
1177N/AThere are three additional functions you might find useful in your
1121N/Aprogram to control logging behavior, two to work with the debugging
1177N/Alevel and one to control the closing of log files.
1121N/A
1121N/Avoid isc_log_setdebuglevel(isc_log_t *lctx, unsigned int level) and
1121N/Aunsigned int isc_log_getdebuglevel(isc_log_t *lctx) set and retrieve
1121N/Athe current debugging level of the program. isc_log_getdebuglevel()
1121N/Acan be used so that you need not keep track of the level yourself in
1121N/Aanother variable. One use for these functions would be in a daemon
1121N/Athat could have its debugging level raised with a USR1 signal or lowered
1121N/Awith a USR2 signal.
1121N/A
1121N/AThe void isc_log_closefilelogs(isc_log_t *lcxt) function closes any
1121N/Aopen log files. This is useful for programs that do not want to do
1121N/Afile rotation as with the internal rolling mechanism. For example, a
1177N/Aprogram that wanted to keep daily logs would define a channel which
1121N/Aused ISC_LOG_ROLLNEVER, then once a day would rename the log file and
3853N/Acall isc_log_closefilelogs(). The next time a message needs to be
1121N/Awritten a file that has been closed, it is reopened.
1121N/A
1121N/AWRITING LIBRARIES THAT USE THE LOGGING SYSTEM
1121N/A
1177N/AThis section describes how a new library, libfoo.a, would use the ISC
1121N/Alogging system internally.
1121N/A
1121N/A1) Provide a header file that does the following:
5086N/A * includes isc/log.h
5086N/A * declares foo_lctx, a logging context that will be used throughout
5086N/A the library.
5086N/A * declares the structures that specify the categories and modules
5086N/A known by the library.
5086N/A * defines the macros that provide convenient access to the library's
5086N/A categories and modules.
5086N/A * prototypes the library's log initialization function.
5086N/A
5086N/A See <dns/log.h> for a sample.
5086N/A
5086N/A2) Write a C source module that includes the library's log.h,
5086N/A provides storage for the library's logging context,
5086N/A initializes the category and module structures, and defines the
5086N/A initialization function, foo_log_init(). log.c from libdns.a looks
5086N/A like this (trimmed down):
1689N/A
1121N/A #include <isc/result.h>
1121N/A #include <isc/log.h>
1121N/A #include <dns/log.h>
1121N/A
1121N/A isc_logcategory_t dns_categories[] = {
1121N/A { "dns_general", 0 },
1121N/A { "dns_database", 0 },
1121N/A { "dns_security", 0 },
1121N/A { NULL, 0 }
1177N/A };
1121N/A isc_logmodule_t dns_modules[] = {
1121N/A { "db", 0 },
1121N/A { "rbtdb", 0 },
1121N/A { NULL, 0 }
1121N/A };
5086N/A
1121N/A isc_log_t *dns_lctx;
1121N/A
1121N/A dns_result_t
1121N/A dns_log_init(isc_log_t *lctx) {
1121N/A isc_result_t result;
1121N/A
5086N/A REQUIRE(dns_lctx == NULL);
1121N/A
2811N/A result = isc_log_registercategories(lctx, dns_categories);
2811N/A
2811N/A if (result == ISC_R_SUCCESS) {
2811N/A isc_log_registermodules(lctx, dns_modules);
2811N/A dns_lctx = lctx;
2832N/A }
5086N/A
5086N/A return (result);
5086N/A }
5855N/A
5855N/ANote that the init function is what associates that library's logging
5855N/Acontext with the one that the calling program must create and
5855N/Ainitialize. If the init function is never called, the library's
5855N/Alogging context will be NULL, so any calls by other library functions
5855N/Ato log messages will simply return with no message being written.
5855N/A
5855N/A3) Use the isc_log_write() function to have messages written according
5855N/Ato the definitions in the logging context. Its arguments are the
5855N/Alogging context, a category, a module, a logging level, a printf(3)
5855N/Aformat string, and any additional arguments that are necessary for the
5855N/Aformat string. For example:
5086N/A
5086N/A isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_RBT,
5086N/A ISC_LOG_CRITICAL, "%s",
5086N/A "Node %d in red-black tree is crimson!", node);
5855N/A
5855N/ANo newline should be included, nor should the program name. Usually
5855N/Athe source file name or the function name should not be included
5855N/Aeither, since location information can be attained, if desired, with
5855N/AISC_LOG_PRINTMODULE. On rare occasion it might be necessary to
5855N/Adifferentiate very similar messages in the same module.
5855N/A
5855N/AWhen available, include standard library return codes via %s in the
5855N/Aformat string, with strerrr(errno) from the system libary or functions
5855N/Alike isc_result_totext(result) and dns_result_totext(result).
5855N/A
5855N/ATHINGS I AM NOT KEEN ABOUT
5855N/A
5855N/AI am not happy that using a null channel for a category/module pair
5086N/Ahas no effect on other associations with that pair. It seems to me
5086N/Athat it would be nice to say "send all DATABASE category messages to
5086N/Asyslog, except for those from the RBT base code." I am not sure of
5086N/Ahow I want it specified though. One way to do it is to simply say
5086N/Athat null overrides any previously defined matches for the
5086N/Acategory/module, so that internally when walking down the channel
5086N/Alist, the first category/module match to a null channel stops
5086N/Aprocessing.
5086N/A