HEX
Server: Apache/2.4.34 (Red Hat) OpenSSL/1.0.2k-fips
System: Linux WORDPRESS 3.10.0-1160.118.1.el7.x86_64 #1 SMP Thu Apr 4 03:33:23 EDT 2024 x86_64
User: digital (1020)
PHP: 7.2.24
Disabled: NONE
Upload Files
File: //var/opt/OV/bin/instrumentation/AT.pm
###############################
# 
# Version : 11.11.025
#
###############################
package AT;

use strict;
use OvTrace;
use OvCommon;

require Exporter;
use vars       qw($VERSION @ISA @EXPORT);

my $catalog = OvCommon::GetCatalog(qw/SystemPerl/);

# set the version for version checking
$VERSION     = 0.01;
@ISA         = qw(Exporter);
@EXPORT      = qw(&WriteTraceLogTest &DoStats &DoThresholds &DoAT);

sub new 
{
	  my $class = shift;
      my ( $policy, $console, $rule, $session ) = @_;
	  my $self = {};
	  $self->{OVOPOLICY} = $policy;
	  $self->{OVOCONSOLEMESSAGE} = $console;
	  $self->{OVORULE} = $rule;
	  $self->{OVOSESSION} = $session;
      $self->{TRACEOBJ}=OvTrace->new($policy,$console,$rule,$session);
	  
	  bless($self, $class);
	  return $self;
}

#`opcmsg a=a o=o msg_t=LoadedModule`;

# This subroutine calculates the std. deviation, average, trust factor and confidence factor for the given sample
sub DoStats {

my $self = shift;

    my($objData) = @_;
    my $nConfidence;

    # On Error Resume Next
    my $nCount;
    my $nValue;
    my $objValue;
    my $nSumOfSquares;
    my $nAvg;
    my $nMin;
    my $nMax;
    my $nAverageAbsoluteDeviation;
    my $nSumOfAbsolutes;

    $nCount = 0;
    my $nItems;
    $nItems = $objData->Count();
    $nMin = $objData->Item(0)->Value;
    $nMax = $objData->Item(0)->Value;

    while ($nCount < $nItems) {
        $objValue = $objData->Item($nCount);
        $nCount = $nCount + 1;
        $nValue = $nValue + 
        $objValue->Value;

        if (_compareValues(

        $objValue->Value, $nMin, 1)) {
            $nMin = $objValue->Value;
        }
        if (_compareValues(

        $objValue->Value, $nMax, 4)) {
            $nMax = $objValue->Value;
        }

    }

    # Calculate the standard deviation.  Numbers closer to 0 are better
    $nAvg = sprintf("%.2f", $nValue / $nCount);
    $nCount = 0;

    while ($nCount < $nItems) {
        $objValue = $objData->Item($nCount);
        $nCount = $nCount + 1;
        my $nResult;
        $nResult = 

        $objValue->Value - $nAvg;

        $nSumOfAbsolutes = $nSumOfAbsolutes + abs($nResult);

        $nSumOfSquares = $nSumOfSquares + ($nResult * $nResult);

    }
    # get the stdDev
    my $nStdDev;
    my $nTemp;
    
    if ($nItems > 1)
    {

    $nTemp = $nSumOfSquares / ($nItems - 1);
    # no bias
    $nAverageAbsoluteDeviation = $nSumOfAbsolutes / $nItems;
    # no bias
    
    $nStdDev = sqrt($nTemp);
    
    }
    else
    {
    	$nTemp = 0;
    	$nAverageAbsoluteDeviation = 0;
    	
    }

    # calculate the trust factor for this data
    my $nTrust = 0;
    
    if ($nMax > 0)
    {
    	$nTrust = (1.0 - ($nStdDev / $nMax)) * 100;
    }
    	
    if ($nTrust < 0) {
        $nConfidence = 0;
    }
    if ($nTrust > 100) {
        $nTrust = 0;
    }
    if ($nItems < 5) {
        $nTrust = 0;
    }

    my $objReturn;
    $objReturn = PerfStat->new();

    $objReturn->{nAvg} = sprintf("%.4f", $nAvg);
    $objReturn->{nPoints} = $nItems;
    $objReturn->{nStdDev} = sprintf("%.4f", $nStdDev);
    $objReturn->{nMin} = sprintf("%.4f", $nMin);
    $objReturn->{nMax} = sprintf("%.4f", $nMax);
    $objReturn->{nRange} = sprintf("%.4f", $nMax - $nMin);
    $objReturn->{nTrust} = sprintf("%.4f", $nTrust);
    $objReturn->{nConfidence} = sprintf("%.4f", $nConfidence);
    $objReturn->{nAvgAbsDev} = sprintf("%.4f", $nAverageAbsoluteDeviation);

    return $objReturn;

}

