Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Implementing Web Server Load Balancing, Failover, and State with Squid


Listing 3 check_pservers.pl

#!/usr/bin/perl 
#
#
## Name:         check_pservers.pl - proxy monitoring program
#
## Author:      Tom Northcutt
## Synopsis:    Checks status of various proxy servers
## Description:
#               This script is designed to check the status of
#        various proxy servers and restart them if they
#        have stopped.

# user defined section #####

## HTTP PROXY SERVER CONFIGURATION:
# process name in a ps -C listing
$http_name = "squid"; 
#stop command
my $http_stop = "/etc/init.d/squid stop";
#start command
my $http_start = "/etc/init.d/squid start";

## OTHER PROXY SERVERS (ftp proxy, etc.)
# can be set up here 
# $other_name = "";
# my $other_stop = "";
# my $other_start = "";


# email address of person to receive homepage change warnings
#my $admin_email = q"root@localhost";
my $admin_email = q([email protected]);


# sendmail
my $sendmail = "/usr/lib/sendmail -t";

# end user defined section #####

use Sys::Syslog qw(:DEFAULT setlogsock);
setlogsock "UNIX";

my $used_attempts = 0;
my %start = ();
$start{"$http_name"} = $http_start;
$start{"$other_name"} = $other_start;



## MAIN LOOP ####

##my @proxy  = ($http_name, $other_name);
my @proxy  = ($http_name);

foreach $proxy(@proxy){
  $used_attempts = 0;
  unless (&is_running("$proxy")){
    #we have a down process
    &restart($proxy, 3);
  }
}
1;

## SUBROUTINES ###


##(is_running PROCESS_NAME)
# Given a process name, this routine checks to see if a process
# is currently running.  If the process is up, the pid is 
# returned, otherwise 0.
sub is_running {
  my ($process_name) = @_;

  my @ps_info = `/bin/ps -C $process_name`;
  $null = shift(@ps_info); #first line is ps header info
  my $ps_elem = @ps_info; #num elements in @it #icky perl
  
  my $ps_line = $ps_info[--$ps_elem];
  $ps_line =~ s/^ +//; #ps output varies, remove all leading whitespace

  #in case server forked, process last line 
  my ($pid, @null) = split(/ /, $ps_line);
  return $pid if $pid;
  return 0;
  
}

## (restart PROCESS_NAME, ATTEMPTS)
# Attempts to restart the server specified by PROCESS_NAME.  
# This process will try to restart a problematic server ATTEMPTS 
# times unless a running server is detected.  
sub restart {
  my $proxy = shift;
  my $attempts = shift;

  if ($attempts == 0){     
    unless(&is_running("$proxy")){
      #print error message to syslog
      openlog('check_pservers', 'cons,pid', 'user');
      syslog("notice", "proxy $proxy down, could not be restarted");
      closelog();

      #send error to admin
      mail_admin("PSERVER_ERROR: proxy $proxy down, could not be restarted",
         "After $used_attempts attempts, the proxy server $proxy could\
                  not be successfully restarted with the command:\
                  $start{$proxy}");
      return 0;
    }

  }elsif(&is_running("$proxy")){  
    my $rval = &is_running("$proxy");
    print "proxy $proxy restarted with pid $rval\n";
    openlog('check_pservers', 'cons,pid', 'user');
    syslog("notice", "proxy $proxy down, restarted with pid $rval");
    closelog();
    

    #send error to admin
    mail_admin("PSERVER_NOTICE: proxy $proxy down,restarted with pid $rval ",
           "After $used_attempts attempts, the proxy server $proxy was 
                successfully restarted with the command:\
                $start{$proxy}");
    

    return $rval;

  }else{ #still down w/ more attempts
    system("$start{$proxy}");
    $used_attempts++;
    $attempts--;

    sleep(30); #give it time to either stabilize or die
    &restart($proxy, $attempts); #recursive test
  }
}


## (mail_admin SUBJECT, MESSAGE)
# Send a message to the system administrator leting them know of
# special circumstances. 
sub mail_admin {
  my ($subject,$message) = @_;
  
  open(MAIL, "| $sendmail")
    or die "PROXY-ALERT: Can't fork for sendmail: $!\n";
  
  print MAIL <<"ENDMAIL";
From: $admin_email
To: $admin_email
Subject: $subject

$message
ENDMAIL
  
   close(MAIL);        # close the pipe

}


=head1 NAME

check_pservers.pl - proxy monitoring program

=head1 AUTHOR

Tom Northcutt


=head1 SYNOPSIS

Checks status of various proxy servers


=head1 DESCRIPTION

This script is designed to check the status of
various proxy servers and restart them if they
have stopped.


=head1 SUBROUTINES

=item B<sub is_running(PROCESS_NAME)>

 Given a process name, this routine checks to see if a process
 is currently running.  If the process is up, the pid is 
 returned, otherwise 0.

=item B<sub restart(PROCESS_NAME, ATTEMPTS)>

 Attempts to restart the server specified by PROCESS_NAME.  
 This process will try to restart a problematic server ATTEMPTS 
 times unless a running server is detected.  

=item B<sub mail_admin(SUBJECT, MESSAGE)>

 Send a message to the system administrator leting them know of
 special circumstances. 

=cut


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.