##
##  OSSP l2 - Flexible Logging
##  Copyright (c) 2001-2003 Cable & Wireless Deutschland GmbH
##  Copyright (c) 2001-2003 The OSSP Project (http://www.ossp.org/)
##  Copyright (c) 2001-2003 Ralf S. Engelschall <rse@engelschall.com>
##
##  This file is part of OSSP l2, a flexible logging library which
##  can be found at http://www.ossp.org/pkg/lib/l2/.
##
##  Permission to use, copy, modify, and distribute this software for
##  any purpose with or without fee is hereby granted, provided that
##  the above copyright notice and this permission notice appear in all
##  copies.
##
##  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
##  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
##  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
##  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
##  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
##  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
##  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
##  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
##  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
##  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
##  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
##  SUCH DAMAGE.
##
##  l2.pod: Unix manual page for C API
##

=pod

=head1 NAME

B<OSSP l2> - Flexible Logging

=head1 VERSION

OSSP l2 L2_VERSION_STR

=head1 SYNOPSIS

...

=head1 DESCRIPTION

B<OSSP l2> is a C library providing a very flexible and sophisticated
Unix logging facility. It is based on the model of arbitrary number of
channels, stacked together in a top-down data flow tree structure with
filtering channels in internal nodes and output channels on the leave
nodes.

Channel trees can be either constructed manually through lower-level
API functions or all at once with a single API function controlled by
a compact syntactical description of the channel tree. For generating
log messages a printf-style formatting engine is provided which can be
extended through callback functions. The data flow inside the channel
tree is controlled by (eight fixed and nine custom) logging message
severity levels which are assigned to each individual channel.

Channels are implemented by channel handlers which can be even
customer supplied for creating own channels which seamlessly integrate
into the framework. For convenience reasons, B<OSSP l2> already ships with
pre-implemented filtering (noop, filter, prefix, buffer) and output
(null, fd, file, pipe, socket, syslog, smtp) channels which already
cover mostly all use cases of logging.

A language is provided to allow for channel specification and configuration.
Thus, the channel tree can be constructed either by the API and its ANSI C
bindings or through the use of this B<OSSP l2> channel definition language. Applying
the API allows fine grained control of the channel tree. Additionally, the
API allows for a more interactive channel definition. However, using the
channel definition language to define the channel tree is more convenient,
and takes less coding effort. The channel definition language is almost
always sufficient for an application using B<OSSP l2>.

=head1 LOGGING LEVELS

PANIC    fatal error -> immediate abort (SIGBUS, SIGSEGV)
CRITICAL temporary failure -> sleep, retry possible (malloc == NULL)
ERROR    functionality error
WARNING  functionality successful
NOTICE   operation, statistics, start/stop
--- border line production/testing ---
INFO     step-by-step
TRACE    I/O tracing
--- border line end-user/developer
DEBUG    debugging messages

=head1 CHANNEL TREE SPECIFICATION

An B<OSSP l2> channel tree can be descriped by a textual specification according
to the following Backus-Naur-Form (BNF):

 tree               ::= stream
 stream             ::= channel
                      | channel "->" stream
                      | channel "->" "{" streams "}"
 streams            ::= stream
                      | stream ";" streams
 channel            ::= channel_level "/" channel_level ":" channel_cons
                      | channel_level ":" channel_cons
                      | channel_cons
 channel_level      ::= IDENTIFIER
                      | "(" channel_level_mask ")"
 channel_level_mask ::= IDENTIFIER
                      | IDENTIFIER "|" channel_level_mask
 channel_cons       ::= IDENTIFIER channel_params
 channel_params     ::= EMPTY
                      | "(" channel_param_list ")"
 channel_param_list ::= EMPTY
                      | channel_param
                      | channel_param "," channel_param_list
 channel_param      ::= IDENTIFIER "=" PARAMETER

An example of such a channel tree specification is:

 noop -> {
   debug: prefix(prefix="[%d-%m-%Y/%H:%M:%S] ")
      -> buffer(size=16384)
         -> file(path=foo.log, trunc=0);
   error: syslog(ident=foo, facility=user,
                 remotehost=syslog.example.com,
                 target=remote);
   panic: smtp(host=mail.example.com,
               rcpt=foo@example.com);
 }

=head1 FUNCTIONS

The following functions are provided by the B<OSSP l2> API:

=head1 AVAILABLE CHANNEL HANDLERS

=head2 Syslog Output Channel Handler (l2_handler_syslog)

The Syslog output channel handler C<l2_handler_syslog> sends the
incoming message either via syslog(3) to a local syslogd(8) or via BSD
Syslog protocol to a remote Syslog service. It conforms to RFC 3164 (The
BSD syslog Protocol; C. Lonvick; August 2001).

It provides the following channel parameters:

=over 4

=item B<target> (optional, C<char *>)

Sets the location of the target Syslog service. Possible values
are C<local> (the default) or C<remote>. If C<remote> is used, the
parameters C<remotehost> has to be set, too.

