WebReference.com - Chapter 4 from The mod_perl Developer's Cookbook, from Sams Publishing (3/6) | WebReference

WebReference.com - Chapter 4 from The mod_perl Developer's Cookbook, from Sams Publishing (3/6)

To page 1To page 2current pageTo page 4To page 5To page 6
[previous] [next]

mod_perl Developer's Cookbook

4.4. Writing to the Apache Error Log

You want to send informational or error messages to the Apache error log.

Technique

Use the various methods provided by the Apache::Log class.

use Apache::Log;
use strict;
sub handler {
 my $r = shift;
 my $log = $r->server->log;
 unless ($r->content_type eq 'text/html') {
  $log->info("Request is not for an html document - skipping...");
  $log->error("Custom processing aborted!");
  return DECLINED;
 }
 # Continue along...
}

Comments

The Apache::Log class provides hooks into the Apache logging mechanism, allowing you to send information directly to the file specified by the ErrorLog directive.

To create an Apache::Log object, you can call the log() method from either the Apache class or the Apache::Server class, or on an object created from either class. After you have an Apache::Log object, you can call any of its eight methods, each of which corresponds to and is controlled by the verbosity level of the LogLevel directive:

The main difference between using an Apache::Log object created from the request object or a server object is that server-based logging methods do not print out the client IP address. For instance:

$r->log->warn('Ahoy!');
# prints: [Mon Oct 15 16:40:47 2001] [warn] [client 10.3.4.200] Ahoy!
$r->server->log->warn('Ahoy!');
# prints: [Mon Oct 15 16:40:47 2001] [warn] Ahoy!

Because mod_perl ties STDERR() to the Apache errorlog, writing directly to the error log using simple print() statements is also possible:

print STDERR "You sank my battleship!\n";

Currently, Apache receives all messages sent to the error log through the logging API, but only displays those that are allowed by the LogLevel setting. Because future versions of mod_perl may optimize away Apache::Log calls based on the LogLevel, using these methods over printing directly to STDERR is recommended. Not only will you (someday possibly) realize some performance gains, but users of your code will also be allowed full control over the amount of messages they want to see.

We ought to mention that sending messages to the errorlog does not actually require an Apache::Log object. A few methods are available that allow you to log directly from a the request and server objects:

4.5. Accessing the Apache ErrorLog Directive

You need to know the physical name and path to the Apache error log.

Technique

Use the error_fname() method from the Apache::Server class to retrieve the current file specified by the ErrorLog directive.

package Cookbook::ErrorsToBrowser;
# Print out the last N lines of the error_log.
# Probably not a good idea for production, but
# helpful when debugging development code.
use Apache::Constants qw(OK);
use Apache::File;
use strict;
sub handler {
 my $r = shift;
 my $lines = $r->dir_config('ErrorLines') || 5;
 # Make sure that the file contains a full path.
 my $error_log  = $r->server_root_relative($r->server->error_fname);
 my $fh = Apache::File->new($error_log);
 my @lines;
 while (my $line = ) {
  shift @lines if (push @lines, $line) > $lines;
 }
 $r->send_http_header('text/plain');
 print @lines;
 return OK;
}
1;

Comments

As shown in Recipe 4.1, the Apache server record holds the name of the error log file, as set by the core ErrorLog directive. Because ErrorLog, like most Apache directives that deal with files, allows for a relative or absolute filename, for maximum portability, using error_fname() in conjunction with server_root_relative() is best for digging out the real filename.

The preceding sample code illustrates one possible use of error_fname(). As you begin to get more comfortable with mod_perl handlers and start to use them within your application, you will find that errors can be triggered by phases other than the content generation phase. In these circumstances, using something like CGI::Carp qw(fatalsToBrowser) may not be terribly helpful during development because the problem isn't necessarily your Registry script. Installing code similar to this as an ErrorDocument is one possible alternative. Here is a sample configuration for ErrorsToBrowser.pm:

ErrorDocument 500 /show-errors
<Location /show-errors>
 SetHandler perl-script
 PerlHandler Cookbook::ErrorsToBrowser
 PerlSetVar ErrorLines 25
</Location>

Recipe 16.6 has a more interesting approach to redirecting output to the error log.


To page 1To page 2current pageTo page 4To page 5To page 6
[previous] [next]

Copyright © Pearson Education and
Created: March 18, 2002
Revised: March 18, 2002


URL: http://webreference.com/programming/perl/cookbook/chap4/3.html