#Evaluates threshold values based on stats of baseline data and current sample
sub DoThresholds {

    my $self = shift;
    my($objCurrentStats, $objHistoryStats, $MessageApplication, $MajorHighSeverity, $MinorHighSeverity, $WarningHighSeverity, $MajorLowSeverity, $MinorLowSeverity, $WarningLowSeverity, $WarningDeviations, $MinorDeviations, $MajorDeviations, $MinimumValue, $MaximumValue, $DebugLevel) = @_;
    my $nConfidence;
	my $traceObj = $self->{TRACEOBJ};
		
    # max "normal" value (used with stddev later)
    my $WarningMax;

    # min "normal" value (used with stddev later)
    my $WarningMin;
    my $MinorMax;
    my $MinorMin;
    my $MajorMin;
    my $MajorMax;
	
    my $nStdDev;
    $nStdDev = $objHistoryStats->{nStdDev};

    # set up the min and max values for the "normal" baseline.
    # Edits 7-14-06
    # Change from one-two deviation to configurable deviations in parameters list
    # Calculate the Warning Threshold
    $WarningMin = $objHistoryStats->{nAvg} - ($nStdDev * $WarningDeviations);
	$WarningMin = sprintf("%.4f", $WarningMin);
    $WarningMax = $objHistoryStats->{nAvg} + ($nStdDev * $WarningDeviations);
	$WarningMax = sprintf("%.4f", $WarningMax);
    # Calculate the Minor Threshold
    $MinorMin = $objHistoryStats->{nAvg} - ($nStdDev * $MinorDeviations);
	$MinorMin = sprintf("%.4f", $MinorMin);
    $MinorMax = $objHistoryStats->{nAvg} + ($nStdDev * $MinorDeviations);
	$MinorMax = sprintf("%.4f", $MinorMax);
    # calculate the major threshold
    $MajorMin = $objHistoryStats->{nAvg} - ($nStdDev * $MajorDeviations);
	$MajorMin = sprintf("%.4f", $MajorMin);
    $MajorMax = $objHistoryStats->{nAvg} + ($nStdDev * $MajorDeviations);
    $MajorMax = sprintf("%.4f", $MajorMax);
 
    # enforce the "bounds" for the data.	

    if ($WarningMin < $MinimumValue) {
        $WarningMin = sprintf("%.4f", $MinimumValue);
    }
    if ($MinorMin < $MinimumValue) {
        $MinorMin = sprintf("%.4f", $MinimumValue);
    }
    if ($MajorMin < $MinimumValue) {
        $MajorMin = sprintf("%.4f", $MinimumValue);
    }

    # erase results higher than the max sample received (in wild stddev calcs)

    if ($MaximumValue >= 0) {

        if ($WarningMax > $MaximumValue) {
            $WarningMax = sprintf("%.4f", $MaximumValue);
        }
        if ($MinorMax > $MaximumValue) {
            $MinorMax = sprintf("%.4f", $MaximumValue);
        }
        if ($MajorMax > $MaximumValue) {
            $MajorMax = sprintf("%.4f", $MaximumValue);
        }      

    }

    $self->{OVOSESSION}->Value('WarningMax',$WarningMax);
    $self->{OVOSESSION}->Value('MinorMax',$MinorMax);
    $self->{OVOSESSION}->Value('MajorMax',$MajorMax);
    $self->{OVOSESSION}->Value('WarningMin',$WarningMin);
    $self->{OVOSESSION}->Value('MinorMin',$MinorMin);
    $self->{OVOSESSION}->Value('MajorMin',$MajorMin);
    $self->{OVOSESSION}->Value('HistoryAvg',$objHistoryStats->{nAvg});
    $self->{OVOSESSION}->Value('HistoryStdDev',$objHistoryStats->{nStdDev});
    $self->{OVOSESSION}->Value('HistoryAbsDev',$objHistoryStats->{nAvgAbsDev});
    $self->{OVOSESSION}->Value('HistoryTrust',$objHistoryStats->{nTrust});
    $self->{OVOSESSION}->Value('HistorySampleSize',$objHistoryStats->{nPoints});
    $self->{OVOSESSION}->Value('HistoryRange',$objHistoryStats->{nRange});
    $self->{OVOSESSION}->Value('HistoryMax',$objHistoryStats->{nMax});
    $self->{OVOSESSION}->Value('HistoryMin',$objHistoryStats->{nMin});

    $self->{OVOSESSION}->Value('CurrentAvg',$objCurrentStats->{nAvg});
    $self->{OVOSESSION}->Value('CurrentStdDev',$objCurrentStats->{nStdDev});
    $self->{OVOSESSION}->Value('CurrentAbsDev',$objCurrentStats->{nAvgAbsDev});
    $self->{OVOSESSION}->Value('CurrentTrust',$objCurrentStats->{nTrust});
    $self->{OVOSESSION}->Value('CurrentSampleSize',$objCurrentStats->{nPoints});
    $self->{OVOSESSION}->Value('CurrentRange',$objCurrentStats->{nRange});
    $self->{OVOSESSION}->Value('CurrentMax',$objCurrentStats->{nMax});
    $self->{OVOSESSION}->Value('CurrentMin',$objCurrentStats->{nMin});

    my $strTrust;

    my ($nHighThresh, $nMedThresh, $nLowThresh);
    $nHighThresh = 60;
    $nMedThresh = 50;
    $nLowThresh = 40;

    if ($objHistoryStats->{nTrust} > $nHighThresh) {
        $strTrust = 'High';

    }
    elsif ($objHistoryStats->{nTrust} > $nMedThresh && $objHistoryStats->{nConfidence} <= $nHighThresh) {
        $strTrust = 'Medium';
	
    }
    elsif ($objHistoryStats->{nTrust} > $nLowThresh && $objHistoryStats->{nConfidence} <= $nMedThresh) {
        $strTrust = 'Low';
        # don't do anything
         return;

    }
    else {
        $strTrust = 'Unreliable';
        # don't do anything
         return;

    }

    $self->{OVOSESSION}->Value('HistoryTrust',$strTrust);
    
#$self->SendBaselineAlert($MessageApplication, $MajorHighSeverity, ' much higher than normal');   

    # calculate a maximum violation
	
    if ($objCurrentStats->{nAvg} > $MajorMax) 
    {
            $self->SendBaselineAlert($MessageApplication, $MajorHighSeverity, 'much higher than normal');    
  }
    elsif ($objCurrentStats->{nAvg} > $MinorMax ) {
            $self->SendBaselineAlert($MessageApplication, $MinorHighSeverity, 'higher than normal');	
    }
    elsif ($objCurrentStats->{nAvg} > $WarningMax) {
            $self->SendBaselineAlert($MessageApplication, $WarningHighSeverity, 'higher than normal');
    }

    # now look for minimum violation
    if ($objCurrentStats->{nAvg} < $MajorMin) 
    {
            $self->SendBaselineAlert($MessageApplication, $MajorLowSeverity, 'much lower than normal');           
   }
    elsif ($objCurrentStats->{nAvg} < $MinorMin) 
    {
           $self->SendBaselineAlert($MessageApplication, $MinorLowSeverity, 'lower than normal');
    }
    elsif ($objCurrentStats->{nAvg} < $WarningMin) 
    {
            $self->SendBaselineAlert($MessageApplication, $WarningLowSeverity, 'lower than normal');
    }
    
 #  SendConsoleMessage('Baseline Policy', 'Debug', 'DoStats', '', "WMax:$WarningMax \nWMin:$WarningMin \nMiMax:$MinorMax \nMiMin:$MinorMin \nMaMax:$MajorMax \nMaMin:$MajorMin",'normal'); 
 
    if ($DebugLevel ) 
   {
   		$traceObj->WriteTraceLog($DebugLevel, "WarningMax:$WarningMax \nWarningMin:$WarningMin \nMinorMax:$MinorMax \nMinorMin:$MinorMin \nMajorMax:$MajorMax \nMajorMin:$MajorMin");
    }
}

