PDEL Library (libpdel, -lpdel)
#include
<sys/types.h>
#include <netinet/in.h>
#include
<pdel/structs/structs.h>
#include
<pdel/structs/type/array.h>
#include <pdel/sys/alog.h>
int
alog_configure
(int
channel, const struct
alog_config *conf);
int
alog_shutdown
(int
channel);
int
alog_set_channel
(int
channel);
void
alog
(int
sev, const char
*fmt, ...);
void
valog
(int
sev, const char
*fmt, va_list
args);
int
alog_get_history
(int
channel, int
min_severity, int
max_entries, time_t
max_age, const regex_t
*preg, struct
alog_history *list);
int
alog_clear_history
(int
channel);
int
alog_facility
(const
char *name);
const char *
alog_facility_name
(int
facility);
int
alog_severity
(const
char *name);
const char *
alog_severity_name
(int
severity);
void
alog_set_debug
(int
channel, int
enabled);
void
alog_expand
(const
char *fmt, int
errnum, char *buf,
size_t bufsize);
extern const struct structs_type
alog_facility_type;
extern const struct structs_type alog_severity_type;
extern const struct structs_type alog_config_type;
extern const struct structs_type alog_history_type;
These functions provide support for storing and retrieving log
messages. Up to ALOG_MAX_CHANNELS
independent log
channels are supported. Log entries may be printed to standard error, stored
in a searchable circular log history file, and sent to a local or remote
syslog(3)
server.
alog_configure
()
configures a log channel; channel must be between zero
and ALOG_MAX_CHANNELS - 1
, inclusive. The channel's
configuration is pointed to by conf, which is a
pointer to a struct alog_config
:
struct alog_config {
const char *path; /* logfile filename, or NULL */
const char *name; /* syslog id, or NULL to disable */
const char *facility; /* syslog facility, NULL=stderr */
struct in_addr remote_server; /* remote server, or 0.0.0.0 local */
int min_severity; /* min severity to actually log */
int histlen; /* how much history to save */
};
If path is not NULL
it specifies the pathname of a circular
logfile(3)
used to store log entries, and histlen specifies the
maximum number of entries to store in the file.
If facility is
NULL
, log messages will be sent to standard error.
Otherwise, if name is not
NULL
,
syslog(3)
logging is performed: name is the
syslog(3)
identifier, remote_server specifies the IP address of
a remote
syslog(3)
server to send log entries to (or 0.0.0.0
for the
local
syslogd(8)
listening on /var/run/log), and
facility specifies a
syslog(3)
facility, which must be a valid facility name as returned by
alog_facility_name
()
(see below), e.g., "daemon". If name is
NULL
, log messages are not output at all (but will
still be stored in the log file).
min_severity specifies a minimum
syslog(3)
severity level (actually a maximum, numerically speaking) for logged
entries; less severe entries are filtered out.
After a channel has been configured
successfully via
alog_configure
(),
access to that channel via alog
(),
valog
(), alog_get_history
(),
and alog_clear_history
() by multiple threads is
safe.
alog_shutdown
()
shuts down an alog channel, returning it to its
uninitialized, thread-unsafe state. Logging to an uninitialized channel is
permitted; the output is written to standard error. This allows applications
to log errors before they've configured alog
.
alog_set_channel
()
sets the log channel for newly logged messages. This setting persists until
another call to alog_set_channel
(). A separate
"current channel" variable is kept for each thread.
alog
()
and
valog
()
log a message. sev is a
syslog(3)
severity level such as LOG_ERROR
. The message is
formatted using fmt as a
printf(3)
like format string. As a special case, "%m" is replaced with
strerror
(errno). The value of
errno is not modified by these functions. Note that
when a channel is configured to log to syslog or standard error, these
functions become thread cancellation points.
alog_get_history
()
retrieves previously logged entries from the circular log file associated
with channel channel. Only entries with severity
greater than min_severity are returned; only entries
logged no earlier than max_age seconds ago are
returned; if preg is not NULL
,
log entries not matching the regular expression are filtered out; and
finally, at most max_entries total entries are
returned.
The returned entries are described by an array of pointers to
struct alog_entry
:
struct alog_entry {
time_t when; /* when event was logged */
int sev; /* entry log severity */
char msg[0]; /* entry contents (including '\0') */
};
DEFINE_STRUCTS_ARRAY(alog_history, struct alog_entry *);
This array is stored in *list, which will
then contain a data structure with
structs(3)
type alog_history_type and which must eventually be
freed by the caller via
structs_free(3).
alog_clear_history
()
resets a log history file to empty.
alog_facility
()
takes a
syslog(3)
facility name and returns its numeric value.
alog_facility_name
()
returns the
syslog(3)
facility name for facility.
alog_severity
()
takes a
syslog(3)
severity name and returns its numeric value.
alog_severity_name
()
returns the
syslog(3)
severity name for severity.
alog_expand
()
expands the last occurence of "%m" (if any) in the string
fmt into
strerror
(errnum)
and writes the result into the buffer pointed to by
buf, which has size bufsize.
alog_set_debug
()
causes the next call to alog_configure
() to act as
if facility were equal to
NULL
.
The following
structs(3)
types are pre-defined:
- alog_facility_type
-
Same as
structs_type_string(3)
but may only take values that are valid
syslog(3)
facility names. The default value is “daemon.”
- alog_severity_type
-
Same as
structs_type_int(3)
but the ASCII representation is the severity name from
alog_severity_name
()
instead of a number.
- alog_config_type
-
Describes a struct alog_config
.
- alog_history_type
-
Describes a struct
alog_history
, which is a
structs(3)
array of struct alog_entry *
pointers. This type
is used for accessing and freeing the log history returned by
alog_get_history
().
The above functions return -1 or NULL
to
indicate an error, setting errno accordingly.
The PDEL library was developed at Packet Design, LLC.
http://www.packetdesign.com/
Archie Cobbs
⟨archie@freebsd.org⟩
If multiple channels are configured to write to local syslog,
messages can get written with the wrong identifier or facility. This is an
unavoidable consequence of the implementation of
openlog(3)
and
syslog(3),
which doesn't support threading.