Wednesday, April 1, 2009

Perl script to send alert notification email

We usually have a bunch of automated tasks running at different schedules and it is not feasible to keep monitoring them in person. It is almost always need to have some kind of email alert notification at the minimum in place to get notifications when something suspicious happens in the scheduled tasks running. The Perl script below addresses to that minimum requirement. One can always improvise and add further features to it or have it incorporated can called from your java (or any other) programs etc.

The script has one subroutine msgSender.

eval{
}
or do {
};

In the eval block we will trap any exception thrown in the msgSender subroutine and in or do block we will handle that exception by logging it.
First we need to open the file to read the list of send email addresses from the file.

open (SENDTOLISTFILE, $sendToList ) or die("Could not open sender list file.");
while (my $line = <SENDTOLISTFILE>) {
    chomp($line);
    push(@sendTo,$line);
}
close(SENDTOFILE);

chomp($line) actually chops off \n from the line we read and we are copying the line read in an array defined by sendTo. At the end we close the file.

Next we read the subject of the email and content to be sent as arguments. If you only have one task running, you can have your subject and message hardcoded.

my $messageSubject = $_[0];
my $messageContent = $_[1];

Now comes the actual part of setting up the SMTP server for send the email notification.

# Setup SMTP mail server to send the alert email
use Net::SMTP;
$smtp = Net::SMTP->new('SMTP_SERVER_INFO'); # connect to an SMTP server
$smtp->mail('alertNotify@YOUR_DOMAINNAME.com'); # use the sender's address here
for($count = @sendTo; $count>0 ; $count--)
{         
    $sendToVal = $sendTo[$count-1];
    $smtp->to($sendToVal);            # recipient's address
}
$smtp->data(); # Start writing the mail
        
# Send the header.    
$smtp->datasend("To: alertNotify\@YOUR_DOMAINNAME.com\n");
$smtp->datasend("From: alertNofity\@YOUR_DOMAINNAME.com\n");
$smtp->datasend("Subject: $messageSubject\n");
$smtp->datasend("\n");
        
# Send the body.
$smtp->datasend("This is a Broadcast Message. Please DO NOT reply to this email. It is not monitored\n");
$smtp->datasend("------------------------------------------------------------------------------------------\n");
$smtp->datasend("$messageContent\n");
$smtp->dataend(); # Finish sending the mail
$smtp->quit; # Close the SMTP connection

Update SMTP_SERVER_INFO with your smtp server info and update the sender addresses with your sender email address.

Once we have the SMTP server info set, we need to setup the header and body info. At the end we end the email with the quit statement.

At the end we log errors if any.

or do{
my $errorLogging = "C:/logs/alertNotify.err";
open(LOG,">$errorLogging") || die("Cannot Open File");
print LOG "alertNotify:$@";
close(LOG);
exit(-1);
};

Or do block is reached only if the eval block throws an exception which is captured in $@ variable.

Instead of or do block we can also use the eval block in combination with if condition as below to capture and log errors.

eval{
...
};
if($@){
my $errorLogging = "C:/logs/alertNotify.err";
open(LOG,">$errorLogging") || die("Cannot Open File");
print LOG "alertNotify:$@";
close(LOG);
exit(-1);
}

Feel free to post comments and questions here or at bhawnablog@gmail.com

Putting it all together…the complete Perl script is below

#!/usr/bin/perl

msgSender($ARGV[0],$ARGV[1]);
 

sub msgSender{
eval{    
        #Read the email sendTo list from the txt file
        my $sendToList = "C:/alerts/sendToList.txt";
        
        #Open Pipe to the sendTo list file
        open (SENDTOLISTFILE, $sendToList ) or die("Could not open sender list file C:/alerts/sendToList.txt");
         while (my $line = <SENDTOLISTFILE>) {
            chomp($line);
             push(@sendTo,$line);
        }
        close(SENDTOFILE);
        
        #Read arguments for subject and content
        my $messageSubject = $_[0];
        my $messageContent = $_[1];
        
        # Setup SMTP mail server to send the alert email
        use Net::SMTP;
        
        $smtp = Net::SMTP->new('SMTP_SERVER_HOST'); # connect to an SMTP server
        $smtp->mail('alertNotify@YOUR_DOMAINNAME.com'); # sender's address here
        for($count = @sendTo; $count>0 ; $count--)
        {         
            $sendToVal = $sendTo[$count-1];
            $smtp->to($sendToVal);            # recipient's address
        }
        $smtp->data(); # Start writing the mail
        
        # Send the header.    
        $smtp->datasend("To: alertAlias\@YOUR_DOMAINNAME.com\n");
        $smtp->datasend("From: alertNofity\@YOUR_DOMAINNAME.com\n");
        $smtp->datasend("Subject: $messageSubject\n");
        $smtp->datasend("\n");
        
        # Send the body.
        $smtp->datasend("This is a Broadcast Message. Please DO NOT reply to this email. It is not monitored\n");
        $smtp->datasend("------------------------------------------------------------------------------------------\n");
        $smtp->datasend("$messageContent\n");
        $smtp->dataend(); # Finish sending the mail
        $smtp->quit; # Close the SMTP connection        
    }
    or do{
            my $errorLogging = "C:/logs/alertNotify.err";
            open(LOG,">$errorLogging") || die("Cannot Open File");
            print LOG "alertNotify:$@";
            close(LOG);
            exit(-1);
    };        
    exit(0);    
}