#Sends alert with appropriate severity to HP OM's active message browser
sub SendBaselineAlert {
   
   my($self, $strApp, $strSev, $strCondition ) = @_;
   my $z;
   my $MHTN; my $HTN; my $MLTN; my $LTN;
   if ( $catalog =~ /Perlen/ )
   {
        $catalog = "SystemPerlen.1";
		$MHTN=" much higher than normal";
		$HTN=" higher than normal";
		$MLTN=" much lower than normal";
		$LTN=" lower than normal";
   }
   else
   {
     if ( $catalog =~ /Perlja/ )
     {
        $catalog = "SystemPerlja.1";
     }
     elsif ( $catalog =~ /Perlzh/ )
     {
        $catalog = "SystemPerlzh.1";
     }
     open FP, $catalog;
     while ( <FP> )
     {
      if (/^29/)
      {
        my $num;
        ($num, $z)=split;
        $z =~ s/\\x22/\x22/g;$z =~ s/\\x25/\x25/g;$z =~ s/\\x27/\x27/g;$z =~ s/\\\\/\\/g;$z =~ s/\\\$/@%@%@/g;$z =~ s/(\$[\w_!?]+[\[\{][\w_!?\$]+[\]\}])/$1/eeg;$z =~ s/(\$[\w_!?^]+)/$1/eeg;$z =~ s/@%@%@/\$/g;$z =~ s/\\x24/\x24/g;
        chomp $z;
        $MHTN=$z;
      }
      elsif (/^30/)
      {
        my $num;
        ($num, $z)=split;
        $z =~ s/\\x22/\x22/g;$z =~ s/\\x25/\x25/g;$z =~ s/\\x27/\x27/g;$z =~ s/\\\\/\\/g;$z =~ s/\\\$/@%@%@/g;$z =~ s/(\$[\w_!?]+[\[\{][\w_!?\$]+[\]\}])/$1/eeg;$z =~ s/(\$[\w_!?^]+)/$1/eeg;$z =~ s/@%@%@/\$/g;$z =~ s/\\x24/\x24/g;
        chomp $z;
        $HTN=$z;
      }
      elsif (/^31/)
      {
        my $num;
        ($num, $z)=split;
        $z =~ s/\\x22/\x22/g;$z =~ s/\\x25/\x25/g;$z =~ s/\\x27/\x27/g;$z =~ s/\\\\/\\/g;$z =~ s/\\\$/@%@%@/g;$z =~ s/(\$[\w_!?]+[\[\{][\w_!?\$]+[\]\}])/$1/eeg;$z =~ s/(\$[\w_!?^]+)/$1/eeg;$z =~ s/@%@%@/\$/g;$z =~ s/\\x24/\x24/g;
        chomp $z;
        $MLTN=$z;
      }
      elsif (/^32/)
      {
        my $num;
        ($num, $z)=split;
        $z =~ s/\\x22/\x22/g;$z =~ s/\\x25/\x25/g;$z =~ s/\\x27/\x27/g;$z =~ s/\\\\/\\/g;$z =~ s/\\\$/@%@%@/g;$z =~ s/(\$[\w_!?]+[\[\{][\w_!?\$]+[\]\}])/$1/eeg;$z =~ s/(\$[\w_!?^]+)/$1/eeg;$z =~ s/@%@%@/\$/g;$z =~ s/\\x24/\x24/g;
        chomp $z;
        $LTN=$z;
      }
      else
      {
         next;
      }
    }
    close FP;
   }
   my %cond_hash = (
           'much higher than normal' => "$MHTN",
           'higher than normal' => "$HTN",
           'much lower than normal' => "$MLTN",
           'lower than normal' => "$LTN",
           );
		   
   my %CMA_hash = (
           'much higher than normal' => "MuchHigherThanNormal",
           'higher than normal' => "HigherThanNormal",
           'much lower than normal' => "MuchLowerThanNormal",
           'lower than normal' => "LowerThanNormal",
           );

   my $strConditionText;
   my $strConditionWoS;
   $strConditionText = $cond_hash{$strCondition};
   $strConditionWoS = $CMA_hash{$strCondition};
   #$strConditionWoS =~ s/\s+//g; # removes all spaces
 
   my $tempStr;
	
  #convert to lower case
  my $tempStr = lc($strSev);
  # check to see if user specified NONE for this severity.
    if ($tempStr eq 'none') 
    {	
        # when none is specified, that means suppress this alert.
        $self->{OVORULE}->Status(0);
    }

    else {
        $self->{OVOPOLICY}->MsgSeverity($strSev);
        $self->{OVOSESSION}->Value('MessageApp', $strApp);
        $self->{OVOSESSION}->Value('MessageCondition',$strConditionText);
        $self->{OVOSESSION}->Value('MessageConditionWoS',$strConditionWoS);
        $self->{OVORULE}->Status(1);
    }
}

