Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Monitor your website performance and uptime with Perl

0.00/5 (No votes)
3 Aug 2004 7  
Receive email notification if your website is down or slow.

Sample Image - backlog.gif

Introduction

Be notified if your website is down or slow.

What it does

This simple Perl script is designed to run on a schedule. If you are on Windows, you can use the Windows Task Scheduler, if you are on Linux, you can run schedule it as a Cron job. The script will check a website, actually "grab" the default page, then record how long this takes. You can then receive an email if the page is down, or if the response time is greater than what you have set.

How it works

The script has 3 files.

  • URLS.txt - This file holds all the URLs (websites) that you wish to check. Each URL is on one line. This makes it easy to update and change your list without having to dig into the Perl script.
  • SMTP_Settings.txt - This file holds the SMTP settings that the script should use to send the notifications, as well as who to send it to. Again, these settings are located out of the script in a text file to make things easier to change.
  • responser.pl - Is the script that does the task of checking the website and attempting to grab the default file. You do need to set your minimum response time that is acceptable to you within the script itself. Keep in mind that if the connection you are running the script from is slow, you may also hit your response time limit, thus triggering the email.

Other files created by the script:

The script will also create an error file, where any reported errors are written to. This is handy for troubleshooting, this file can be deleted at anytime.

The script will also create a daily log file each time it's run. The daily log file will append, so each day you'll have a record of what happened.

The complete script with the readme file can be downloaded for free from here.

Sample output from the log file:

******************************************************
+--------------------------------------------------------------------------------+
|                              Time: 23:26:31                                    |
|          HOST                                  STATUS       RESPONSE           |
+--------------------------------------------------------------------------------+
| http://www.yahoo.com/                          ACCESSED   Response 1 seconds   |
| http://www.hotmail.com/                        ACCESSED   Response 1 seconds   |
| http://www.ebay.com/                           ACCESSED   Response 1 seconds   |
| http://www.example.com/                        ACCESSED   Response 0 seconds   |
| http://www.not/ a real site.com                WRONG       N/A                 |
+--------------------------------------------------------------------------------+
|                              Time: 23:30:17                                    |
|          HOST                                  STATUS       RESPONSE           |
+--------------------------------------------------------------------------------+
| http://www.yahoo.com/                          ACCESSED   Response 0 seconds   |
| http://www.hotmail.com/                        ACCESSED   Response 0 seconds   |
| http://www.ebay.com/                           ACCESSED   Response 1 seconds   |
| http://www.example.com/                        ACCESSED   Response 0 seconds   |
| http://www.not/ a real site.com                WRONG       N/A                 |
+--------------------------------------------------------------------------------+
|                              Time: 23:31:26                                    |
|          HOST                                  STATUS       RESPONSE           |
+--------------------------------------------------------------------------------+
| http://www.yahoo.com/                          ACCESSED   Response 0 seconds   |
| http://www.hotmail.com/                        ACCESSED   Response 1 seconds   |
| http://www.ebay.com/                           ACCESSED   Response 0 seconds   |
| http://www.example.com/                        ACCESSED   Response 0 seconds   |
| http://www.not/ a real site.com                WRONG       N/A                 |
#!/usr/bin/perl
use warnings;
use strict;
use Tie::File;
use Net::SMTP;
use LWP::UserAgent;

#################################################################
#             Program  Settings
#
my $error_log  = 'Responser_errors.txt';# File to store errors of program
my $input_file = 'urls.txt';       # From where program will read WEB Addresses
my $smtp_file  = 'SMTP_Settings.txt';   # File for SMTP Settings
my $response_limit = 12; #In Seconds    # Positively diggit -> SendMail;
                                        #        0 -> will not send mail
my $send_mail  = 1;                # my $send_mail  = 1; ->SMTP option is ON,
                                   # my $send_mail  = 0; ->SMTP option is OFF
##################################################################
#                      END OF SETTINGS
# Do not edit bellow if you dont understand it.
##################################################################
die "File $input_file is not exist\n" unless (-e $input_file);
die "SMTP is ON, but file $smtp_file is not exist\n" unless (-e $smtp_file);
my $localtime     = localtime;
our @errors;
my ($day,$month,$date,$hour,$year) = split /\s+/,scalar localtime;
my $output_file = 'report-'.$date.'.'.$month.'.'.$year.'.txt';
my ($smtp_host,$recipient,$reverse_path, @all_addr) = ();
tie @all_addr, 'Tie::File', 
    $input_file or error("Cant open $input_file to read addresses");
