Monday, April 28, 2008

Simple email alert error page.

Mongrel, Apache, mod_proxy and Rails do go very well together. However, there are times when it can break down. While you can rely to some degree on monitoring tools, if a user is given an error page, it is nice to know as soon as it happens.
One good way to do this, have the error page, trigger an email alert letting you know some basic information so that you can debug and figure out what has gone wrong.
When mod proxy cannot connect to the mongrel cluster, it will return a 503 error page. Apache lets you specify this to be a cgi script so that you can bounce them to a cgi error page that packages up the environment and emails it to an administrator.

Here are 4 steps to follow to use this technique:

Step 1: Write a cgi error document

#!/usr/bin/perl
use strict;
use CGI;


my $query = new CGI;

my $sendmail = "/usr/sbin/sendmail -t";
my $reply_to = "Reply-to: REPLYEAMAIL\@REPLYDOMAIN.com\n";
my $subject = "Subject: Apache Error Page\n";

my $content = "SERVER_SOFTWARE = " . $ENV{'SERVER_SOFTWARE'} . "\n";
$content = $content . "SERVER_SOFTWARE = " . $ENV{'SERVER_SOFTWARE'} . "\n";
$content = $content . "SERVER_NAME = " . $ENV{'SERVER_NAME'} . "\n";
$content = $content . "GATEWAY_INTERFACE = " . $ENV{'GATEWAY_INTERFACE'} . "\n";
$content = $content . "SERVER_PROTOCOL = " . $ENV{'SERVER_PROTOCOL'} . "\n";
$content = $content . "SERVER_PORT = " . $ENV{'SERVER_PORT'} . "\n";
$content = $content . "REQUEST_METHOD = " . $ENV{'REQUEST_METHOD'} . "\n";
$content = $content . "HTTP_ACCEPT = '" . $ENV{'HTTP_ACCEPT'} . "\n";
$content = $content . "PATH_INFO = " . $ENV{'PATH_INFO'} . "\n";
$content = $content . "PATH_TRANSLATED = " . $ENV{'PATH_TRANSLATED'} . "\n";
$content = $content . "SCRIPT_NAME = " . $ENV{'SCRIPT_NAME'} . "\n";
$content = $content . "QUERY_STRING = " . $ENV{'QUERY_STRING'} . "\n";
$content = $content . "REMOTE_HOST = " . $ENV{'REMOTE_HOST'} . "\n";
$content = $content . "REMOTE_ADDR = " . $ENV{'REMOTE_ADDR'} . "\n";
$content = $content . "REMOTE_USER = " . $ENV{'REMOTE_USER'} . "\n";
$content = $content . "CONTENT_TYPE = " . $ENV{'CONTENT_TYPE'} . "\n";
$content = $content . "CONTENT_LENGTH = " . $ENV{'CONTENT_LENGTH'} . "\n";

my $to = "To: YOUREMAIL\@YOURDOMAIN.com\n";

open(SENDMAIL, "|$sendmail") or die "Cannot open $sendmail: $!";
print SENDMAIL $reply_to;
print SENDMAIL $subject;
print SENDMAIL $to;
print SENDMAIL "Content-type: text/plain\n\n";
print SENDMAIL $content;
close(SENDMAIL);


print "Content-type: text/html\n\n";
print <

Step 2: Place it in your script alias path and set it as the error document for 503 errors

...edit your httpd.conf file...
ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
ErrorDocument 503 /cgi-bin/error.pl

Step 3: Allow it to run (chmod a+x error.pl)
Step 4: Tell modd proxy to leave /cgi-bin scripts alone

...insert before your RewriteRule that proxies requests...
RewriteCond %{REQUEST_URI} !^/cgi-bin

No comments: