TOC PREV NEXT INDEX

LynxOS User's Guide


Event Logging

The Event Logging System

Event Logging provides the ability to log specific kernel and user application events. With the LynuxWorks Event Logging System, users can maintain system performance, predict and eliminate problems, and reduce system downtime.

Events can be monitored from several system facilities (mail, kernel, or file system, for example) with a variety of severities (warning, emergency, or critical, for example). Process threads can be set up to log specific events, monitor facility conditions and receive notifications on specific events.

Event Logging Components

The LynuxWorks Event Logging System is comprised of several components that interact to provide a fully-featured means of logging system events. The following table describes the components of the Event Logging System.

Event Logging System Components  
Component
Description
User Libraries
User libraries include the function calls that interact with the Event Logging System. For function prototypes and descriptions, see "The Event Logging Daemon".
System Log Files
System Log Files include the Active System Log and Archived System Log. At any given time, the Event Logging System writes to an open file, known as the Active System Log. This log file is written to until it reaches maximum capacity. When the Active System Log file is full, it is archived and a new Active System Log is created.
Event Log Driver
The Event Log Driver contains the read and write interfaces used by the Log Daemon to read and write to memory. The Event Log Driver can be installed statically or dynamically.
System Log Buffer
The System Log Buffer is a buffer of rows. Each row contains two elements: an Event Record and the Event Data. The Event Record is used to identify the contents of the User Data. The Event Data is the raw data of the event. For more information on Event Record Identifier types, see "Event Record Identifier (log_event_t)".
Log Daemon
The Log Daemon is a user space application that maintains event notifications, and the Active System Log.

Process Flow

The following sections describe the various flows used by the reading, writing, and opening functions.

Write Flow

A user thread initiates log_write(), which calls the write interface of the Event Log Driver. The Event Log Driver fills the Event Record and Event Data with the parameters provided in log_write(). If the Log System Buffer is full, an error is returned. If successful, the Log Daemon reads the contents of the System Log Buffer and writes the event to the Active System Log. The Event Log Driver clears out the buffer for future use.

After the event is processed in the Active System Log, the Log Daemon searches the notification list to determine if any processes must access the event. If so, the process is sent a notification signal.

Write Flow

Read Flow

A user thread initiates a log_read() function, which reads the log entry of the file handle provided by log_read(). The function checks if the event record matches the current query requirements. If it matches, the event record data and event data are returned to the calling thread. If not, the event is skipped and the next event is checked.

Read Flow

Open Flow

A user thread initiates the log_open() function, which opens a log file.

If the path parameter of log_open() is NULL, it retrieves the Active System Log file name from memory. Otherwise, the path parameter is used to open an Archived System Log.

Open Flow

Notify Flow

A user thread initiates the log_notify() function, which sends process and signal information to the Log Daemon. If the Log Daemon finds a matching event, a signal is sent to the calling thread.

Notification Flow

Installing the Event Logging System

Installing on a Native LynxOS System

Use the following commands to install the Event Logging driver on a native LynxOS system:

# cd /sys/lynx.os
# make install.evlog

Removing from a Native System

Use the following commands to remove the Event Logging driver from a Native LynxOS system:

# cd /sys/lynx.os
# make uninstall.evlog

Installing On a Cross Development System

Use the following commands to install the Event Logging driver on a cross development system:

# cd /usr/lynx/4.0.0/<cpu>
where <cpu> is the platform of the system, x86 or ppc.
# source SETUP.bash
# cd $ENV_PREFIX/sys/lynx.os
# make install.evlog

Removing From a Cross Development System

Use the following commands to remove the Event Logging driver from a cross development system.

# cd /usr/lynx/4.0.0/<cpu>
where <cpu> is the platform of the system, x86 or ppc.
# source SETUP.bash
# cd $ENV_PREFIX/sys/lynx.os
# make uninstall.evlog

Configuring the Event Logging System

Event Logging Parameters

The following sections provide the configurable parameters available to the Event Logging System. Depending on the installation type, these options are set in the evloginfo.h header file.

