#!/usr/bin/perl # Copyright 2007, Robert Auch, totalnetsolutions.net. # This script accesses websites and sends an email ONLY if # one of them is down (avoiding false-positives). # This script requires chk-web.ini to work properly. # Formatting of chk-web.ini explained inside parseIni() # chk-web.ini created automatically with initial data if it's missing # Mail server settings stored in %mailSettings after read from INI use strict; #use warnings; use LWP::UserAgent; use HTTP::Request; use Tie::File; use Config::IniFiles; use Net::SMTP; my (@webs, @upwebs, %mailSettings); my ($searchString, $sendMail, $errorLog, $responseLimit, $localtime, $outputLog); my ($el, $data, $name, $temp, $error, @badResponses); my $iniFile="./chk-web.ini"; # Change this to change the INI file in use. # You can set this to a non-existant file, or delete the INI file that was sent to you, # and this program will create a blank one with all possible values filled with dummy # data. Change all parameters in there, except for the path and $debug below. my $debug=0; # Change this to 1 to print all sorts of odd debug info to STDOUT $errorLog="webcheck-errors.log"; $error = parseIni($iniFile); if ($error) { error($error); die "Error with INI File: $error\n"; } $localtime=localtime; $debug && print scalar localtime, "\n"; my ($day,$month,$date,$hour,$year) = split /\s/, $localtime; $debug && print "$outputLog-$date.$month.$year.txt"; $outputLog = "$outputLog-$date.$month.$year.txt"; if (-e $outputLog) { open(OUT,">> $outputLog") or error("Cant open exist file $outputLog for append"); } else { open(OUT,"> $outputLog") or error("Cant open new file $outputLog for writing"); } $debug && print "Successfully parsed INI file\n"; foreach $el (@webs) { check_url($el); $debug && print "tested $el\n"; } $debug && print "$#badResponses down URLs and $#webs URLs\n"; if ($#badResponses>=0) { $debug && print "mailing about $el\n"; $error=sendMail($el); $debug && $error && print "mail error is $error\n"; $error && error($error); $error && die ("$error\n"); } exit 0; 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 ($responseLimit && ($responseLimit <= $time)) { push(@badResponses, "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 $debug && 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(@badResponses, "$target is DOWN." . $res->status_line) or error("Cannot push error for DOWN"); print OUT $out_format; # write to file $debug && print $out_format; # print to console } } sub error { # subroutine who print in Error Log my $error_msg = shift; $debug && print "$error_msg\n"; if (-e $errorLog) { open(ERR,">> $errorLog") or error("Cant open exist file $errorLog for append"); } else { open(ERR,"> $errorLog") or error("Cant open new file $errorLog for writing"); } open (ERR, "@>> $errorLog") or print "Cannot open log file $errorLog : $!\n"; print ERR "$localtime\: $error_msg : $!\n"; print "$localtime\: $error_msg : $!\n"; close ERR or die "Cannot close log file $errorLog : $!\n"; exit 1; } sub makeIni { my $confFile = shift; my $error; my $cfg = new Config::IniFiles (); unless ($cfg->SetFileName($iniFile)) { return "Could not create or set file name. $!"; } unless ($cfg->AddSection ("WebServers")) { return "Could not add 'WebServers' section. $!"; } unless ($cfg->AddSection ("MailSettings")) { return "Could not add 'MailSettings' section. $!"; } unless ($cfg->AddSection ("Logging")) { return "Could not add 'Logging' section. $!"; } unless ($cfg->newval("WebServers", "URLList", "http://www.google.com", "http://www.hotmail.com")) { return "Could not set 'URLList' parameter. $!"; } unless ($cfg->newval("WebServers", "SearchString", "