#!/bin/perl

# File        : mon_taskpsec.pl
#
# Objective   : Monitor the number of tasks per second for a specific component
#
# Argument(s) : 0  component e.g. "WfProcMgr" 
#
# Returns     : Positive integer     number of active concurrent users
#
# Date (yyyymmdd)   Who              What
# ---------------   --------------   -------------------------------------------------
# 2006 10 18        Peter van Nes    Initial release

# Include libraries
use Socket;
use Net::Domain ;

# Restrict unsafe constructs
use strict ;

# Declare lexical variables
my($port) = "3456" ;                # siebcmdserver portnumber
my($sk) = "AF13BAA8A078E4CF" ;      # siebcmdserver sessionkey
my($line) = "" ; 
my($comp) = $ARGV[0] ;
my(%tskcount) = () ;
my($sumtsk) = 0 ;

if ($#ARGV != -1) {

  # Get (FQDN) hostname, siebcmdserver is considered to be on the same host
  my($fqnode) = Net::Domain::hostfqdn() ;
  my($node) = Net::Domain::hostname() ;
  
  # submit srvrmgr command through siebcmdserver
  # list tasks for comp WfProcMgr show TK_START_TIME,TK_END_TIME,TK_DISP_RUNSTATE
  my($svroutput) = mysrvrmgr($fqnode,$port,$sk,"list tasks for comp \"$comp\" show TK_START_TIME,TK_END_TIME,TK_DISP_RUNSTATE") ;
  
  # Check if session with siebcmdserver failed
  if ($svroutput !~ m/^FAILED/) {
    # Session OK, parse valid rows
    foreach $line (split(/\n/,$svroutput)) {
      if ($line =~ m/^(\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2})\s*(\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2})\s*(.*)$/i) {
        $tskcount{$1}++ ;
      }
    }
  
    # Count the number of tasks per second
    foreach (keys(%tskcount)) {
      $sumtsk += $tskcount{$_} ;
    }
  
    if (keys(%tskcount ) != 0) {
      # Calculate and print the average  
      print int($sumtsk/keys(%tskcount)) . "\n" ;
    }
    else {
      print "0\n" ;
    }
  }
  else {
    # Print error
    print "-1\n" ;
    print "$svroutput" ;
  }

}
else {
  # Print error
  print "-1\n" ;
  print "Specify component name as an argument\n" ;
}

exit ;

## Subroutine mysrvrmgr
##
## Compatible with siebcmdserver 1.24 based on mysrvrmgr.pl 1.22
##
sub mysrvrmgr {

  my($remote,$port,$sk,$cmd) = (@_) ;

  # Declare variables
  my ($iaddr, $paddr, $proto);
  my ($dread) = "" ;
  my ($eod) = "" ; 
  my ($soutput) = "" ;

  # Get protocol number
  $proto   = scalar(getprotobyname('tcp')) ;

  ## Open port and attempt to connect
  if ($iaddr = inet_aton($remote)) {
    $paddr = sockaddr_in($port, $iaddr);
    ## Create a TCP socket
    if (socket(SOCK, PF_INET, SOCK_STREAM, $proto)) {
      ## Connect to the server
      if (connect(SOCK, $paddr)) {
        ## send the supplied srvrmgr command 
        send(SOCK,"$sk $cmd",0) ;
        ## wait for response for 60 seconds
        eval {
          local $SIG{ALRM} = sub { die "Timed Out!\n" };
           # save the previous alarm value
           my $previous_alarm = alarm(60);
           my $buffer = "" ;
           while (($eod ne "1") && ($dread !~ m/$sk\sFAILED/)) {
             ## If data is received
             if ( defined (recv(SOCK, $dread, 240, 0)) ) { 
               ## Put data in buffer
               $buffer .= $dread ;
               ## Check buffer for EOD marker and remove marker if found
               $eod = ($buffer =~ s/(.*)$sk END/$1/) || ($buffer =~ m/$sk\sFAILED/) ;
               ## Display complete received lines  and remove them from the buffer 
               while ($buffer =~ s/^(.*)\n(.*)/$2/g) {
                 $soutput .= "$1\n" ;
               }
             } ;
           }
          alarm($previous_alarm) ;
        } ;
  
        if (! $eod) { 
          $soutput = "FAILED Timeout with siebscmdserver occured\n" ;
         } ;
       
      }
      else {
        $soutput = "FAILED Failed to connect to $remote ($!)\n" ;
      }
    }
    else {
      $soutput = "FAILED Failed to create socket ($!)\n" ;
    }
  }
  else {
    $soutput = "FAILED Failed to find host for IP address \"$remote\"\n" ;
  }
  
  close (SOCK) ;
 
  return ($soutput) ;
 
}