=item B<remotehost> (optional, C<char *>)

Host name or IP address of the remote Syslog service.
No default exists, user has to provide value.

=item B<remoteport> (optional, C<int>)

Port number of the remote SMTP service.
Default is C<514>.

=item B<localhost> (optional, C<char *>)

The name of the local host, I<without> any domain appended.

=item B<facility> (optional, C<char *>)

The Syslog facility used for all messages. It has to be one of the
following: C<kern>, C<user>, C<mail>, C<daemon>, C<auth>, C<syslog>,
C<lpr>, C<news>, C<uucp>, C<cron>, C<authpriv>, C<ftp>, C<ntp>,
C<security>, C<console>, C<clock>, C<local0>, C<local1>, C<local2>,
C<local3>, C<local4>, C<local5>, C<local6>, C<local7>.

=item B<ident> (I<mandatory>, C<char *>)

Arbitrary string identifying the program.
There is no default, user has to provide value.

=item B<logpid> (optional, C<int>)

Boolean flag whether to add the Process ID (pid)
to the B<ident> tag in messages. Default is C<0>.

=back

=head2 Pipe Output Channel Handler (l2_handler_pipe)

The Pipe output channel handler C<l2_handler_pipe> sends the incoming
message to the standard input of a chosen command, passed to the l2
library as a parameter when calling l2_configure.

Any command that operates on the standard input (c language descriptor
stdin) can be used, but attention is advised due to the wide
variety of commands and their particular exit behaviours.

Attention! Commands that exit on their own and with a success return value will
not be restarted, however those returning with non-zero exit codes will be
restarted. B<OSSP l2> reopens closed pipe channels due to faulted command processes in
this way. Should such a reconnection be required after a command's successful
self-termination, l2_channel_open() may be called again on the same pipe channel
pointer previously used. Stream logging will then write to the pipe channel
handler, which will forward the log messages to the given command as always. To
find out if a pipe channel has closed due to the behaviour of its command
process, the l2_channel_write() operation may be called on it with a non-NULL
message parameter, and 0 as the buffsize parameter. The return result will be
L2_OK if the channel is open. Using the C language, such a check might look
like:

TODO NOTE FROM MICHAEL: This info will change once the pipe channel handler is
redesigned to allow for proper process termination, signal handling of such
processes, and subsequent channel closing!!!!!!!!!!!

    if (l2_channel_write(pPipechannel, L2_LEVEL_NOTICE, "", 0) != L2_OK)
        if (l2_channel_open(pPipechannel) != L2_OK)
            exit(1); /* failure */

The command passed to the pipe channel handler may also be stopped while still
using a B<OSSP l2> stream log. If a command process is stopped no action is taken
until further logging occurs. As soon as the pipe channel handler receives a
message due to a l2_stream_log operation, it will attempt to restart the
stopped command process and write to its standard input. If the effort to
restart the command process fails then the command process is considered
dead, and B<OSSP l2> will terminate the process and close the channel. A
l2_channel_open() will then reopen the pipe channel using configuration
information previously entered with l2_channel_configure().

It provides the following channel parameters:

=over 4

=item B<command> (optional, C<char *>)

B<OSSP l2> will execute the command at this user-provided path, and pipe messages to
its standard input when l2_stream_log operations are called.

=back

=head2 SMTP Output Channel Handler (l2_handler_smtp)

The SMTP output channel handler C<l2_handler_smtp> sends the incoming
message via Simple Mail Transfer Protocol (SMTP) as an Email to a remote
mail service. It conforms to RFC 2821 (Simple Mail Transfer Protocol; J.
Klensin; April 2001) and RFC 2822 (Internet Message Format; P. Resnick;
April 2001).

It provides the following channel parameters:

=over 4

=item B<progname> (optional, C<char *>)

Arbitrary string identifying the program using B<OSSP l2>.
Default is C<NULL> which means no program identification.

=item B<localhost> (optional, C<char *>)

Hostname of the underlying machine.
Default is set through uname(3) or C<localhost>.

=item B<localuser> (optional, C<char *>)

Username corresponding to the UID of the underlying process.
Default is set through resolving getuid(2) or C<uid#N>.

=item B<from> (optional, C<char *>)

Sender Email address for outgoing mails.
Default is set through B<localuser> and B<localhost>.

=item B<rcpt> (I<mandatory>, C<char *>)

Recipient Email address for outgoing mails.
No default exists, user has to provide value.

=item B<subject> (optional, C<char *>)

Arbitrary string identifying the generated Email message.
Default is C<[L2] log channel output on {localhost}>.

=item B<host> (I<mandatory>, C<char *>)

Host name or IP address of the remote SMTP service.
No default exists, user has to provide value.

=item B<port> (optional, C<char *>)

Port name or number of the remote SMTP service.
Default is C<smtp> (25).

=item B<timeout> (optional, C<int>)

Timeout in seconds for all I/O operations.
Default is C<30>.

=back

=cut