#Validates CutOff margin
# CutOff has value x ==>  Continue only if current data sample avg is greater than x
# CutOff has value >x ==>  Continue only if current data sample avg is less than x
sub EvalCutOff {

	my ($cutoff, $avg) = @_;
	my ( $cutoffval, $res );

	if ( $cutoff =~ /^>/ )
	{
		$cutoff = $';
		if($cutoff =~ /[^0-9]/)
		{
			$res = 2;
		}
		else
		{
			if ( $avg < $cutoff) {
				$res = 0;	
			}
			else {
				$res = 1;
			}
		}
	}
	else
	{
		if($cutoff =~ /[^0-9]/)
		{
			$res = 2;
		}
		else
		{
			if ( $avg > $cutoff) {
				$res = 0;	
			}
			else {
				$res = 1;
			}
		}
	}
	#`opcmsg a=a o=o msg_t="cutoffval is $cutoffval"`;
	return $res;
}

sub GetTodaysDataSample() {

	#my $self = shift;
	my ($self, $DataObject, $CodaPath, $BaselinePeriod, $instanceName) = @_;
	my $objToday ;
	# Get Today's data for the current baseline period
	$objToday = $self->{OVOPOLICY}->SourceCollection($CodaPath, $BaselinePeriod);
	
	if ( lc($DataObject) ne "global") {
		# Add for multi-instance the Include call to FILTER data.
		$objToday = $objToday->Include("^$instanceName", "");
	}
	
	return $objToday ;
}	