Configurable Parameters

Buffer Length

The default buffer length for the Event Logging System is 80. The maximum, defined as LOG_ENTRY_MAXLEN is 250.

Buffer Size

The buffer size represents the number of rows the Log System Buffer contains. The default value is 100.

High Watermark Level

The High Watermark Level is the percentage of how full a Log System Buffer is before a high watermark message is written. The default High Watermark Level is 90%. After the Log System Buffer reaches the High Watermark Level, a High Watermark Level record is written to the buffer stating that this level has been reached. This system message has a facility LOG_EVLOG and severity LOG_WARNING.

The High Watermark Level can be disabled by setting it to 100.

When one entry remains in the Log System Buffer, a message is written to the last buffer stating that the Log System Buffer is full. Additional events cannot be written to the buffer. log_write() fails when the System Buffer is full.

Low Watermark Level

The Low Watermark Level is the percentage of how empty a Log System Buffer is before a low watermark message is written. The default Low Watermark Level is 0%. When the Log System Buffer meets the Low Watermark Level, a log entry is written to the buffer stating the Low Watermark Level is reached. This system message has a facility of LOG_EVLOG and a severity of LOG_WARNING.

The Event Logging Daemon

The Event Logging Daemon, evlogd must be running to use the Event Logging System. To start the Event Logging Daemon, type evlogd:

# evlogd

evlogd can also be added to the /bin/rc file to start the Event Logging Daemon when the system starts.

Note: The Event Logging driver must be installed before the Event Logging Daemon can run. See "Installing on a Native LynxOS System".

evlogd has the following command line options:

Event Log Daemon Options  
Command Option
Description
-l <number_of_entries>
The -l option specifies the number of log entries written to the Active System Log before creating a new log file. The default value is 10000. This value can be changed from a minimum of 10 and a maximum of 999999.
-d <path>
The -d option specifies a path to the log files on a system. The default path is /sys/log. The directory name cannot exceed 80 characters.

Function Prototypes and Descriptions

typedefs in eventlog.h

Log File Descriptor (logd_t)

The logd_t type represents a log file stream opened for reading. The logd_t type is defined as an unsigned short.

System Identifier (log_facility_t)

The log_facility_t type identifies the subsystem that generated the event. The following table lists the types, memory addresses and descriptions of the available facilities.

log_facility_t Values  
Name
Bit Address
Description
LOG_AUTH
0x00000001
Authorization & authentication events
LOG_CRON
0x00000002
cron daemon
LOG_DAEMON
0x00000004
Background services
LOG_LPR
0x00000008
lpr subsystem
LOG_MAIL
0x00000010
Mail delivery system
LOG_NEWS
0x00000020
News system
LOG_KERN
0x00000040
General Kernel events
LOG_KERN_FS
0x00000080
File system events
LOG_KERN_NET
0x00000100
Networking events
LOG_LOG
0x00000200
Logging system events
LOG_LOCAL0
0x00001000
Reserved
LOG_LOCAL1
0x00002000
Reserved
LOG_LOCAL2
0x00004000
Reserved
LOG_LOCAL3
0x00008000
Reserved
LOG_LOCAL4
0x00010000
Reserved
LOG_LOCAL5
0x00020000
Reserved
LOG_LOCAL6
0x00040000
Reserved
LOG_LOCAL7
0x00080000
Reserved

Additionally, the log_facility_set_t type is used during query operations. The log_facility_set_t type is defined as an unsigned int.

Severity Type (log_serverity_t)

The log_severity_t type defines the severity of the event. The log_severity_t type is defined as an unsigned int.

log_severity_t Values  
Name
Bit Address
Description
LOG_EMERG
0x00000001
Emergency condition
LOG_ALERT
0x00000002
Condition requiring immediate correction
LOG_CRIT
0x00000004
Critical condition
LOG_ERR
0x00000008
Error
LOG_WARNING
0x00000010
Warning message
LOG_NOTICE
0x00000020
Condition requiring special handling
LOG_INFO
0x00000040
Informational message
LOG_DEBUG
0x00000080
Debugging message
LOG_POSIX_SEV1
0x80000000
Sets POSIX standard rather than default error handling
1
Default POSIX behavior can be added by including LOG_POSIX_SEV in a function with the and or or expression. The Default POSIX behavior is to include the highest severity level found, and every severity level beneath.

