#!/opt/perl/bin/perl

#######################################################################
# Author: Shawn M. Emery
# Date  : 9/15/97
# Program: statAgent.pl
#
# Revision History:
#
# 9/15/97 : Parse vmstat data.
# 9/17/97 : Parse ping data.
# 10/18/97: Communication to gatherer implementation.
# 11/3/97 : Parse web server statistics.
#######################################################################

use Socket;
use IO::Socket;
use Sys::Hostname;

$webServer = hostname();

$httpPort = "8080";

&processParams();

&configureInterface();

while (1)
  {
  &processVmstat();

  &processPing();

	&configureTcpInterface($webServer, $httpPort);

	&processWebStats();

	&processMsg("data");

	&sendMsg();

  sleep $updates;
  }

sub processParams
{

  if ($#ARGV == 2)
		{
  	$gateway = $ARGV[0];

		$server = $ARGV[1];

		$updates = $ARGV[2];
		}
	else
		{
		print "\nUsage: statAgent.pl <gateway> <server> <updates>\n\n";

		exit(1);
		}

}

sub processMsg
{

	($type) = @_;

	$messageString = "$type:cpuUsage:$cpuUsage:avgPing:$avgPing:runQueue:$runQueue:swapOut:$scanRate:rps:$rps:busy:$busy:idle:$idle";

	#print "messageString: $messageString\n";

}

sub sendMsg
{

	($ia, $p) = sockaddr_in($serverpaddr);

	#print "ia, p: $ia, $p\n";

	defined(send(SOCKET, $messageString, 0, $serverpaddr)) or print STDERR "\nsend $server: $!\n\n"; 

}

sub Alarm
{

	($alarmMsg) = @_;

	print "$alarmMsg thresh hold has been reached\n";

	&sendMsg($alarmMsg);

}

sub configureInterface
{

  $iaddr = gethostbyname(hostname());

  #print "iaddr: $iaddr\n";

  $proto = getprotobyname('udp');

  # Make sure /etc/services has the wlb udp entry
  $port = getservbyname('wlb', 'udp');

  $paddr = sockaddr_in(0, $iaddr);

  socket(SOCKET, PF_INET, SOCK_DGRAM, $proto) or die "socket: $!";

  bind(SOCKET, $paddr)                        or die "bind: $!";

	$serveriaddr = inet_aton($server) or die "unknown host";

	$serverpaddr = sockaddr_in($port, $serveriaddr);

}

sub configureTcpInterface
{

	local ($webServer, $httpPort) = @_;

	$sockaddr = 'S n a4 x8';

	$clientHost = hostname();

	$clientPort = (getservbyname('wlbTcp', 'tcp')) [2] unless $port =~ /^d+$/;;

	$client = pack ($sockaddr,
									&AF_INET,
									$clientPort,
									(gethostbyname($clientHost)) [4]);

	$server = pack ($sockaddr,
									&AF_INET,
									$httpPort,
									(gethostbyname($webServer)) [4]);

	socket (S, &PF_INET, &SOCK_STREAM, (getprotobyname('tcp')) [2]) ||
		die "socket: $!";

	bind (S, $client) || die "bind: $!";

	connect (S, $server) || die "connect: $!";

	select (S);

	$| = 1;

	select (STDOUT);

}

sub processWebStats
{

	local ($request = "/server-status");

	print S "GET $request\n";

	#print STDOUT "GET $request\n";

	while (<S>)
		{
		$rps = "$1$2" if (m|(\d*.\d*)\ requests/sec|);

		$busy = $1 if (m|(\d+)\ requests\ currently|);

		$idle = $1 if (m|(\d+)\ idle|);
		}

	close (S);

	#print "rps: $rps\n";
	#print "busy: $busy\n";
	#print "idle: $idle\n";
}

sub processPing
{
  $pingString = `ping -s $gateway 56 1`;

  $pingString =~ s/[a-zA-Z]|\=|\_|\:|\-|\%|\,|\(|\)//g;

  $pingString =~ s/\// /g;

  @pingElements = split(/\s+/, $pingString);

  $elements = scalar(@pingElements);

  $avgPing = $pingElements[$elements-2];

  #print "Network Latency to GW: $avgPing\n";
}

sub processVmstat
{
  &processVmString();

  &processRunnable();

  &processCPU();

  &processScanRate();
}

sub processVmString
{

	$vmString = `vmstat 1 2`;
	#print "$vmString\n";

	$vmString =~ s/\D+/\:/g;
	#print "$vmString\n";

	@vmElements = split(/:/, $vmString);
}

sub processRunnable
{

	$runIndex = 25;

	#print "Runnable: $vmElements[$runIndex]\n";

	$runQueue = $vmElements[$runIndex];

	#if ($runQueue > 0)
  	#{
  	#&printError("Warning: Runnable Queue Greater than 0\n");
  	#}
}

sub processCPU
{

	$cpuIndex = 46;

	#print "CPU: $vmElements[$cpuIndex]\n";

	$cpuUsage = $vmElements[$cpuIndex];

	#if ($cpuUsage < 50)
  	#{
  	#&printError("Warning: CPU usage is high\n");
  	#}
}

sub processScanRate
{

	$scanRateIndex = 36;

	#print "Scan Rate: $vmElements[$scanRateIndex]\n";

	$scanRate = $vmElements[$scanRateIndex];

	#if ($scanRate > 0)
  	#{
  	#&printError("Warning: scan rate is high\n");
  	#}
}

sub printError
{
  ($errorMessage) = @_; 

  print "$errorMessage";
}
