Team BBL
Previous Page Next Page

13.4. Error Logging

One problem a daemon has is how to handle error messages. It can't simply write to standard error, since it shouldn't have a controlling terminal. We don't want all the daemons writing to the console device, since on many workstations, the console device runs a windowing system. We also don't want each daemon writing its own error messages into a separate file. It would be a headache for anyone administering the system to keep up with which daemon writes to which log file and to check these files on a regular basis. A central daemon error-logging facility is required.

The BSD syslog facility was developed at Berkeley and used widely in 4.2BSD. Most systems derived from BSD support syslog.

Until SVR4, System V never had a central daemon logging facility.

The syslog function is included as an XSI extension in the Single UNIX Specification.

The BSD syslog facility has been widely used since 4.2BSD. Most daemons use this facility. Figure 13.2 illustrates its structure.

Figure 13.2. The BSD syslog facility


There are three ways to generate log messages:

  1. Kernel routines can call the log function. These messages can be read by any user process that opens and reads the /dev/klog device. We won't describe this function any further, since we're not interested in writing kernel routines.

  2. Most user processes (daemons) call the syslog(3) function to generate log messages. We describe its calling sequence later. This causes the message to be sent to the UNIX domain datagram socket /dev/log.

  3. A user process on this host, or on some other host that is connected to this host by a TCP/IP network, can send log messages to UDP port 514. Note that the syslog function never generates these UDP datagrams: they require explicit network programming by the process generating the log message.

Refer to Stevens, Fenner, and Rudoff [2004] for details on UNIX domain sockets and UDP sockets.

Normally, the syslogd daemon reads all three forms of log messages. On start-up, this daemon reads a configuration file, usually /etc/syslog.conf, which determines where different classes of messages are to be sent. For example, urgent messages can be sent to the system administrator (if logged in) and printed on the console, whereas warnings may be logged to a file.

Our interface to this facility is through the syslog function.

#include <syslog.h>

void openlog(const char *ident, int option, int
 facility);

void syslog(int priority, const char *format, ...);

void closelog(void);

int setlogmask(int maskpri);

Returns: previous log priority mask value


Calling openlog is optional. If it's not called, the first time syslog is called, openlog is called automatically. Calling closelog is also optionalit just closes the descriptor that was being used to communicate with the syslogd daemon.

Calling openlog lets us specify an ident that is added to each log message. This is normally the name of the program (cron, inetd, etc.). The option argument is a bitmask specifying various options. Figure 13.3 describes the available options, including a bullet in the XSI column if the option is included in the openlog definition in the Single UNIX Specification.

Figure 13.3. The option argument for openlog

option

XSI

Description

LOG_CONS

If the log message can't be sent to syslogd via the UNIX domain datagram, the message is written to the console instead.

LOG_NDELAY

Open the UNIX domain datagram socket to the syslogd daemon immediately; don't wait until the first message is logged. Normally, the socket is not opened until the first message is logged.

LOG_NOWAIT

Do not wait for child processes that might have been created in the process of logging the message. This prevents conflicts with applications that catch SIGCHLD, since the application might have retrieved the child's status by the time that syslog calls wait.

LOG_ODELAY

Delay the open of the connection to the syslogd daemon until the first message is logged.

LOG_PERROR

 

Write the log message to standard error in addition to sending it to syslogd. (Unavailable on Solaris.)

LOG_PID

Log the process ID with each message. This is intended for daemons that fork a child process to handle different requests (as compared to daemons, such as syslogd, that never call fork).


The facility argument for openlog is taken from Figure 13.4. Note that the Single UNIX Specification defines only a subset of the facility codes typically available on a given platform. The reason for the facility argument is to let the configuration file specify that messages from different facilities are to be handled differently. If we don't call openlog, or if we call it with a facility of 0, we can still specify the facility as part of the priority argument to syslog.

Figure 13.4. The facility argument for openlog

facility

XSI

Description

LOG_AUTH

 

authorization programs: login, su, getty, ...

LOG_AUTHPRIV

 

same as LOG_AUTH, but logged to file with restricted permissions

LOG_CRON

 

cron and at

LOG_DAEMON

 

system daemons: inetd, routed, ...

LOG_FTP

 

the FTP daemon (ftpd)

LOG_KERN

 

messages generated by the kernel

LOG_LOCAL0

reserved for local use

LOG_LOCAL1

reserved for local use

LOG_LOCAL2

reserved for local use

LOG_LOCAL3

reserved for local use

LOG_LOCAL4

reserved for local use

LOG_LOCAL5

reserved for local use

LOG_LOCAL6

reserved for local use

LOG_LOCAL7

reserved for local use

LOG_LPR

 

line printer system: lpd, lpc, ...

LOG_MAIL

 

the mail system

LOG_NEWS

 

the Usenet network news system

LOG_SYSLOG

 

the syslogd daemon itself

LOG_USER

messages from other user processes (default)

LOG_UUCP

 

the UUCP system


We call syslog to generate a log message. The priority argument is a combination of the facility shown in Figure 13.4 and a level, shown in Figure 13.5. These levels are ordered by priority, from highest to lowest.

Figure 13.5. The syslog levels (ordered)

level

Description

LOG_EMERG

emergency (system is unusable) (highest priority)

LOG_ALERT

condition that must be fixed immediately

LOG_CRIT

critical condition (e.g., hard device error)

LOG_ERR

error condition

LOG_WARNING

warning condition

LOG_NOTICE

normal, but significant condition

LOG_INFO

informational message

LOG_DEBUG

debug message (lowest priority)


The format argument and any remaining arguments are passed to the vsprintf function for formatting. Any occurrence of the two characters %m in the format are first replaced with the error message string (strerror) corresponding to the value of errno.

The setlogmask function can be used to set the log priority mask for the process. This function returns the previous mask. When the log priority mask is set, messages are not logged unless their priority is set in the log priority mask. Note that attempts to set the log priority mask to 0 will have no effect.

The logger(1) program is also provided by many systems as a way to send log messages to the syslog facility. Some implementations allow optional arguments to this program, specifying the facility, level, and ident, although the Single UNIX Specification doesn't define any options. The logger command is intended for a shell script running noninteractively that needs to generate log messages.

Example

In a (hypothetical) line printer spooler daemon, you might encounter the sequence

   openlog("lpd", LOG_PID, LOG_LPR);
   syslog(LOG_ERR, "open error for %s: %m", filename);

The first call sets the ident string to the program name, specifies that the process ID should always be printed, and sets the default facility to the line printer system. The call to syslog specifies an error condition and a message string. If we had not called openlog, the second call could have been

   syslog(LOG_ERR | LOG_LPR, "open error for %s: %m", filename);

Here, we specify the priority argument as a combination of a level and a facility.

In addition to syslog, many platforms provide a variant that handles variable argument lists.

#include <syslog.h>
#include <stdarg.h>

void vsyslog(int priority, const char *format,
 va_list arg);


All four platforms described in this book provide vsyslog, but it is not included in the Single UNIX Specification.

Most syslogd implementations will queue messages for a short time. If a duplicate message arrives during this time, the syslog daemon will not write it to the log. Instead, the daemon will print out a message similar to "last message repeated N times."

    Team BBL
    Previous Page Next Page