log_open_stream, log_close_stream, log_get_stream, log_get_filename,
log_vwrite, log_write, log_new_context, log_free_context,
log_add_channel, log_remove_channel, log_option, log_category_is_active,
log_new_syslog_channel, log_new_file_channel, log_set_file_owner,
log_new_null_channel, log_inc_references, log_dec_references,
log_free_channel -- logging system
#include <isc/logging.h>
FILE *
log_open_stream(log_channel chan);
int
log_close_stream(log_channel chan);
FILE *
log_get_stream(log_channel chan);
char *
log_get_filename(log_channel chan);
void
log_vwrite(log_context lc, int category, int level, const char *format,
va_list, args");
void
log_write(log_context lc, int category, int level, const char *format,
...);
int
log_check_channel(log_context lc, int level, log_channel chan);
int
log_check(log_context lc, int category, int level);
int
log_new_context(int num_categories, char **category_names,
log_context *lc);
void
log_free_context(log_context lc);
int
log_add_channel(log_context lc, int category, log_channel chan);
int
log_remove_channel(log_context lc, int category, log_channel chan);
int
log_option(log_context lc, int option, int value);
int
log_category_is_active(log_context lc, int category);
log_channel
log_new_syslog_channel(unsigned int flags, int level, int facility);
log_channel
log_new_file_channel(unsigned int flags, int level, char *name,
FILE *stream, unsigned int versions, unsigned long max_size);
int
log_set_file_owner(log_channel chan, uid_t owner, gid_t group);
log_channel
log_new_null_channel(void);
int
log_inc_references(log_channel chan);
int
log_dec_references(log_channel chan);
int
log_free_channel(log_channel chan);
The ISC logging library is flexible logging system which is based upon a
set of concepts: logging channels, categories, and logging contexts.
The basic building block is the ``logging channel'', which includes a
priority (logging level), which type of logging is to occur, and other
flags and information associated with technical aspects of the logging.
The set of priorities which are supported is shown below, in the section
Message Priorities. A priority sets a threshold for message logging; a
logging channel will only log those messages which are at least as
important as its priority indicates. (The fact that ``more important''
means ``more negative'', under the current scheme, is an implementation
detail; if a channel has a priority of log_error, then it will not log
messages with the log_warning priority, but it will log messages with the
log_error or log_critical priority.)
The logging channel also has an indication of the type of logging performed.
Currently, the supported logging types include (see also Logging
Types, below):
log_syslog for syslog(3)-style logging
log_file for use of a file
log_null for no logging
A new logging channel is created by calling either
log_new_syslog_channel(), log_new_file_channel(), or
log_new_null_channel(), respectively. When a channel is no longer to be
used, it can be freed using log_free_channel().
Both log_syslog and log_file channel types can include more information;
for instance, a log_syslog-type channel allows the specification of a
syslog(3)-style ``facility'', and a log_file-type channels allows the
caller to set a maximum file size and number of versions. (See
log_new_syslog_channel() or log_new_file_channel(), below.) Additionally,
once a logging channel of type log_file is defined, the functions
log_open_stream() and log_close_stream() can open or close the stream
associated with the logging channel's logging filename. The
log_get_stream() and log_get_filename() functions return the stream or
filename, respectively, of such a logging channel. Also unique to logging
channels of type log_file is the log_set_file_owner() function,
which tells the logging system what user and group ought to own newly
created files (which is only effective if the caller is privileged.)
Callers provide ``categories'', determining both the number of such categories
and any (optional) names. Categories are like array indexes in C;
if the caller declares ``n'' categories, then they are considered to run
from 0 to n-1; with this scheme, a category number would be invalid if it
were negative or greater than/equal to n. Each category can have its own
list of logging channels associated with it; we say that such a channel
is ``in'' the particular category. NOTE: Individual logging channels can
appear in more than one category.
A ``logging context'' is the set of all logging channels associated with
the context's categories; thus, a particular category scheme is associated
with a particular logging context. NOTE: A logging channel may
appear in more than one logging context, and in multiple categories
within each logging context.
Use log_add_channel() and log_remove_channel() to add or remove a logging
channel to some category in a logging context. To see if a given category
in a logging context is being used, use the Boolean test
log_category_is_active().
A logging context can also have a priority (logging level) and various
flags associated with the whole context; in order to alter the flags or
change the priority of a context, use log_option().
Message Priorities [Toc] [Back]
Currently, five priorities (logging levels) are supported (they can also
be found in the header file):
#define log_critical (-5)
#define log_error (-4)
#define log_warning (-3)
#define log_notice (-2)
#define log_info (-1)
In the current implementation, logging messages which have a level
greater than 0 are considered to be debugging messages.
Logging Types [Toc] [Back]
The three different logging types currently supported are different values
of the enumerated type log_output_type (these are also listed in the
header file):
typedef enum { log_syslog, log_file, log_null } log_output_type;
Logging Channel Flags [Toc] [Back]
There are several flags which can be set on a logging channel; the flags
and their meanings are as follows (they are also found in the header
file):
LOG_CHANNEL_BROKEN This is set only when some portion of
log_open_stream() fails: open(2) or
fdopen(3) fail; stat(2) fails in a ``bad''
way; versioning or truncation is requested
on a non-normal file.
LOG_CHANNEL_OFF This is set for channels opened by
log_new_null_channel().
LOG_CLOSE_STREAM If this flag is set, then
log_free_channel() will free a non- NULL
stream of a logging channel which is being
free(3)-d (if the logging channel is of
type log_file, of course).
LOG_PRINT_CATEGORY If set, log_vwrite() will insert the category
name, if available, into logging messages
which are logged to channels of type
log_syslog or log_file.
LOG_PRINT_LEVEL If set, log_vwrite() will insert a string
identifying the message priority level
into the information logged to channels of
type log_syslog or log_file.
LOG_REQUIRE_DEBUG Only log debugging messages (i.e., those
with a priority greater than zero).
LOG_TIMESTAMP If set, log_vwrite() will insert a timestamp
into logging messages which are
logged to channels of type log_syslog or
log_file.
LOG_TRUNCATE Truncate logging file when re-opened
(log_open_stream() will unlink(2) the file
and then open(2) a new file of the same
name with the O_EXCL bit set).
LOG_USE_CONTEXT_LEVEL Use the logging context's priority or logging
level, rather than the logging channel's
own priority. This can be useful
for those channels which are included in
multiple logging contexts.
FUNCTION DESCRIPTIONS [Toc] [Back]
The function log_open_stream() is for use with channels which log to a
file; i.e., logging channels with a type field set to ``log_file''. If
the logging channel pointed to by ``chan'' is valid, it attempts to open
(and return) the stream associated with that channel. If the stream is
already opened, then it is returned; otherwise, stat(2) is used to test
the filename for the stream.
At this point, if the logging file is supposed to have different versions
(i.e., incremented version numbers; higher numbers indicate older versions
of the logging file). If so, then any existing versions are
rename(2)-d to have one version-number higher than previously, and the
``current'' filename for the stream is set to the ``.0'' form of the
name. Next, if the logging file is supposed to be truncated (i.e., the
LOG_TRUNCATE bit of the flags field of the logging channel structure is
set), then any file with the ``current'' filename for the stream is
unlink(2)-d. NOTE: If the logging file is not a regular file, and either
of the above operations (version numbering or truncation) is supposed to
take place, a NULL file pointer is returned.
Finally, the filename associated with the logging channel is open(2)-d
using the appropriate flags and a mode which sets the read/write permissions
for the user, group, and others. The file descriptor returned by
open(2) is then passed to fopen(3), with the append mode set, and the
stream returned by this call is stored in the chan structure and
returned.
If log_open_stream() fails at any point, then the LOG_CHANNEL_BROKEN bit
of the flags field of the logging channel pointed to by chan is set, a
NULL is returned, and errno contains pertinent information.
The log_close_stream() function closes the stream associated with the
logging channel pointed to by ``chan'' (if chan is valid and the stream
exists and can be closed properly by fclose(3)). The stream is set to
NULL even if the call to fclose(3) fails.
The function log_get_stream() returns the stream associated with the logging
channel pointed to by ``chan'', if it is non-NULL and specifies a
logging channel which has a FILE * or stream associated with it.
The log_get_filename() function returns the name of the file associated
with the logging channel pointed to by ``chan'', if it is non-NULL and
specifies a logging channel which has a file associated with it.
The log_vwrite() function performs the actual logging of a message to the
various logging channels of a logging context lc. The message consists
of an fprint(3)-style format and its associated args (if any); it will be
written to all logging channels in the given category which have a priority
set to level or any less important priority value. If the category
is not valid or has no logging channels, then the category defaults to 0.
There are a number of conditions under which a call to log_vwrite() will
not result in actually logging the message: if there is no logging channel
at even the default category (0), or if a given channel is either
``broken'' or ``off'' (i.e., its flags have LOG_CHANNEL_BROKEN or
LOG_CHANNEL_OFF set, respectively), or if the logging channel channel is
of type log_null. Additionally, if the logging channel's flag has
LOG_REQUIRE_DEBUG set and the message is not a debugging message (i.e.,
has a level greater than 0), then it will not be logged. Finally, if the
message's priority is less important than the channel's logging level
(the priority threshold), will not be logged. NOTE: If a logging channel's
flag has LOG_USE_CONTEXT_LEVEL set, it will use the logging context's
priority, rather than its own.
If all of these hurdles are passed, then only log_syslog and log_file
channels actually can have logging. For channels which use syslog(3),
the channel's syslog(3) facility is used in conjunction with a potentially
modified form of the message's priority level, since syslog(3) has
its own system of priorities (/usr/include/syslog.h). All debug messages
(priority >= 0) are mapped to syslog(3)'s LOG_DEBUG priority, all messages
``more important'' than log_critical are mapped to LOG_CRIT, and
the priorities corresponding to the ones listed in the section Message
Priorities are given the obvious corresponding syslog(3) priority.
For log_file type logging channels, if the file size is greater than the
maximum file size, then no logging occurs. (The same thing happens if a
NULL stream is encountered and log_open_stream() fails to open the channel's
stream.)
For both logging to normal files and logging via syslog(3), the value of
the flags LOG_TIMESTAMP, LOG_PRINT_CATEGORY, and LOG_PRINT_LEVEL are used
in determining whether or not these items are included in the logged
information.
The log_write() function is merely a front-end to a call to log_vwrite();
see the description of that function, above, for more information.
log_check() and log_check_channel() are used to see if a contemplated
logging call will actually generate any output, which is useful when creating
a log message involves non-trivial work. log_check() will return
non-zero if a call to log_vwrite() with the given category and level
would generate output on any channels, and zero otherwise.
log_check_channel() will return non-zero if writing to the chan at the
given level would generate output.
The function log_new_context() creates a new logging context, and stores
this in the ``opaque'' field of the argument ``lc'', and opaque structure
used internally. This new context will include the ``num_categories''
and ``category_names'' which are supplied; the latter can be NULL. NOTE:
Since ``category_names'' is used directly, it must not be freed by the
caller, if it is non-NULL. The initial logging flags and priority are
both set to zero.
The log_free_context() function is used to free the opaque structure
``lc.opaque'' and its components. NOTE: The ``opaque'' field of ``lc''
must be non-NULL. For each of the various ``categories'' (indicated by
the ``num_categories'' which were in the corresponding call to
log_new_context()) associated with the given logging context, all of the
logging channels are free(3)-d. The opaque structure itself is then
free(3)-d, and ``lc.opaque'' is set to NULL.
NOTE: The function log_free_context() does not free the memory associated
with category_names, since the logging library did not allocate the memory
for it, originally; it was supplied in the call to log_new_context().
The function log_add_channel() adds the logging channel ``chan'' to the
list of logging channels in the given category of the logging context
``lc''. No checking is performed to see whether or not chan is already
present in the given category, so multiple instances in a single category
can occur (but see log_remove_channel(), below).
The log_remove_channel() function removes all occurrences of the logging
channel ``chan'' from the list of logging channels in the given category
of the logging context ``lc''. It also attempts to free the channel by
calling log_free_channel() (see its description, below).
The log_option() function is used to change the option of the indicated
logging context lc to the given value. The option can be either
LOG_OPTION_LEVEL or LOG_OPTION_DEBUG; in the first case, the log context's
debugging level is reset to the indicated level. If the option is
LOG_OPTION_DEBUG, then a non-zero value results in setting the debug flag
of the logging context, while a zero value means that the debug flag is
reset.
The log_category_is_active() test returns a 1 if the given category of
the indicated logging context lc has at least one logging channel, and 0,
otherwise.
The functions log_new_syslog_channel(), log_new_file_channel(), and
log_new_null_channel() create a new channel of the type specified (thus,
the difference in arguments); the ``type'' field of the new ``struct
log_channel'' is always set to the appropriate value.
The log_new_syslog_channel() function malloc(3)-s a new struct
log_channel of type log_syslog, i.e., a logging channel which will use
syslog(3). The new structure is filled out with the ``flags'',
``level'', and ``facility'' which are given; the references field is initialized
to zero. See Logging Channel Flags and Message Priorities,
above, or the header file for information about acceptable values for
``flags'', and ``level''. The ``facility''. can be any valid syslog(3)
facility; see the appropriate system header file or manpage for more
information.
log_channel log_new_file_channel(unsigned int flags, int level, char
*name, FILE *stream, unsigned int versions, unsigned long max_size)
log_new_null_channel()
The functions log_inc_references() and log_dec_references() increment or
decrements, respectively, the references field of the logging channel
pointed to by ``chan'', if it is a valid channel (and if the references
field is strictly positive, in the case of log_dec_references()). These
functions are meant to track changes in the number of different clients
which refer to the given logging channel.
The log_free_channel() function frees the field of the logging channel
pointed to by ``chan'' if there are no more outstanding references to it.
If the channel uses a file, the stream is fclose(3)-d (if the
LOG_CLOSE_STREAM flag is set), and the filename, if non-NULL, is
free(3)-d before ``chan'' is free(3)-d.
log_open_stream() NULL is returned under any of several error
conditions: a) if ``chan'' is either NULL or a
non-log_file channel (errno is set to EINVAL);
b) if either versioning or truncation is
requested for a non-normal file (errno is set
to EINVAL); c) if any of stat(2), open(2), or
fdopen(3) fails (errno is set by the call which
failed). If some value other than NULL is
returned, then it is a valid logging stream
(either newly-opened or already-open).
log_close_stream() -1 if the stream associated with ``chan'' is
non-NULL and the call to fclose(3) fails. 0 if
successful or the logging channel pointed to by
``chan'' is invalid (i.e., NULL or not a logging
channel which has uses a file); in the
latter case, errno is set to EINVAL.
log_get_stream() NULL under the same conditions as those under
which log_close_stream(), above, returns 0
(including the setting of errno). Otherwise,
the stream associated with the logging channel
is returned.
log_get_filename() NULL under the same conditions as those under
which log_close_stream(), above, returns 0
(including the setting of errno). Otherwise,
the name of the file associated with the logging
channel is returned.
log_new_context() -1 if malloc(3) fails (with errno set to
ENOMEM). Otherwise, 0, with ``lc->opaque''
containing the new structures and information.
log_add_channel() -1 if a) either ``lc.opaque'' is NULL or
category is invalid (negative or greater than
or equal to lcp->num_categories), with errno
set to EINVAL; b) malloc(3) fails (with errno
set to ENOMEM). Otherwise, 0.
log_remove_channel() -1 if a) either ``lc.opaque'' is NULL or
category is invalid, as under failure condition
a) for log_add_channel(), above, including the
setting of errno; b) no channel numbered chan
is found in the logging context indicated by lc
(with errno set to ENOENT). Otherwise, 0.
log_option() -1 if a) ``lc.opaque'' is NULL, b) option specifies
an unknown logging option; in either
case, errno is set to EINVAL. Otherwise, 0.
log_category_is_active() -1 if ``lc.opaque'' is NULL (with errno set to
EINVAL); 1 if the category number is valid and
there are logging channels in this category
within the indicated logging context; 0 if the
category number is invalid or there are no logging
channels in this category within the indicated
logging context.
log_new_syslog_channel() NULL if malloc(3) fails (with errno set to
ENOMEM); otherwise, a valid log_syslog-type
log_channel.
log_new_file_channel() NULL if malloc(3) fails (with errno set to
ENOMEM); otherwise, a valid log_file-type
log_channel.
log_new_null_channel() NULL if malloc(3) fails (with errno set to
ENOMEM); otherwise, a valid log_null-type
log_channel.
log_inc_references() -1 if ``chan'' is NULL (with errno set to
EINVAL). Otherwise, 0.
log_dec_references() -1 if ``chan'' is NULL or its references field
is already <= 0 (with errno set to EINVAL).
Otherwise, 0.
log_free_channel() -1 under the same conditions as
log_dec_references(), above, including the setting
of errno; 0 otherwise.
isc/logging.h include file for logging library
syslog.h syslog(3)-style priorities
This table shows which functions can return the indicated error in the
errno variable; see the RETURN VALUES section, above, for more information.
EINVAL log_open_stream(), log_close_stream(),
log_get_stream(), log_get_filename(),
log_add_channel(), log_remove_channel(),
log_option(), log_category_is_active(),
log_inc_references(), log_dec_references(),
log_free_channel().
ENOENT log_remove_channel().
ENOMEM log_new_context(), log_add_channel(),
log_new_syslog_channel(), log_new_file_channel(),
log_new_null_channel().
(any other value) returned via a pass-through of an error code from
stat(2), open(2), or fdopen(3), which can occur in
log_open_stream() and functions which call it
(currently, only log_vwrite()).
Additionally, log_vwrite() and log_free_context() will fail via assert()
if ``lc.opaque'' is NULL. The function log_vwrite() can also exit with a
critical error logged via syslog(3) indicating a memory overrun
named(8), syslog(3). The HTML documentation includes a file,
logging.html, which has more information about this logging system.
Bob Halley...TODO
4th Berkeley Distribution January 1, 1996 4th Berkeley Distribution
[ Back ] |