Log Record Identifier (log_recid_t)

The log_recid_t type is used to identify specific records to any log-reading code. Defined as an unsigned int.

Event Record Identifier (log_event_t)

log_event_t indicates the format of the Event Data portion of the event data. Defined as an unsigned int.

log_event_t Values  
Name
Bit Address
Description
LOG_STRING

Event Data is a NULL-terminated string.
LOG_BYTE

Event Data is a series of bytes.
LOG_SHORT
2 bytes each
Event Data is a series of shorts.
LOG_INT
4 bytes each
Event Data is a series of ints.
LOG_USERBASE
10,000
Minimum user defined type
LOG_USERMAX
INT_MAX
Maximum user defined type

Log Record (log_entry)

The log_entry struct reads the back of the constant part of a log record. log_entry contains the following members.

log_entry Members  
Member
Type
Description
log_status
byte
Status of the record:
· bit 0: Available=0, Used=1
· bit 1: Endian of this entry. 1=big, 0=little
· bits 2-7: reserved
log_recid
log_recid_t
System assigned ID of the log record; starts at 1, and increases to a maximum of 65535.
0 represents the header or a daemon error.
log_size
size_t
Size of the log record's variable data portion
log_event_id
log_event_t
Log record identification code; provides the format of the data.
log_facility
log_facility_t
Log record facility code
log_severity
log_severity_t
Log record severity code
log_uid
uid_t
Effective User ID associated with event
log_gid
gid_t
Effective Group ID associated with event
log_pid
pid_t
Process ID associated with event
log_pgrp
pid_t
Process group associated with event
log_tid
tid_t
Thread ID associated with event
log_time
struct timespace
System time when event was logged

Log Query (log_query_t)

The log_query_t type is used to filter events in a log.

log_query_t  
Member
Type
Description
q_facility_set
log_facility_set_t
Stores facilities for query.
q_severity
log_severity_t
Stores severity for query.

Writing Log Entries

The log_write() function is used to write information to the System Log. For more information on the process flow, see "Write Flow".

log_write()

#include <eventlog.h>

int log_write(log_facility_t facility,
int event_id, log_severity_t severity,
const void *buf, size_t len);

Description

The log_write() function creates the facility, severity, and data for an event log. After filling the structure, log_write() passes the data to the Event Logging Driver. If the Event Logging Driver is not running, the log_write() function fails.

Note: Success of this function indicates that the event is buffered to memory, not written to the Active System Log file.

In addition to the facility set, severity, and size arguments listed in the prototype, log_write() also adds arguments defined in the table "log_entry Members".

This function is available as both a kernel space and user library function.

Returns

The log_write() function returns 0 after a successful completion. If an error occurred, log_write() returns an error number.

log_write() Error Returns  
Error
Description
EINVAL
The severity argument is invalid.
buf is invalid.
ENOSPC
There are no free buffers in the Log System Buffer.
EMSGSIZE
The len argument exceeds LOG_ENTRY_MAXLEN.
EPERM
The caller does not have appropriate privileges.
EIO
An I/O error occurred when writing to the System Buffer.
ENODEV
The Event Log Driver is not running.

Processing Log Entries

The functions log_open(), log_read(), log_notify(), log_close(), log_seek(), log_severity_compare(), log_facility*(), and log_query() are implemented according to POSIX 1003.1h specifications. These log processing functions are provided only as user library functions.

log_open()

#include <eventlog.h>

int log_open(logd_t *logdes, const char *path,
const log_query_t *query);

Description

The log_open() function establishes a connection between a log file and a log descriptor. If the path parameter is NULL, the current Active System Log is used. Otherwise, the log_open() function searches the Archived System Log pointed to by path. After successful completion, log_open() returns a log file handle (in the logdes parameter) to the calling process.