if (-e $output_file) {
   open(OUT,">> $output_file") 
      or error("Cant open exist file $output_file for append");
} else {
   open(OUT,"> $output_file") 
      or error("Cant open new file $output_file for writting");
}
my @smtp_settings;
if ($^O =~ /win/i) {
        tie @smtp_settings, 'Tie::File', $smtp_file,, 
            recsep => "\012" 
            or error("Cant open $smtp_file to read SMTP settings");
} else {
tie @smtp_settings, 'Tie::File', $smtp_file,autochomp => '0' 
    or error("Cant open $smtp_file to read SMTP settings");
}
for (@smtp_settings) {
   chomp;
   next if /^#/;
   #next if /^$/;
 if (/^(\w+)\s=\s'(\S+)'/) {
   $smtp_host     = $2 if ($1 eq 'SMTPHost');
   $recipient     = $2 if ($1 eq 'Recipient');
   $reverse_path  = $2 if ($1 eq 'Reverse');
 }
}
print OUT "\n+" .('-' x 84) . "+\n";
print OUT   "|", ' ' x 30,"Time: $hour",' ' x 40,"|\n";
print OUT   "|",' 'x 10,'HOST',' ' x 37,'STATUS',' ' x 7, 
                               "RESPONSE            |\n";
print OUT   "+" .('-' x 84) . "+\n";
for (0 .. $#all_addr) {
 chop $all_addr[$_] if ($all_addr[$_] =~ /\s+$/);
 next if ($all_addr[$_]  eq "");
 if ($all_addr[$_] =~ /^http:\/\/\S+\.\w{2,4}$/) {  
      #address will beginnig with http://,next some string
      # finish with point and 2 to 4 letters
   check_url($all_addr[$_]);    #call subroutine check_url()
 } else {
   my $out_format = sprintf "| %-50.50s %-10s  %-20s|\n", 
                           $all_addr[$_], "WRONG", "N/A";
   printf OUT $out_format;
   printf $out_format;
         push @errors, "$all_addr[$_] is WRONG Address.";
 }
}

my $err = join "\015\012",@errors;
my $err_num = scalar @errors;  # How match DOWN + WRONG Sites have
$send_mail = 0 unless $err_num;
untie @all_addr or error("Unable to close file $input_file");
if ($send_mail) {
 my $smtp = Net::SMTP->new($smtp_host,
                    -Debug=>1,
                    -Timeout=>20,
                    -Hello=>"$smtp_host") 
                        or error("Cant connect to $smtp_host");
# Begin Compare mail message
my $msg = <<__END_OF_MAIL__;
To: $recipient
Subject: $err_num Error Sites | $localtime .
$localtime
$err

__END_OF_MAIL__
# End Compare

 $smtp->mail("$reverse_path") 
       or error("Failed to specify a reverse-path");#  If all is OK
 $smtp->to($recipient) 
       or error("Failed to specify a recipient");   #  that will
 $smtp->data([$msg]) 
       or error("Failed to send a message");     #  send mail
 $smtp->quit or error("Failed to quit");         #  to You
} else {
  print "Send Mail is OFF\n" if $err_num; # If you do not wish to receive mail
}

close OUT or error("Unable to close file $output_file");
print "\nProcess FINISH\n";

sub check_url {  # subroutine who check given URL
    my $target = $_[0];
        my $ua = LWP::UserAgent->new;
        $ua->agent("$0/0.1 " . $ua->agent);
        my $req = HTTP::Request->new(GET => "$target");
        $req->header('Accept' => 'text/html');          #Accept HTML Page
        # send request
        my $start = time;      # Start timer
        my $res = $ua->request($req);
        # check the outcome
        if ($res->is_success) {
        # Success....all content of page has been received
          my $time = time;     # End timer
          my $out_format;
          $time = ($time - $start); # Result of timer
          if ($response_limit && ($response_limit <= $time)) {
             push(@errors, "Slow response from $target\: $time seconds");
             $out_format = sprintf "| %-50.50s %-10s %-20s |\n", 
                      $target, "SLOW", "Response $time seconds";
          } else {
             $out_format = sprintf "| %-50.50s %-10s %-20s |\n", 
                  $target, "ACCESSED", "Response $time seconds";
          }
          print OUT $out_format; # write to file
          print $out_format;     # print to console
        } else { # Error .... Site is DOWN and script send e-mail to you..
          my $out_format = sprintf "| %-50.50s %-10s %-20s |\n", 
                                          $target, "DOWN", " N/A";
          push(@errors, "$target is DOWN." . $res->status_line) 
                           or error("Cannot push error for DOWN");
          print OUT $out_format; # write to file
          print $out_format;     # print to console
    }
}
sub error {      # subroutine who print in Error Log
  my $error_msg = shift;
  open ERR,">> $error_log" 
       or die "Cannot open log file $error_log : $!\n";
  print ERR "$localtime\: $error_msg : $!\n";
  close ERR or die "Cannot close log file $error_log : $!\n";
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here