Add Book to My BookshelfPurchase This Book Online

Chapter 16 - Miscellaneous Routines

UNIX Systems Programming for SVR4
David A. Curry
 Copyright © 1996 O'Reilly & Associates, Inc.

Error Logging
When systems programs encounter errors, it's often difficult to figure out where to print the error message. For commands executed by users, the answer is simple: print the message on the terminal screen. For daemons, programs run out of at or cron, and so forth, there's no obvious place. One method is simply to open /dev/console (the machine's console terminal) and print the error there. Back in the days of console terminals such as Decwriters that had a printer instead of a screen, this made sense. But most machines now have a video screen for a console, if they have one at all. Once a message scrolls off the top of the screen, it is gone forever. If nobody sees it before it disappears, the error will never be noted and fixed.
In 4.2BSD, Berkeley introduced the syslog daemon, a technique that has since been adopted by most vendors. The syslogd program starts when the system boots, and remains active permanently. Programs (and the operating system itself) that have errors or other information to report send these messages to the daemon. The daemon follows the directions in its configuration file, usually stored in /etc/syslog.conf, to handle the message:
 It can print the message on the system console. The message will be preceded by the current date and time, the name of the program that sent it, and, optionally, the program's process ID number.
 It can print the message to a log file. Different types of messages may be sent to the same log file, but they may also be sent to different files.
 It can send the message to a syslogd running on another host. The remote host will then process the message. It is common to configure client systems to send all their messages to the file server for logging, both because of the additional disk space on the server, and to reduce the number of places messages are logged.
 It can ignore the message. It is common to ignore debugging messages; when they are needed, syslogd can always be told to process them temporarily.
To log error messages via syslogd, a program must first call the openlog function:
    #include <syslog.h>
    void openlog(char *ident, int logopts, int facility);
    void closelog(void);
The ident parameter is a name that identifies the program. Usually, it can just be the value of argv[0] with any leading pathname removed. The logopts parameter specifies several logging options that may be or ed together:
LOG_PID
Log the process ID with each message. This is frequently used in daemon processes to identify the particular instance of the daemon.
LOG_CONS
Write messages to the system console if they cannot be sent to syslogd. This is safe to do in daemon processes that have no controlling terminal, as syslog will spawn a child process to open the console.
LOG_NDELAY
Open the connection to syslogd immediately, instead of waiting until the first message is logged. This can be used in programs that need to manage the order in which file descriptors are allocated.
LOG_NOWAIT
Do not wait for child processes that have been spawned to write on the system console. This should be used by processes that receive notification of child exits via SIGCHLD, since syslog may otherwise block waiting for a child whose exit status has already been collected.
The facility parameter specifies a default facility (category) to be assigned to all messages that do not have a facility encoded in them. The facility is used in the syslogd configuration file to group messages of certain types together. The allowable facilities are:
LOG_KERN
Messages generated by the operating system kernel. These cannot be generated by user processes.
LOG_USER
Messages generated by user processes. This is the default facility if none is specified.
LOG_MAIL
Messages generated by the mail subsystem.
LOG_DAEMON
Messages generated by system daemon processes.
LOG_AUTH
Messages generated by the authentication subsystem (login, su, etc.).
LOG_LPR
Messages generated by the print spooler subsystem.
LOG_NEWS
Messages generated by the Usenet news subsystem. This facility is not available in HP-UX 10.x.
LOG_UUCP
Messages generated by the UUCP subsystem. This facility is not available in HP-UX 10.x.
LOG_CRON
Messages generated by cron and at. This facility is available only in Solaris 2.x.
LOG_LOCAL0 —
LOG_LOCAL7
Reserved for local use. These can be assigned to any purpose the system administrator desires.
The closelog function closes the log file.
Messages are actually logged using the syslog function:
    #include <syslog.h>
    void syslog(int priority, char *mesg, /* args */ ...);
    #include <stdarg.h>
    int vsyslog(int priority, char *mesg, va_list ap);
The mesg parameter is a character string identical to that used by printf, with the additional conversion specification %m, which is replaced with a system error message (as would be printed by perror). The args parameters correspond to the conversion specifications in mesg, just as they do in printf.
The priority parameter is encoded as a facility and a level, or ed together. The facility part is as described above; if omitted, the facility declared in the call to openlog is used. The level part may be one of the following:
LOG_EMERG
A panic condition; messages at this level are usually broadcast to all logged-in users.
LOG_ALERT
A condition that should be corrected immediately, such as a corrupt system database.
LOG_CRIT
Critical conditions, such as hard device errors.
LOG_ERR
Errors such as non-existent files. This is the most frequently used level.
LOG_WARNING
Warning messages.
LOG_NOTICE
Conditions that are not errors, but may require special attention.
LOG_INFO
Informative messages.
LOG_DEBUG
Debugging messages. Normally only used when debugging a program.
The vsyslog function is to syslog as vprintf is to printf (see Chapter 4, The Standard I/O Library). It takes a variable-length argument list and breaks it apart with the stdarg functions. The vsyslog function is not available in HP-UX 10.x.
Finally, the setlogmask function can be used to control which messages actually get delivered to syslogd:
    #include <syslog.h>
    int setlogmask(int maskpri);
The function sets the current mask priority to maskpri and returns the previous priority. Messages whose priority is not contained in maskpri are not delivered to syslogd. The mask for an individual priority pri is calculated with the macro
    LOG_MASK(pri)
The mask for all priorities up to and including pri is calculated with the macro
    LOG_UPTO(pri)
One use of priorities is to include debugging messages in a program, but to print them only when debugging is enabled. This can be achieved with a code segment such as:
    #include <syslog.h>
    ·
    ·
    ·
    openlog(ident, logopt, facility);
    if (debug)
        setlogmask(LOG_UPTO(LOG_DEBUG));
    else
        setlogmask(LOG_UPTO(LOG_ERR));
Although it is a matter of local policy, it is usually appropriate for most system programs to log to the LOG_DAEMON or one of the LOG_LOCALn facilities. A program that generates a large amount of logging information should probably either have one of the LOG_LOCALn facilities reserved for its use so that the syslogd configuration file can be used to separate those messages from others, or it should simply open its own log file and not use syslog at all.

Previous SectionNext Section
Books24x7.com, Inc © 2000 –  Feedback