Note: The log file handle returned by log_open() can only be used by the Event Logging System.

Returns

If successful, log_open() returns the value 0. If an error occurs, log_open() returns an error number.

log_open() Error Returns  
Error
Description
EACCES
Search or read permission is denied on a component of the path prefix.
EINVAL
The query argument is not NULL or does not point to a valid log_query_t.
EINVAL
The path argument is not a valid Event Log file.
EMFILE
The calling process has too many log descriptors open (LOG_OPEN_MAX).
EXDEV
No Active System Log
ENAMETOOLONG
The length of the path argument exceeds PATH_MAX (80 characters).
EMFILE
Too many files are open in the system.
ENOENT
The file specified by path does not exist.
ENOTDIR
A component of the path prefix is not a directory.
ENOEXEC
Read of header file or Log file failed.
EBADMSG
Incompatible log file version

log_read()

#include <eventlog.h>

int log_read(logd_t logdes,
struct log_entry *entry, void *log_buf,
size_t log_len);

Description

The log_read() function reads from the file associated with logdes file descriptor and matches the current query with an event record from an Active or Archived System Log.

If an event record that matches the log file query is found, it returns the event record and event data to the calling process. If the end of file is reached on the Active System Log before a match is found, an EAGAIN error is returned. EAGAIN errors are returned on Active System Log files only. When an end of file is reached on an Archived System Log, an EOF error is returned.

If the Active System Log is full and there is no match, an EOF error is returned. This error occurs only when a user thread is accessing an event log that was closed by the Event Logging Daemon. Use the log_close() function to close this file handle. Use log_open() with a path of NULL to open the new Active System Log.

This is a blocking call and does not wait for a log entry to be written, but rather returns immediately with the result.

Return

If successful, log_read() returns the value 0. If an error occurs, log_read() returns an error number.

log_read() Error Returns  
Error
Description
EBADF
The logdes argument is not a valid file descriptor.
EAGAIN
No data is available: There are no unread matching events remaining and the maximum file size is not reached.
EINTR
A signal has interrupted the call.
EIO
An I/O error has occurred while reading the file.
EOF
End of file is reached without finding a matching event.
EINVAL
log_buf and/or entry are NULL.
EMSGSIZE
Event record data is larger than log_len.

log_notify()

#include <eventlog.h>

int log_notify(logd_t logdes,
const struct sigevent *notification);

Description

The function log_notify() allows a calling process to be notified of specific event records. The Event Logging Daemon returns an event record log that matches the logdes file descriptor.

If notification is NULL, no notification is performed. If the calling process has already registered a notification with the same logdes, the new notification replaces the existing one.

The sig_num member of the notification struct must be a real-time signal.

The notification request is not removed when logdes closes. Though this differs from the POSIX specification, it allows notification to continue after the Active System Log is rolled.

Note: Although open file handles are inherited by child processes, notifications are not.

If the Event Logging Daemon cannot add the notification to the notification table, the Daemon returns a siginfo_t signal to the calling thread. The si_value of siginfo_t is -1 to signal the thread that an error occurred.

To notify a thread of a match with query, the siginfo_t signal is sent to the thread with a si_value of 0.

Return

On successful completion, log_notify() returns 0. If an error occurs, the error number is returned.

log_notify() Error Returns  
Error
Description
EBADF
The logdes argument is not a valid file descriptor.
EINVAL
The notification argument is invalid.
EPERM
The process requested notification on a log that is not written to.
EBADF
The Log Daemon message queue does not exist.
EBUSY
The notification table in the Log Daemon is full.
EXDEV
Cannot access Daemon
EAGAIN
Daemon busy

log_close()

#include <eventlog.h>

int log_close(logd_t logdes);

Description

The log_close() function deallocates the open file descriptor associated with logdes. This function also performs a close() on the file handle.

Return

On successful completion, log_close() returns 0. If an error occurs, the error number is returned.

