Click here to Skip to main content
Email Password   helpLost your password?

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.

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";
}
You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
Questionsend email notification for a specific error message appearing on the website
mohankz
22:21 27 Apr '09  
Hi,

The script is really useful for administrating a site.
But I need to customize it for us.

I'm new to Perl and just started working on this.
I need to create a perl script which sends notificaton email for a specific error message which appeans when a website is accessed.

The thing is that the web site is loaded correctly with the whole content of the page but with an error sometimes. I've to send the notification if this specific error message appears while accessing the URL. Can you please suggest a way out for this or some reference/s etc.?

Thanks in anticipation.

Regards,
MohanZ
Generalquerystring value in url
sankarmca
19:08 1 Nov '06  
hi
your script shows an error msg as 'wrong url' while querysting value is appended in the url. tell me how should i validate url in your script.

Sankar
GeneralMonitor Script does not send alert email
sonny2
12:20 27 Jan '06  
Hi
this Monitor script does not email
I need to have a password and user for smtp
its not safe to leave your mail server open without
a password at least.

is there a way to set this up to use localhost sendmail or qmail?

Thanks Sonny
GeneralCouple ideas
dmoses
8:11 18 Apr '04  
Hi,

I like your project, simple yet effective.

Couple ideas:

a) Maybe add "use Time::HiRes qw ( time );" as a drop in replacement for the time function. Since many sites load in 1 - 3 seconds, maybe a higher resolution would be nice. If you do this I would move the 2nd time call to directly after the http request. I always like to use timers like this 1) get time 2) minimal op's required 3) get time. Not that the 'if' statement takes any real length of time, but its nice to be as accurate as possible..why not.

b) Your project inspired me to create my own. Rather than a logfile I just insert the time of day, and response time into a SQL database. I then used another page to query the database and graph it. Although this requires a database and graphing software, there are free ones available. It's nice to have a visual representation of the trends. Also putting the data into a database, allows for all kinds of processing, and statistics to be run against it. For Example what is the avg for a day/week/month, what is the longest wait, what is the average of the highest 5%, etc.

Cheers, nice work!
GeneralRe: Couple ideas
Anonymous
18:36 26 Sep '05  
I'm inclined to agree with dmoses. the measure of time it takes for the response is far too granular to be of any real value.

Also, I would recommend that you check the list no more than 10 times each cycle that the script runs instead of a single check. What this will do is provide you with greater entropy from which to derive a true messue of site performance. Conditions that exist at the time of one request, may not exist at another, so with time between requests, you can more accurately judge the performance.
Generalthoughts...
l a u r e n
11:32 7 Apr '04  
interesting idea but surely...

what if the delay is ur link to the net rather than ur server?
how can it email me if its truly down?

are issues that need to be addressed no?

nice idea tho as i said
Smile


"there is no spoon"
biz stuff   about me
GeneralRe: thoughts...
vander25
12:04 7 Apr '04  
Well there are 2 checks going on, it will email you if it is down, as in 404, or no connection. And it will also email you if the response time is greater than x. So as long as the connection you are running the script from is okay, then you will get an email if it is really down.

Smile

-Mike

www.aspcontentmanagement.com
GeneralRe: thoughts...
l a u r e n
12:11 7 Apr '04  
is this your product?

so ur saying the mail server could be outside of ur webserver
ok that works
Smile


"there is no spoon"
biz stuff   about me
GeneralRe: thoughts...
darthzep
10:02 11 Mar '09  
this looks like it might be a dead project.. no updates in 5 years, but here's something that may help others..

strictly speaking the line:
die "SMTP is ON, but file $smtp_file is not exist\n" unless (-e $smtp_file);

is wrong, it should be something more like:

if ($send_mail){
die "SMTP is ON, but file $smtp_file is not exist\n" unless (-e $smtp_file);
}

otherwise you have to have a smtp config file even if you aren't using SMTP.
or I suppose you could just change the error message to somehting like
"I require $smtp_file even if I'm not using it"

it'd also be kinda handy to have an example smtp config file, but that's another story.

not really sure how this provides anyone much of anything in the way of stats. it's a start for what I want to do, I suppose. thanks for that.


Last Updated 4 Aug 2004 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010