Apcupsd System Logging

The apcupsd philosophy is that all logging should be done through the syslog facility (see: man syslog). This is now implemented with the exceptions that STATUS logging, for compatibility, with prior versions is still done to a file, and EVENTS logging can be directed to a "temporary" file so that it can be reported by the network information server.

Apcupsd logging into four separate types called:


DEBUG Logging

Debug logging consists of debug messages. Normally these are turned on only by developers, and currently there exist very few of these debug messages.

DATA Logging

Data logging consists of periodically logging important data concerning the operation of the UPS. See the DATA Format section of this manual for more details.

STATUS Logging

Status logging consists of logging all available information known about your UPS as a series of ASCII records. This information is also made available by the apcupsd network information server.

For more details on STATUS logging, see the STATUS Format section of this manual.

EVENTS Logging

Events logging consists of logging events as they happen. For example, successful startup, power fail, battery failure, system shutdown, ...

See the EVENTS Format section of this manual for more details.

Implementation Details

In order to ensure that the data logged to syslog() can be directed to different files, I have assigned syslog() levels to each of our four types of data as follows:

1. DEBUG logging has level LOG_DEBUG 3. STATUS logging has level LOG_NOTICE
4. EVENTS logging has levels LOG_WARNING, LOG_ERR, LOG_CRIT, and LOG_ALERT

It should be noted that more work needs to be done on the precise definitions of each of the levels for EVENTS logging. Currently, it is roughly broken down as follows:

LOG_WARNING general information such as startup, etc.
LOG_ERR an error condition detected, e.g. communications problem with the UPS.
LOG_CRIT a serious problem has occurred such as power failure, running on UPS batteries, ...
LOG_ALERT a condition that needs immediate attention such as pending system shutdown, ...

More work needs to be done to the code to ensure that it corresponds to the above levels.

As a practical example of how to setup your syslog() to use the new logging feature, suppose you wish to direct all DATA logging to a file named /var/log/, all EVENTS to the standard /var/log/messages file (to be mixed with other system messages), and at the same time send all EVENTS to /var/log/, and finally, you want to send all STATUS logging to the named pipe /var/log/apcupsd.status

First as root, you create the named pipe:

mkfifo /var/log/apcupsd.status

change its permissions as necessary or use the -m option to set them when creating the pipe.

Then you modify your /etc/syslog.conf file to direct the appropriate levels of messages where you want them. To accomplish the above, my syslog.conf file looks like:

# exclude all apcupsd info by default
*.info;local0.none                    /var/log/messages

# Everything for apcupsd goes here;local0.!notice             /var/log/
local0.notice;local0.!warn            |/var/log/apcupsd.status
local0.warn                            /var/log/
local0.warn                            /var/log/messages

Developer's Notes

All logging functions and all error reporting are now done through the log_event() subroutine call. Exceptions to this are: initialization code where printf's are done, and writing to the status file. Once the initialization code has completed and the fork() to become a daemon is done, no printf's are used. log_event() has exactly the same format as syslog(). In fact, the subroutine consists of only a syslog() call. If anyone really wishes to log to a file, the code to do so can easily be done by adding code to log_event() in apclog.c.