log_close() Error Returns  
Error
Description
EBADF
The logdes argument is not a valid file descriptor.

log_seek()

#include <eventlog.h>
int log_seek(logd_t logdes,
log_recid_t log_recid);

Description

The log_seek() function sets the file offset of the open log associated with logdes to the event record that matches log_recid. Two values other than a record ID can be passed. LOG_SEEK_START (defined as 0) and LOG_SEEK_END (defined as -1) reposition the start or end of the current log file, respectively.

Return

On successful completion, log_seek() returns 0. If an error occurs, the error number is returned.

log_seek() Error Returns  
Error
Description
EBADF
The logdes argument is not a valid file descriptor.
ENOENT
No log record exists in the specified log file with a record ID matching log_recid.

log_severity_compare()

#include <eventlog.h>
int log_severity_compare(int *order,
log_severity_t s1, log_severity_t s2);

Description

The log_severity_compare() function compares the severity levels of s1 and s2. If s1 is more severe than s2, order is set to 1. If s2 is more severe, order is set to -1. If s1 equals s2, order is set to 0.

Return

On successful completion, log_severity_compare() returns 0. If an error occurs, the error number is returned.

log_severity_compare() Error Returns
Error
Description
EINVAL
s1, s2, or both, are invalid severities.

Setting Log Facilities

log_facilityemptyset()

#include <eventlog.h>

int log_facilityemptyset(
log_facility_set_t *set);

Description

The log_facilityemptyset() function excludes all facilities in the facility set pointed to by set.

Return

On successful completion, log_facilityemptyset() returns 0. If an error occurs, the error number is returned.

log_facilityemptyset() Error Returns
Error
Description
EINVAL
set points to NULL.

log_facilityfillset()

#include <eventlog.h>

int log_facilityfillset(
log_facility_set_t *set);

Description

The log_facilityfillset() function includes all facilities in the facility set pointed to by set.

Return

On successful completion, log_facilityfillset() returns 0. If an error occurs, the error number is returned.

log_facilityfillset() Error Returns  
Error
Description
EINVAL
set points to NULL.

log_facilityaddset()

#include <eventlog.h>

int log_facilityaddset(log_facility_set_t *set,
log_facility_t facilityno);

Description

The log_facilityaddset() function adds the facility facilityno to the facility set to pointed to by set.

Return

On successful completion, log_facilityaddset() returns 0. If an error occurs, the error number is returned.

log_facilityaddset() Error Returns  
Error
Description
EINVAL
set points to NULL.

log_facilitydelset()

#include <eventlog.h>

int log_facilitydelset(log_facility_set_t *set,
log_facility_t facilityno);

Description

The log_facilitydelset() function removes the facility facilityno from the facility set pointed to by set.

Return

On successful completion, log_facilitydelset() returns 0. If an error occurs, the error number is returned.

log_facilitydelset() Error Returns  
Error
Description
EINVAL
set points to NULL.

log_facilityismember()

#include <eventlog.h>

int log_facilityismember(
log_facility_set_t *set,
log_facility_t facilityno, int *member);

Description

The log_facilityismember() function checks if facilityno is included in the facility set pointed to by set.

Return

On successful completion, log_facilityismember() returns 0. If an error occurs, the error number is returned.

log_facilityismember() Error Returns  
Error
Description
EINVAL
set points to NULL.
EINVAL
member is NULL.

Querying Log Entries

log_query_init()

#include <eventlog.h>

int log_query_init(lot_query_t *query);

Description

The log_query_init() function initializes the log_query_t struct query. The default value for query is an empty facility set and an empty severity. The log_query_init() function does not allocate memory for query.

Return

On successful completion, log_query_init() returns 0. If an error occurs, the error number is returned.

log_query_init() Error Returns  
Error
Description
EINVAL
query points to NULL.

log_query_destroy()

#include <eventlog.h>

int log_query_destroy(lot_query_t *query);

Description

The log_query_destroy() function is included as a part of the POSIX specification. Because the log_query_init() function does not allocate memory for query, there is no need to destroy it.