sub BuildBaseline() {

	#my $self = shift;
	my ($self, $DataObject, $CodaPath, $BaselinePeriod, $instanceName, $DebugLevel) = @_;
	my ($dCurrent, $dWeek);
	my ($strWeek, $bWeek);
	my $objWeek;
	my $traceObj = $self->{TRACEOBJ};
	my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst);
	$dCurrent = time();

	my $objBaselineStore;
	for( my $week=1; $week < 5; $week++) {	
		$dWeek = $dCurrent - 604800 * $week;
		($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($dWeek);
		$strWeek = sprintf("%02d/%02d/%d %02d:%02d:%02d", $mday, $mon+=1,$year+=1900,$hour,$min,$sec);
	
		# Get the data for the week ago periods.. (same time last week, week before, etc)
		$objWeek = $self->{OVOPOLICY}->SourceCollection($CodaPath, $BaselinePeriod, $strWeek);
	
		if ( lc($DataObject) ne "global") {
			# Add for multi-instance the Include call to FILTER data.
			$objWeek = $objWeek->Include("^$instanceName","" );	
		}
		
		my $nCurrent;
		my $objValue;
		if (defined($objWeek) == 1) {
		
			$bWeek = $objWeek->DataAvailable;
			##if ($DebugLevel == 1) 
		    	##{
			##$self->WriteTraceLog(  "Processing week $week samples " . $objWeek->Count() );
		    	##}
		    			
			if ( ($bWeek) && ($week == 1) )
			{
				$objBaselineStore = $objWeek;
			}   			
			else {
				if (defined($objBaselineStore) && ($bWeek == 1) )
				{
				        $nCurrent = 0;
				        while ($nCurrent < $objWeek->Count()) 
				        {
					       	$objValue = $objWeek->Item($nCurrent);
					        $objBaselineStore->Add($objValue->Time, $objValue->Value);
					        $nCurrent = $nCurrent + 1;
					}
				}
				else {
				    	if ($bWeek == 1)  #So $baselineStore isn't valid, so initialize it.
				    	{
				    		$objBaselineStore = $objWeek;
				    	}
				}
			}  	   						
		}
		else 
		{
		    $bWeek = 0;
    		if ($DebugLevel ) 
		    {
			$traceObj->WriteTraceLog( $DebugLevel, "Week $week Data NOT Available " );   
		    }
		}
	}

$objWeek = undef;
return $objBaselineStore;
}

