home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  

Writing Apache Modules with Perl and C
By:   Lincoln Stein and Doug MacEachern
Published:   O'Reilly & Associates, Inc.  - March 1999

Copyright 1999 by O'Reilly & Associates, Inc.


   Show Contents   Previous Page   Next Page

Chapter 9 - Perl API Reference Guide / The Apache Request Object
Logging Methods

In this section...

Pre­1.3 API methods
The Apache::Log class


   Show Contents   Go to Top   Previous Page   Next Page

This section covers request object methods that generate entries in the server error log. They are handy for debugging and error reporting. Prior to Apache 1.3, the error-logging API was a very simple one that didn't distinguish between different levels of severity. Apache now has a more versatile logging API similar to the Unix syslog system.4 Each entry is associated with a severity level from low (debug) to high (critical). By adjusting the value of the LogLevel directive, the webmaster can control which error messages are recorded to the error log file.

First we cover the interface to the earlier API. Then we discuss the Apache::Log class, which implements the 1.3 interface.

Pre­1.3 API methods

   Show Contents   Go to Top   Previous Page   Next Page


The log_error() method writes a nicely timestamped error message to the server error log. It takes one or more string arguments, concatenates them into a line, and writes out the result. This method logs at the "error" log level according to the newer API.

For example, this code:

$r->log_error("Can't open index.html $!");

results in the following ErrorLog entry:

[Tue Jul 21 16:28:51 1998] [error] Can't open index.html No such file or directory


The log_reason() method behaves like log_error() but generates additional information about the request that can help with the postmortem. Here is the format of the entries produced by this method:

[$DATE] [error] access to $URI failed for $HOST, reason: $MESSAGE

where $DATE is the time and date of the request, $URI is the requested URI, $HOST is the remote host, and $MESSAGE is a message that you provide. For example, this code fragment:

$r->log_reason("Can't open index.html $!");

might generate the following entry in the error log:

[Tue Jul 21 16:30:47 1998] [error] access to /perl/index.pl
failed for w15.yahoo.com, reason: Can't open index.html No such file
or directory

The argument to log_reason() is the message you wish to display in the error log. If you provide an additional second argument, it will be displayed rather than the URI of the request. This is usually used to display the physical path of the requested file:

$r->log_reason("Can't open file $!", $r->filename);

This type of log message is most often used by content handlers that need to open and process the requested file before transmitting it to the browser, such as server-side include systems.


warn() is similar to log_error(), but on post-1.3.0 versions of Apache it will result in the logging of a message only when LogLevel is set to warn or higher.


$r->warn("Attempting to open index.html");


The as_string() method is a handy debugging aid for working out obscure problems with HTTP headers. It formats the current client request and server response fields into an HTTP header and returns it as a multiline string. The request headers will come first, followed by a blank line, followed by the response. Here is an example of using as_ string() within a call to warn() and the output it might produce:

$r->warn("HTTP dump:\n", $r->as_string);
[Tue Jul 21 16:51:51 1998] [warn] HTTP dump:
GET /perl/index.pl HTTP/1.0
User-Agent: lwp-request/1.32
Host: localhost:9008
200 OK
Connection: close
Content-Type: text/plain

The Apache::Log class

   Show Contents   Go to Top   Previous Page   Next Page

Apache version 1.3 introduced the notion of a log level. There are eight log levels, ranging in severity from emerg to debug. When modules call the new API logging routines, they provide the severity level of the message. You can control which messages appear in the server error logging by adjusting a new LogLevel directive. Messages greater than or equal to the severity level given by LogLevel appear in the error log. Messages below the cutoff are discarded.

The Apache::Log API provides eight methods named for each of the severity levels. Each acts like the request object's error_log() method, except that it logs the provided message using the corresponding severity level.

In order to use the new logging methods, you must use Apache::Log in the Perl startup file or within your module. You must then fetch an Apache::Log object by calling the log() method of either an Apache ($r->log()) or an Apache::Server object ($r->server->log()). Both objects have access to the same methods described below. However, the object returned from the $r->log() provides some additional functionality. It will include the client IP address, in dotted decimal form, with the log message. In addition, the message will be saved in the request's notes table, under a key named error-notes. It is the equivalent of the C-language API's ap_log_rerror() function (Chapter 10).

The methods described in this section can be called with one or more string arguments or a subroutine reference. If a subroutine reference is used, it is expected to return a string which will be used in the log message. The subroutine will only be invoked if the LogLevel is set to the given level or higher. This is most useful to provide verbose debugging information during development while saving CPU cycles during production.


The log() method returns an object blessed into the Apache::Log class. log() is implemented both for the Apache class and for the Apache::Server class.

use Apache::Log ();
my $log = $r->log;         # messages will include client ip address
my $log = $r->server->log; # message will not include client ip address


This logs the provided message at the emergency log level, a level ordinarily reserved for problems that render the server unusable.

$log->emerg("Cannot open lock file!");


This logs the message using the alert level, which is intended for problems that require immediate attention.

$log->alert("getpwuid: couldn't determine user name from uid");


This logs the message at the critical level, intended for severe conditions.

$log->crit("Cannot open configuration database!");


This logs the message at the error level, a catchall for noncritical error conditions.

$log->error("Parse of script failed: $@");


The warn level is intended for warnings that may or may not require someone's attention.

$log->warn("No database host specified, using default");


notice() is used for normal but significant conditions.

$log->notice("Cannot connect to master database, trying slave $host");


This method is used for informational messages.

$log->info("CGI.pm version is old, consider upgrading") if
  $CGI::VERSION < 2.42;


This logs messages at the debug level, the lowest of them all. It is used for messages you wish to print during development and debugging. The debug level will also include the filename and line number of the caller in the log message.

$log->debug("Reading configuration from file $fname");
$log->debug(sub {
   "The request: " . $r->as_string;
   Show Contents   Go to Top   Previous Page   Next Page
Copyright 1999 by O'Reilly & Associates, Inc.