logging revision 2aee8fb2cbb1d4b77ea05327340e839e26265ae9
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceThe ISC logging system is designed to provide a flexible, extensible
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencemethod of writing messages. Messages can be sent to the system's
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencelogging facility, directly to a file, or into the bitbucket, usually
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceconfigured per the desires of the users of the program. Each message
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceis associated with a particular category (eg, "security" or
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence"database") that reflects its nature, and a particular module (such as
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencethe library's source file) that reflects its origin. Messages are
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencealso each assigned a priority level which states how remarkable the
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencemessage is, so that too can be configured by the program's user to
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencecontrol how much detail is desired.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceLibraries which use the ISC logging system can be linked against each
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceother without fear of conflict. A program is able to select which, if
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceany, libraries will write log messages.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceThis section describes the basics of how the system works, introduces
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceterms and defines C preprocessor symbols used in conjuction with
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencelogging functions. Actual uses of functions are demonstrated in the
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencefollowing two sections.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceLog messages are associated with three pieces of information that are
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceused to determine their disposition: a category, a module, and a
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencelevel (aka "priority").
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceA category describes the conceptual nature of the message, that is,
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencewhat general aspect of the code it is concerned with. For example,
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencethe DNS library defines categories that include the workings of the
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencedatabase as well security issues. Macros for naming categories are
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencetypically provided in the library's log header file, such as
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceDNS_LOGCATEGORY_DATABASE and DNS_LOGCATEGORY_SECURITY in <dns/log.h>
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencefor the two categories in the previous sentence. The special category
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceISC_LOGCATEGORY_DEFAULT is associated with any message that does not
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencematch a particular category (or matches a category but not a module,
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceas seen in the next paragraph).
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceA module is loosely the origin of a message. Though there not be a
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceone-to-one correspondence of source files with modules, it is typical
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencethat a module's name reflect the source file in which it is used. So,
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencefor example, the module identifier DNS_LOGMODULE_RBT would be used by
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencemessages coming from within the dns/rbt.c source file.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceThe specification of the combination of a category and a module for a
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencemessage are called the message's "category/module pair".
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceThe level of a message is an indication of its severity. There are
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencesix standard logging levels, in order here from most to least severe
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence(least to most common):
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence ISC_LOG_CRITICAL -- An error so severe it causes the program to exit.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence ISC_LOG_ERROR -- A very notable error, but the program can go on.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence ISC_LOG_WARNING -- Something is probably not as it should be.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence ISC_LOG_NOTICE -- Notable events that occur while the program runs.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence ISC_LOG_INFO -- Statistics, typically.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence ISC_LOG_DEBUG(unsigned int level) -- detailed debugging messages.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceISC_LOG_DEBUG is not quite like the others in that it takes an
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceargument the defines roughly how detailed the message is; a higher
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencelevel means more copious detail, so that values near 0 would be used
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceat places like the entry to major sections of code, while greater
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencenumbers would be used inside loops.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceSo, ok, technically there are five + at least 4,294,967,296 levels.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrencePicky picky. In any event, the six levels correspond with similar
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencelevels used by Unix's syslog, and when messages using one of those
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencelevels is sent to syslog, the equivalent syslog level is used. (Note
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencethat this means that any debugging messages go to the singular
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceLOG_DEBUG priority in syslog, regardless of their level internal to
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencethe ISC logging system.)
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceThe next building block of the logging system is a channel. A channel
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencespecifies where a message of a particular priority level should go, as
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencewell as any special options for that destination. There are four
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencebasic destinations, as follows:
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence ISC_LOG_TOSYSLOG -- Send it to syslog.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence ISC_LOG_TOFILE -- Write to a file.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence ISC_LOG_TOFILEDESC -- Write to a (previously opened) file descriptor.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence ISC_LOG_TONULL -- Do not write the message when selected.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceA file destination names a path to a log file. It also specifies the
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencemaximum allowable byte size of the file before it is closed (where 0
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencemeans no limit) and the number of versions of a file to keep (where
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceISC_LOG_ROLLNEVER means the logging system never renames the log file,
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceand ISC_LOG_ROLLINFINITE means no cap on the number of versions).
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceVersion control is done just before a file is opened, so a program
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencethat used it would start with a fresh log file (unless using
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceISC_LOG_ROLLNEVER) each time it ran. If you want to use an external
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencerolling method, use ISC_LOG_ROLLNEVER and ensure that your program has
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencea mechanism for calling isc_log_closefilelogs().
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence(ISC_LOG_ROLLINFINITE is not truly infinite; it will stop at INT_MAX.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceOn 32 bit machines that means the logs would need to roll once per
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencesecond for more than sixty years before exhausting the version number
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceA file descriptor destination is simply associated with a previously
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceopened stdio file descriptor. This is mostly used for associating
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencestdout or stderr with log messages, but could also be used, for
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceexample, to send logging messages down a pipe that has been opened by
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencethe program. File descriptor destinations are never closed, have no
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencemaximum size limit, and do not do version control.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceSyslog destinations are associated with the standard syslog facilities
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceavailable on your system. They too have no maximum size limit and do
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceno version control.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceSince null channels go nowhere, no additional destination
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencespecification is necessary.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceThe words "destination" and "channel" can be used interchangably in
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencesome contexts. Referring to a file channel, for example, means a
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencechannel that has a file destination.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceChannels have string names that are their primary external reference.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceThere are four predefined logging channels:
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence "default_stderr" -- Descriptor channel to stderr at priority ISC_LOG_INFO
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence "default_debug" -- Descriptor channel to stderr at priority ISC_LOG_DYNAMIC
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence "default_syslog" -- Syslog channel to LOG_DAEMON at priority ISC_LOG_INFO
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence "null" -- Null channel
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceWhat's ISC_LOG_DYNAMIC? That's how you tell the logging system that
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceyou want debugging messages, but only at the current debugging level
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceof the program. The debugging level is controlled as described near
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencethe end of the next section. When the debugging level is 0 (turned
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceoff), then no debugging messages are written to the channel. If the
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencedebugging level is raised, only debugging messages up to its level are
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencewritten to the channel.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceYou can reuse a channel name. If you define a channel with the same
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencename as an existing channel, the new definition is used by all future
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencereferences to the name. The old definition is still used by anything
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencethat was pointing to the name before the redefinition. This even
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceapplies to redefinitions of the predefined channels, with one
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceexception: redefining default_stderr will change the default
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencedestination of messages, as explained in more detail in a few paragraphs.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceChannels can additionally have any of four options associated with
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencethem. The following options are listed in the order which their
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencecorresponding print strings appear in a log message:
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence ISC_LOG_PRINTTIME -- The date and time.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence ISC_LOG_PRINTCATEGORY -- The category name.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence ISC_LOG_PRINTMODULE -- The module name.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence ISC_LOG_PRINTLEVEL -- The level.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceSyslog channels do not need ISC_LOG_PRINTTIME, but it is usally a good
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceidea for file and file descriptor feeds.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceNow with these objects -- the category, module, and channel -- you can
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceactually direct messages to your desired destinations. As shown in
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencethe next section, you associate the category/module pair with a
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencechannel. It is possible to use one function call to say "all modules
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencecoupled with this category" and vice versa, but conceptually the
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencematching is still referred to as applying to category/module pairs,
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencesince that is what comes in from functions writing messages.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceSpeaking of functions writing messages, here's what happens when a
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencefunction wants to write a message through the logging system. First
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencethe function calls isc_log_write(), specifying a category, module and
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceIn isc_log_write(), the logging system first looks up a list that
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceconsists of all of the channels associated with a particular category.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceIt walks down the list looking for each channel that also has the
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceindicated module associated with it, and writes the message to each
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencechannel it encounters. If no match is found in the list for the
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencemodule, the default channel is used. Similarly, the default is used
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceif no channels have been specified for the category at all.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceWhat is the default? It is ISC_LOGCATEGORY_DEFAULT -- sort of. You
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencecan specify an association of the channel ISC_LOGCATEGORY_DEFAULT with
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceany particular module, or more usually all of them, and that's what
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencewill be used for any category/module pair for which you have not
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencespecified a channel. If you do not associate ISC_LOGCATGORY_DEFAULT
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceand the indicated module, then the internal default of using the
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencedefault_stderr channel is used. This brings us back to the statement
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencemade a few paragraphs ago about redefining the predefined channels --
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceif you redefine default_stderr, and a messages comes in for a
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencecategory/module pair that has had neither its original pair or
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencethe ISC_LOGCATEGORY_DEFAULT/module pair configured for it, then the
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencemessage will go to the _new_ definition of default_stderr.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceHere are some other ways to think about how category/module pairs get
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencematched with regard to using the defaults:
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence If a channel is is specified for a category as applying to all modules
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence which use that category, then the default channel will be used for no
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence combination of that category with any module.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence If a category is specified with one or more explicit modules, any
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence modules _not_ using that category still use the default.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceAs with the BIND 8 logging code, when a log message is not written
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencebecause the of the severity level of the channel, the default is _not_
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceused, because the category and module are considered to have matched.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceThe default is only used when a category/module pair has not been
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencespecified. If you want to use the default for some messages but also
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencesend higher (lower?) priority messages someplace else, then you will
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceneed to specify both the default channel and a custom channel for that
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceIt is important to note that specifying a null destination for a
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencecategory/module pair has no effect on any other destinations
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceassociated with that pair, regardless of ordering. For example,
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencethough it seems reasonable, you cannot say "for category A and all
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencemodules, log to stderr, but for category A and module 2 don't show any
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencemessages." You would need to specify stderr for category A with all
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencemodules except module 2, and then specify null for A/2. This could be
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceinconvenient, especially if you do not know all of the modules
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceassociated with a particular category but you know the one you want to
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceshut up. Because of this, it is likely that specifying a null
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencedestination _will_ block other channels that also specify a particular
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencecategory/module pair, but the exact mechanism has not yet been
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceNo attempt is made to filter out duplicate destinations, so it is
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencecertainly possible to define things such that a single log gets more
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencethan one copy of the same message. This may change in the future.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceFinally, here is a note about multiprocessing. The entire logging
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencecontext is pthread locked for most of duration of the isc_log_write.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceThat's it, that's the note.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceUSING LIBRARIES THAT USE THE LOGGING SYSTEM
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceTo enable the messages from a library that uses the logging system,
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencethe following steps need to be taken to initialize it.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence1) Include the main logging header file as well as the logging header
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencefile for any additional library you are using. For example, when
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceusing the DNS library, include the following:
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence2) Initialize a logging context. A logging context needs a valid
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencememory context in order to work, so the following code snippet shows a
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencerudimentary initialization of both.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence isc_mem_t *mctx;
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence isc_log_t *lctx;
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence if (isc_mem_create(0, 0, &mctx) != ISC_R_SUCCESS) ||
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence isc_log_create(mctx, &lctx) != ISC_R_SUCCESS))
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence oops_it_didnt_work();
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence3) Initalize any additional libraries. The convention for the name of
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencethe initialization function is {library}_log_init, with just a pointer
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceto the logging context as an argument. The function can only be
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencecalled once in a program or it will generate an assertion error.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence dns_log_init(lctx);
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceIf you do not want a library to write any log messages, simply do not
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencecall its the initialization function.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence4) Create any channels you want in addition to the internal channels
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceof default_syslog, default_stderr, default_debug and null. A
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencedestination structure needs to be filled for any destination other
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencethan null. The following examples show use of a file log, a file
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencedescriptor log, and syslog.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence isc_logdestination_t destination;
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence destination.file.maximum_size = 0; /* No byte limit. */
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence destination.file.versions = ISC_LOG_ROLLNEVER; /* External rolling. */
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence if (isc_log_createchannel(lctx, "sample1" ISC_LOG_TOFILE, ISC_LOG_DYNAMIC,
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence &destination, ISC_LOG_PRINTTIME) != ISC_R_SUCCESS)
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence oops_it_didnt_work();
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence if (isc_log_createchannel(lctx, "sample2" ISC_LOG_TOFILEDESC, ISC_LOG_INFO,
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence &destination, ISC_LOG_PRINTTIME) != ISC_R_SUCCESS)
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence oops_it_didnt_work();
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence if (isc_log_createchannel(lctx, "sample2" ISC_LOG_SYSLOG, ISC_LOG_ERROR,
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence &destination, 0) != ISC_R_SUCCESS)
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence oops_it_didnt_work();
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceNote that ISC_LOG_DYNAMIC is used to define a channel that wants any
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceof the messages up to the current debugging level of the program
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence(described below). ISC_LOG_DEBUG(level) can define a channel that
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence_always_ gets messages up to the debug level specified, regardless of
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencethe debugging state of the server.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceRemember that you can redefine these internal channels, and that in
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceparticular redefining default_stderr will change the default logging
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence5) Direct the various log categories and modules to the desired
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencedestination. This step is not necessary if the normal behavior of
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencesending all messages to default_stderr is acceptable. The following
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceexamples sends DNS security messages to stderr, DNS database messages
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceto null, and all other messages to syslog.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence if (isc_log_usechannel(lctx, "default_stderr", DNS_LOGCATEGORY_SECURITY,
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence NULL) != ISC_R_SUCCESS)
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence oops_it_didnt_work();
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence if (isc_log_usechannel(lctx, "null", DNS_LOGCATEGORY_DATABASE, NULL)
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence != ISC_R_SUCCESS)
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence oops_it_didnt_work();
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence if (isc_log_usechannel(lctx, "default_syslog", ISC_LOGCATEGORY_DEFAULT,
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence NULL) != ISC_R_SUCCESS)
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence oops_it_didnt_work();
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceProviding a NULL argument for the category means "associate the
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencechannel with the indicated module in all known categories" ---
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceincluding ISC_CATEGORY_DEFAULT. Providing a NULL argument for the
2aee8fb2cbb1d4b77ea05327340e839e26265ae9Andreas Gustafssonmodule means "associate the channel with all modules that use this
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence6) If you are sending any messages to syslog, call
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceisc_log_opensyslog(). Currently the arguments to this function are
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceexactly the same as to syslog's openlog() function, but it is expected
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencethat this will change. This is necessary
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence isc_log_opensyslog(NULL, LOG_PID, LOG_DAEMON);
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceNow the libraries used by your program will write messages according
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceto your specifications.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceThere are three additional functions you might find useful in your
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceprogram to control logging behavior, two to work with the debugging
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencelevel and one to control the closing of log files.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencevoid isc_log_setdebuglevel(isc_log_t *lctx, unsigned int level) and
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceunsigned int isc_log_getdebuglevel(isc_log_t *lctx) set and retrieve
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencethe current debugging level of the program. isc_log_getdebuglevel()
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencecan be used so that you need not keep track of the level yourself in
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceanother variable. One use for these functions would be in a daemon
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencethat could have its debugging level raised with a USR1 signal or lowered
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencewith a USR2 signal.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceThe void isc_log_closefilelogs(isc_log_t *lcxt) function closes any
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceopen log files. This is useful for programs that do not want to do
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencefile rotation as with the internal rolling mechanism. For example, a
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceprogram that wanted to keep daily logs would define a channel which
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceused ISC_LOG_ROLLNEVER, then once a day would rename the log file and
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencecall isc_log_closefilelogs(). The next time a message needs to be
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencewritten a file that has been closed, it is reopened.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceWRITING LIBRARIES THAT USE THE LOGGING SYSTEM
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceThis section describes how a new library, libfoo.a, would use the ISC
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencelogging system internally.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence1) Provide a header file that does the following:
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence * declares foo_lctx, a logging context that will be used throughout
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence * declares the structures that specify the categories and modules
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence known by the library.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence * defines the macros that provide convenient access to the library's
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence categories and modules.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence * prototypes the library's log initialization function.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence See <dns/log.h> for a sample.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence2) Write a C source module that includes the library's log.h,
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence provides storage for the library's logging context,
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence initializes the category and module structures, and defines the
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence initialization function, foo_log_init(). log.c from libdns.a looks
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence like this (trimmed down):
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence isc_logcategory_t dns_categories[] = {
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence { "dns_general: ", 0 },
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence { "dns_database: ", 0 },
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence { "dns_security: ", 0 },
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence isc_logmodule_t dns_modules[] = {
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence { "db: ", 0 },
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence { "rbtdb: ", 0 },
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence isc_log_t *dns_lctx;
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence dns_log_init(isc_log_t *lctx) {
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence isc_result_t result;
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence REQUIRE(dns_lctx == NULL);
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence result = isc_log_registercategories(lctx, dns_categories);
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence if (result == ISC_R_SUCCESS) {
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence isc_log_registermodules(lctx, dns_modules);
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence dns_lctx = lctx;
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence return (result);
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceNote that the init function is what associates that library's logging
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencecontext with the one that the calling program must create and
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceinitialize. If the init function is never called, the library's
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencelogging context will be NULL, so any calls by other library functions
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceto log messages will simply return with no message being written.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence3) Use the isc_log_write() function to have messages written according
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceto the definitions in the logging context. Its arguments are the
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencelogging context, a category, a module, a logging level, a printf(3)
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceformat string, and any additional arguments that are necessary for the
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceformat string. For example:
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_RBT,
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence ISC_LOG_CRITICAL, "%s",
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrence "Node %d in red-black tree is crimson!", node);
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceNo newline should be included, nor should the program name. Usually
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencethe source file name or the function name should not be included
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceeither, since location information can be attained, if desired, with
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceISC_LOG_PRINTMODULE. On rare occasion it might be necessary to
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencedifferentiate very similar messages in the same module.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceWhen available, include standard library return codes via %s in the
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceformat string, with strerrr(errno) from the system libary or functions
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencelike isc_result_totext(result) and dns_result_totext(result).
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceTHINGS I AM NOT KEEN ABOUT
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceThe category/module names passed into the registration functions need
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrenceto have a colon-space (": ") at the end of each name.
6ad14a42e1058dbf92a747b27538d22fe4d977f8David LawrenceI am not happy that using a null channel for a category/module pair
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencehas no effect on other associations with that pair. It seems to me
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencethat it would be nice to say "send all DATABASE category messages to
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencesyslog, except for those from the RBT base code." I am not sure of
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencehow I want it specified though. One way to do it is to simply say
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencethat null overrides any previously defined matches for the
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencecategory/module, so that internally when walking down the channel
6ad14a42e1058dbf92a747b27538d22fe4d977f8David Lawrencelist, the first category/module match to a null channel stops