sub GenerateBaselineAlert {

	my $self = shift;
    my $arghashref = shift;
    my %arghash = %$arghashref;
    my $traceObj = $self->{TRACEOBJ};
		
	my ($InstanceSource, $DataObject, $CodaPath, $BaselinePeriod, $DebugLevel, $MessageApplication, $CutOff);
	my ($MajorHighSeverity, $MinorHighSeverity, $WarningHighSeverity, $MajorLowSeverity, $MinorLowSeverity);
	my ($WarningLowSeverity, $WarningDeviations, $MinorDeviations, $MajorDeviations, $MinimumValue, $MaximumValue);
	#`opcmsg a=a o=o msg_t="CodaPath is $CodaPath and BaselinePeriod is $BaselinePeriod"`;

	$InstanceSource = $arghash{"InstanceSource"};
	$DataObject = $arghash{"DataObject"};
	$CodaPath = $arghash{"CodaPath"};
	$BaselinePeriod = $arghash{"BaselinePeriod"};
	$DebugLevel = $arghash{"DebugLevel"};
	$MessageApplication = $arghash{"MessageApplication"};
	$MajorHighSeverity = $arghash{"MajorHighSeverity"};
	$MinorHighSeverity = $arghash{"MinorHighSeverity"};
	$WarningHighSeverity = $arghash{"WarningHighSeverity"};
	$MajorLowSeverity = $arghash{"MajorLowSeverity"};
	$MinorLowSeverity = $arghash{"MinorLowSeverity"};
	$WarningLowSeverity = $arghash{"WarningLowSeverity"};
	$WarningDeviations = $arghash{"WarningDeviations"};
	$MinorDeviations = $arghash{"MinorDeviations"};
	$MajorDeviations = $arghash{"MajorDeviations"};
	$MinimumValue = $arghash{"MinimumValue"};
	$MaximumValue = $arghash{"MaximumValue"};
	$CutOff = $arghash{"CutOff"};

	my $instanceName;

	if ( lc($DataObject) ne "global") {

		# for multi-instance data, this is where we get the instance we're working on right now.
		my $policySource;
		$policySource = $self->{OVOPOLICY}->Source($InstanceSource);
	
		if (defined $policySource)
		{
			$instanceName = $policySource->Name();
			$self->{OVOSESSION}->Value('instanceName', $instanceName);
			if ($DebugLevel ) 
			{
			      $traceObj->WriteTraceLog( $DebugLevel, 'Instance ' . $policySource->Name);
			}
			
		}
	}

	#Get current sample and validate against CutOff
	my $objToday;
	$objToday = $self->GetTodaysDataSample($DataObject, $CodaPath, $BaselinePeriod, $instanceName);
	
	my ($bToday, $objTodayStats);
	if ($objToday->DataAvailable == 1) {
	    	    
		$bToday = 1;
                $objTodayStats = $self->DoStats($objToday);

	        if ($DebugLevel ) {
  			$traceObj->WriteTraceLog($DebugLevel, "Today's Data Available. Number of samples is " . $objToday->Count() . "\nCODA DataPath is " . $CodaPath . "\nToday Data Average is " . $objTodayStats->{nAvg} . "\n StdDev is" . $objTodayStats->{nStdDev} );
    		   }

   	        if ( $CutOff ) {
			my $StopAT;
			$StopAT = EvalCutOff( $CutOff, $objTodayStats->{nAvg} );
			if ( $StopAT == 1 ) { 
				return;
			}
			if ( $StopAT == 2 ) { 
				if ($DebugLevel ) {
					$traceObj->WriteTraceLog($DebugLevel, 'Invalid Cutoff parameter' );
				}
				return;
			}
		}
	}
	else {
	       $bToday = 0;
		if ($DebugLevel ) {
			$traceObj->WriteTraceLog( $DebugLevel, 'Today Data NOT Available ' );
		}
	}

my $objBaselineStore = $self->BuildBaseline($DataObject, $CodaPath, $BaselinePeriod, $instanceName, $DebugLevel);

# alrighty, we've gotten the data and are proceeding to calculate the baseline
# first, calculate the "quality" of the baseline

if ($bToday == 1) {
    # we have data for today, that's a good start
    my $objBaselineStats;
    
    # bugfix.   Its possible that $objBaselineStore is undefined because of no history.  This will catch that case
    if (defined($objBaselineStore) == 1)
    {
	    $objBaselineStats = $self->DoStats($objBaselineStore);
	
	    if ($DebugLevel ) {
		$traceObj->WriteTraceLog($DebugLevel, "Baseline stats - \nnumber of samples " . $objBaselineStore->Count() . "\nBaselineStore Data Average " . $objBaselineStats->{nAvg} . "\nBaselineStore StdDev " . $objBaselineStats->{nStdDev} );
	    }

	    $self->DoThresholds($objTodayStats, $objBaselineStats, $MessageApplication, $MajorHighSeverity, $MinorHighSeverity, $WarningHighSeverity, $MajorLowSeverity, $MinorLowSeverity, $WarningLowSeverity, $WarningDeviations, $MinorDeviations, $MajorDeviations, $MinimumValue, $MaximumValue, $DebugLevel);
    }
    else
    {
    	if ($DebugLevel )
    	{
	 	$traceObj->WriteTraceLog($DebugLevel,  'Baseline Store is empty (as no history) not processing thresholds' );
    	}
    }
}
else {

    # no data for today, cannot compare baseline data as there's nothing to compare
}

# clean up objects
$objToday = undef;

}
	  
sub _isNumeric {
    no warnings qw(numeric);
    return ($_[0] + 0) eq $_[0];
}

sub _compareValues {
    my($lhs, $rhs, $cval) = @_;
    my $cmpVal= (_isNumeric($lhs) || _isNumeric($rhs)) ? ($lhs <=> $rhs) : ($lhs cmp $rhs);
    # Map (-1, 0, 1) => (1, 2, 4) and do a bit-and
    return $cval & (1, 2, 4)[$cmpVal + 1];
}

package PerfStat;

sub new {
    my $invocant = shift;
    my $class = ref $invocant || $invocant;
    return bless {}, $class;
}

1;