Thursday, August 3, 2017

Perl Webpage status checker

How to check webpage status using Perl

We have several web pages that we needs to be monitored from outside of our work network especially after a maintenance window. I didn't want to do this manually (ever again), so I wrote a Perl script to run on my Linux server (laptop) from home.

This is the header portion. I imported these modules to be used by my script. Line 3 turns any expression that is deemed difficult to debug into error. And line 4 enabled optional warnings.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#!/usr/local/bin/perl
## to install modules, follow instruction from http://www.cpan.org/modules/INSTALL.html
use strict;
use warnings;
use WWW::Mechanize;
use HTTP::Cookies;
use IO::Socket::SSL;
use Email::Sender::Simple qw(sendmail);
use Email::Sender::Transport::SMTPS ();
use Email::Simple ();
use Email::Simple::Creator ();
use WWW::Wunderground::API;
use Try::Tiny;
binmode STDOUT, ':utf8'; # for degrees symbol

----
Below is to use Weather Underground API. You must obtain your own free API key to use.
1
2
3
4
5
my $weather = new WWW::Wunderground::API(
    location => 'pws:XXXXXXXXXX',
    api_key  => '1111111111111111',
    auto_api => 1,
);

---
In the below code, we paste Message of the Day to our email body and get a list of URLs from a file.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
## For debugging purposes
#my $outfile = "/home/me/Documents/perl/output.htm";

## Message of day
my $motd = `exec /usr/games/fortune | /usr/games/cowsay -n`;

## List of websites to check from outside
my $filename = '/home/me/Documents/perl/serverlist.txt';
open(my $fh, '<:encoding(UTF-8)', $filename)
 or die "Could not open file '$filename' $!";

---
Below is the main section used to loop through the list of URLs and check their status using a function call (last block of codes below). In line 10, we also use the WeatherUnderground API to get our temperature.  

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
my $emailbody = "webpage status codes\n";
while (my $text = <$fh>) {
 chomp $text;
 $emailbody = $emailbody  . "$text: ";  
 my $answer = get_answer($text);
  $emailbody = $emailbody  . "$answer\n"; 
}
$emailbody = $emailbody  . "$motd\n"; 

my $currentTemp = $weather->conditions->temp_f;
my $cTempString = "Current Temperature is $currentTemp degrees";
$emailbody = $emailbody  . "$cTempString\n";

##For debugging purposes
#print $emailbody;

---
 The below block of code is to connect to my email service provider and send email to everyone in the address book.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
## Put SMTP authentication information here
my $smtpserver = 'smtp.office365.com';
my $smtpport = 587;
my $smtpuser   = 'me@outlook.com';
my $smtppassword = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
my $tousers='';
## List of email addresses
$filename = '/home/me/Documents/perl/addresses.txt';
open($fh, '<:encoding(UTF-8)', $filename)
  or die "Could not open file '$filename' $!";

while (my $row = <$fh>) {
   chomp $row;
   $tousers = $tousers  . "$row,";  
}
$tousers = $tousers  . "$smtpuser";

##setup the email server connection here
my $transport = Email::Sender::Transport::SMTPS->new({
   host => $smtpserver,
   port => $smtpport,
   ssl => "starttls",
   sasl_username => $smtpuser,
   sasl_password => $smtppassword,
});

##create email object
my $email = Email::Simple->create(
   header => [
      To      => $tousers,
      From    => $smtpuser,
      Subject => 'Status',
   ],
   body => $emailbody,
);

##send the email
sendmail($email, { transport => $transport });

---
The below code is my function that does the actual website checking. Notice the Try-Catch blocks, this is useful for checking webpage status because if the website is unreachable it is a Catch event. Also line 2 shows how we obtain the parameter value for this function call. Be sure to wrap the variable around ().

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
sub get_answer {
 my ($row) = @_;
 try{
  chomp $row;
  ##print "$row\n";
      my $mech=WWW::Mechanize->new(ssl_opts => {
         verify_hostname => 0,
      }); 
     $mech->cookie_jar(HTTP::Cookies->new());
     $mech->get($row);
     ##my $output_page = $mech->content();
     my $output_status = $mech->status();
     ##print $output_page; 
  chomp $output_status;
  return $output_status;
 }catch{
    my $output_status = "Fail";
  return $output_status;
 };
}



No comments:

Post a Comment

AWS WAF log4j query

How to query AWS WAF log for log4j attacks 1. Setup your Athena table using this instruction https://docs.aws.amazon.com/athena/latest/ug/wa...