Return

log_query_destroy() always returns 0.

log_query_getfacilities()

#include <eventlog.h>
int log_query_getfacilities(log_query_t *query,
log_facility_set_t *facility);

Description

The log_query_getfacilities() function returns the facility for the current query.

Return

On successful completion, log_query_getfacilities() returns 0. If an error occurs, the error number is returned.

log_query_getfacilities() Error Returns  
Error
Description
EINVAL
query points to NULL.

log_query_setfacilities()

#include <eventlog.h>
int log_query_setfacilities(log_query_t *query,
log_facility_set_t *facility);

Description

The log_query_setfacilities() function sets the current facility set for query to the facility set pointed to by facility.

Return

On successful completion, log_query_setfacilities() returns 0. If an error occurs, the error number is returned.

log_query_setfacilities() Error Returns  
Error
Description
EINVAL
query points to NULL.

log_query_getseverity()

#include <eventlog.h>
int log_query_getseverity(log_query_t *query,
log_severity_t *severity);

Description

The log_query_getseverity() function returns the severities for query. The severities are placed into the severity set pointed to by severity. The log_query_getseverity() function sets the value of severity equal to the severity member of query.

Return

On successful completion, log_query_getseverity() returns 0. If an error occurs, the error number is returned.

log_query_getseverity() Error Returns  
Error
Description
EINVAL
query points to NULL.
EINVAL
severity points to NULL.

log_query_setseverity()

#include <eventlog.h>
int log_query_setseverity(log_query_t *query,
log_severity_t *severity);

Description

The log_query_setseverity() function sets the current severities in query.

Return

On successful completion, log_query_setseverity() returns 0. If an error occurs, the error number is returned.

log_query_setseverity() Error Returns  
Error
Description
EINVAL
query points to NULL.
EINVAL
severity is an invalid severity.

Sample Driver Code

The following section provides sample code used with the Event Logging System.

Kernel Code Example

#include <eventlog.h>
...
int rval;
...
rval = log_write(LOG_KERN, LOG_STRING, LOG_CRIT,
"Kernel error", 12);
...

User Code Example

#include <sys/types.h>
#include <stdio.h>
#include <signal.h>
#include <ctype.h>
#include <eventlog.h>
logd_t logfd;
int sig_handler(int sig, siginfo_t *extra, void *v)
{log_entry_t e;
char buff[500];
int rc;
     if ((rc = log_read(logfd, &e, buff, 500)) != LOG_OK)
     {
          printf("\nError reading log. rc = %u",rc);
     }
     else
     {
          printf("\nEvent Read: fac %u sev %u data %s",
               e.log_facility, e.log_severity, buff);
          fflush(stdout);
     }
}

/*********************************************
* MAIN
*********************************************/
int main(int argc, char **argv)
{
struct sigaction sa;
int rc;log_query_t q;

struct sigevent not;

     /* set up signal handler for notify */
     sa.sa_handler = (void(*)(_MATCH_ALL))sig_handler;
     sigemptyset(&sa.sa_mask); /* clear signal mask */
     sa.sa_flags = 0;
     if (sigaction(SIGRTMIN, &sa, NULL))
     {
          printf("\nError setting up signal handler.");
          exit(1);
     }

     /* setup the query */
     q.q_facility_set = LOG_EVLOG;
     q.q_severity = LOG_WARNING;

     /* open the active system log */
     if ((rc = log_open(&logfd, NULL, &q)) != LOG_OK)
     {
          printf("\nError opening active system log.");
          exit(1);
     }

     /* set up a notify*/
     not.sigev_signo = SIGRTMIN;

     /* attempt to do a notify on archive...it should fail */
     if ((rc = log_notify(logfd, &not)) != LOG_OK)
     {
          printf("\nError setting up notify.");
          exit(1);
     }

     while(1)
          sleep(1);
     exit(0);



LynuxWorks, Inc.
855 Branham Lane East
San Jose, CA 95138
http://www.lynuxworks.com
1.800.255.5969
TOC PREV NEXT INDEX