NAME
Fugu::Log - logging to syslog, standard error, or nowhere
SYNOPSIS
use Fugu::Log;
my $log = Fugu::Log->new(
mode => 'syslog',
ident => 'mydaemon',
level => 'info',
facility => 'daemon',
);
$log->info('listening on port %d', $port);
$log->error('cannot open %s: %s', $path, $!);
Fugu::Log->set_default($log);
DESCRIPTION
Fugu::Log gives a program one logging interface. The interface is the same when the program runs as a daemon and when it runs in the foreground. The caller selects the destination one time, when it creates the logger. Every call site then has the same form for all destinations.
The logger discards messages below the configured level. The levels, from lowest to highest, are debug, info, notice, warning and error. Each level is a method of the same name, and there is one spelling for each level.
The module also holds one process default logger. Library code that gets no logger asks for it with default, so no library has to die for the lack of one.
new
new(%args) creates a logger. These are the arguments:
mode-
The destination for messages. The value is one of:
syslog-
Messages go through syslog(3). The logger pins the transport that
syslog_methodnames withsetlogsockfrom Sys::Syslog, and then calls openlog(3) immediately with thendelayandpidoptions.The pin keeps a pledged daemon alive. On OpenBSD the default
nativemechanism delivers with sendsyslog(2), which sits inside thestdiopromise. Every other mechanism opens a socket, and a daemon that pledgesstdiodies at that call. stderr-
Messages go to standard error, with one line for each message. Each line starts with a local-time stamp and the level in upper case.
quiet-
Messages go nowhere. The logger discards them before it does a check of the level.
The default is
stderr. level-
The lowest level to emit. The default is
info. ident-
The program name that the logger passes to openlog(3). The default is
fugu. The logger uses this argument only whenmodeissyslog. facility-
The syslog facility. The value is a Sys::Syslog constant, or one of the names
daemon,userorlocal0throughlocal7. The default isLOG_DAEMON. syslog_method-
The syslog transport. The value is one mechanism name, or an array reference of names in the order to try. The default is
native, which serves the pledged OpenBSD daemon. An empty array reference means no pin: the logger then never callssetlogsock, and Sys::Syslog keeps its own order.These are the names the logger accepts:
console,inet,native,pipe,stream,tcp,udpandunix. They are the mechanism names of Sys::Syslog. Theeventlogmechanism is not in the set, because it needs the Win32 API.The logger stores the value in every mode, and it uses the value in syslog mode alone.
identandfacilitybehave the same way.
debug, info, notice, warning, error
$log->info($fmt, @args);
Each method logs one message at the level that its name gives. When @args is not empty, the method formats $fmt through sprintf(3). When @args is empty, the method uses $fmt as a literal string.
There is one method for each level, and no other spelling parses.
set_level
set_level($level) changes the lowest level to emit on a logger after its creation. If the value is not a known level name, the logger uses info.
level
level returns the lowest level to emit, by name. The name is one of the six canonical levels, whatever spelling the caller used.
mode
mode returns the destination, one of the MODE_SYSLOG, MODE_STDERR and MODE_QUIET constants. The constants hold the strings syslog, stderr and quiet.
syslog_method
syslog_method returns the syslog transport as an array reference. The reference holds the mechanism names in the order the logger gives to setlogsock, so a caller can audit the choice. An empty reference reports that the logger pins nothing.
The accessor takes no argument. A caller must not change the transport of a logger that is already open: new and reopen are the two calls that talk to Sys::Syslog, and both read the stored value.
reopen
reopen closes and opens the log again with the same settings. A daemon calls this after it drops privileges: the syslog(3) connection belongs to the user that opened it. In the other modes the method does nothing.
In syslog mode the method pins the syslog_method transport again before it opens the connection. The transport list of Sys::Syslog is process-wide state, so a pin from the first open does not last.
This replaces the older pattern of discarding the logger and building an identical one. That pattern needed every call site to learn the new object.
default
default returns the process default logger. The first call creates a stderr logger, so the method never returns undef.
This is the fallback for library code. A module takes a log argument and uses default when the caller gives none. Thus no library dies for the lack of a logger, and no library needs a global of its own.
set_default
set_default($log) replaces the process default logger and returns the new default. A program calls this once at startup.
RETURN VALUES
new, default and set_default return a logger object. reopen returns the object. level and mode return a name. syslog_method returns an array reference. The logging methods and set_level have no useful return value.
EXAMPLES
This example logs to standard error in the foreground, and to syslog in the background, with no change to the call sites:
my $log = Fugu::Log->new(
mode => $foreground ? 'stderr' : 'syslog',
ident => 'mydaemon',
level => $verbose ? 'debug' : 'info',
);
Fugu::Log->set_default($log);
This example opens the syslog connection again as the unprivileged user:
Fugu::Privdrop->drop_privileges(user => '_myapp');
$log->reopen;
ERRORS
new dies if mode is not one of the three names above. It also dies for a syslog_method name outside the set above, in every mode: the logger validates the value once, at the boundary. An unknown level or facility is not an error. The level becomes info, and the facility becomes LOG_DAEMON.
In syslog mode, new and reopen die when setlogsock reports a failed pin. A failed setlogsock restores the default transport list, and that list holds mechanisms that open a socket. A pledged daemon with that list dies at its first log line, with SIGABRT and no diagnosis. A clear death at the open is the better outcome.
SEE ALSO
syslog(3), Fugu::Daemon, Sys::Syslog, syslog.conf(5)
AUTHORS
Dick Olsson <hi@senzilla.io>
CAVEATS
The logging methods pass the format string to sprintf(3) only when arguments follow it. Thus a message that has a percent sign is safe alone, but not when an argument follows. Log variable text with %s. Do not interpolate the text into the format string.
A process must create no more than one syslog-mode logger. openlog(3) and closelog(3) act on process-wide state. Thus, when a second logger goes out of scope, it closes the connection that the first logger still uses. Use reopen on the one logger instead of building a second one.
The native mechanism reports success in every case. The C library drops a message that it cannot deliver, and no error reaches the caller. A host with no working native transport therefore loses every log line, and the module cannot detect the loss. The syslog_method argument is the answer for such a host.