Edit D:\app\Administrator\product\11.2.0\dbhome_1\sysman\admin\scripts\progResUtil.pl
# # Copyright (c) 2004, 2007, Oracle. All rights reserved. # # NAME # procResUtil.pl # # DESCRIPTION # Metric script that monitors CPU and resident memory utilization of processes # # # OUTPUT: # # Zero or more lines of: # em_result=prog_name|owner|prog_max_cpu_util|prog_max_cpu_util_pid|prog_total_cpu_util|prog_max_cpu_time|prog_max_cpu_time_pid|prog_total_cpu_time|prog_max_rss|prog_max_rss_pid|prog_process_count # # NOTES # Supported platforms: Solaris, HP-UX, AIX and Linux. # # Usage: progResUtil.pl # # Input: inputs are agentConditionContext environment variables, which specify program criteria # in terms of program name and owner name # # # MODIFIED (MM/DD/YY) # ajayshar 09/29/06 - Backport ajayshar_bug-5451828 from main # snandarg 01/22/07 - Bug 5837452 # ajayshar 09/28/06 - Bug#5451828 - making the script portable This includes: # bug#5053887 , # cpu Time format changes for SOL and HP-UX , # AIX support for the metrics and cpucount support for HP-UX,AIX and SOL # removed reference to hostGenFunctins.pl # # sreddy 06/21/05 - fix bug#4442004 # sacgoyal 01/25/05 - moved getCpuCount() method to hostGenFunctins.pl # sacgoyal 01/25/05 - update computation of %cpu utilization # sacgoyal 11/23/04 - remove warning # sacgoal 10/03/04 - correction in getCpuCount(), remove pid-list from # em_result, fix of "duplicate key-value set bug". # sacgoyal 07/22/04 - Creation for Agent Condition Context, # Enterprise Manager, 10.2 # # use strict; use File::Basename; require "conditionContext.pl"; require "emd_common.pl"; require "semd_common.pl"; my $conditionContextAref = &getConditionContext; my %key_value_set = (); my %previous_cputime = (); my %current_cputime = (); my $previous_timestamp = ""; my $current_timestamp = ""; $conditionContextAref = &addDefaultConditionContext( $conditionContextAref ); if ($#$conditionContextAref < 0) { raise_error_and_exit("No condition context passed.", 1); } # ------------------------------------------------------------------------ # determine OS type and run ps get the list of processes and their # characteristics. # ------------------------------------------------------------------------ my $pgSize; # page size in bytes on HP-UX my $os; if (($os = get_osType())==-1) { raise_error_and_exit("Unsupported OS", 2); } my $isTestMode=0; my @psList = (); # list of processes my %ps_command = ( "SOL" => '/usr/bin/ps -eo "pid user pcpu rss time args"', "LNX" => '/bin/ps -eo "pid user pcpu rss time args"', "HP" => '/usr/bin/ps -eo "pid user pcpu sz time args"', "AIX" => '/usr/sysv/bin/ps -eo "pid user pcpu rss time args"', "OSF1" => '/bin/ps -eo "pid user pcpu rss time args"' ); $isTestMode=1 if ($ENV{EM_TEST_MODE}); if ($ARGV[0]) { unless (open(INPUT, $ARGV[0])) { raise_error_and_exit("$ARGV[0] file couldn't be opened",3); } @psList = <INPUT>; close(INPUT); $isTestMode=1; } else { if ($os eq "HP") { $ENV{UNIX95} = "XPG4"; $pgSize=`getconf SC_PAGE_SIZE`; if ($? != 0) { raise_error_and_exit("Failed to run getconf command", 4); } } if (!defined($ps_command{$os})) { raise_error_and_exit("Unsupported OS", 5); } @psList = `$ps_command{$os}`; if ($? != 0) { raise_error_and_exit("Failed to run ps command", 6); } $current_timestamp = time; } shift @psList; # remove ps header line getPreviousState(); # get the previous state for %cpu utilization computation # ------------------------------------------------------------------------ # screen the processes in the process list based on monitoring criteria. # compute and keep track of total CPU percentage and max resident memory # used by each user-specified process. also keep track of the PIDs. # ------------------------------------------------------------------------ foreach my $conditionHref (@$conditionContextAref) { my $keysAref = ${$conditionHref}{"keyColumnAref"}; if ($#{$keysAref} < 0 ) { next; } my ($progKeyToMatch,$progKeyToReturn,$progKeyOperator)=("","",""); my ($userKeyToMatch,$userKeyToReturn,$userKeyOperator)=("","",""); foreach my $keyHref (@$keysAref) { if (${$keyHref}{"keyName"} eq "prog_name") { $progKeyToMatch = ${$keyHref}{"keyValueToMatch"}; $progKeyToReturn = ${$keyHref}{"keyValueToReturn"}; $progKeyOperator = ${$keyHref}{"keyOperator"}; } elsif (${$keyHref}{"keyName"} eq "owner") { $userKeyToMatch = ${$keyHref}{"keyValueToMatch"}; $userKeyToReturn = ${$keyHref}{"keyValueToReturn"}; $userKeyOperator = ${$keyHref}{"keyOperator"}; } else { EMD_PERL_ERROR("Unknown Key Column: ${$keyHref}{'keyName'}"); } } if ($progKeyToReturn eq "" && $userKeyToReturn eq "") { EMD_PERL_ERROR("Skipping, Required Key Columns are null"); next; } # When User hasn't entered one of two keys, then manually assigning them to "%". # so that in performance-UI page, "ALL" can be put wherever "%" is found in the column value. # These lines might required to be deleted. if($progKeyToReturn eq "") { $progKeyToReturn = "%"; } if($userKeyToReturn eq "") { $userKeyToReturn = "%"; } # Checking whether this key-value set is already included if ( $key_value_set{$progKeyToReturn}{$userKeyToReturn} == 1 ) { next; } # Creating record that current key-value set is included $key_value_set{$progKeyToReturn}{$userKeyToReturn} =1; if ($isTestMode) { print("progKeyToMatch=[$progKeyToMatch], progKeyOperator=$progKeyOperator, progKeyToReturn=[$progKeyToReturn], userKeyToMatch=[$userKeyToMatch], userKeyOperator=$userKeyOperator, userKeyToReturn=[$userKeyToReturn]\n"); } EMD_PERL_DEBUG("progKeyToMatch=[$progKeyToMatch], progKeyOperator=$progKeyOperator, progKeyToReturn=[$progKeyToReturn], userKeyToMatch=[$userKeyToMatch], userKeyOperator=$userKeyOperator, userKeyToReturn=[$userKeyToReturn]"); my $maxPcntCpu = 0; # running max CPU percentage my $maxPcntCpuPid = ""; # PID of the process instance with max Cpu Utilization my $totPcntCpu = 0; # running total CPU percentage my $maxCpuTime = 0; # running max CPU time my $maxCpuTimePid = ""; # PID of the process instance with max Cpu time my $totCpuTime = 0; # running total CPU time my $maxMem = 0; # max resident memory by a process instance my $maxMemPid = ""; # PID of the process instance with max resident memory usage my $maxMemMB = 0; my $instanceCount = 0; # instance counter my $pidStr = ""; # string that holds PIDs my $command = ""; # Command which appear for the program in ps command output my $flagCputime = 0; # Flag, so that "storing of Cpu Times of all processes" is done only once. foreach my $psLine( @psList ) { $psLine =~ s/^\s+//; # remove any leading space chomp($psLine); my ($pid, $user, $pcntCpu, $resMem, $cpuTime, @cmdArgs); my $resMemPg; # resident memory in pages (HP-UX) my $computeFlag = 0; if ( $os eq "HP") { ($pid, $user, $pcntCpu, $resMemPg, $cpuTime, @cmdArgs) = split(/\s+/,$psLine); $resMem = ($resMemPg * ($pgSize/1024)); } else { ($pid, $user, $pcntCpu, $resMem, $cpuTime, @cmdArgs) = split(/\s+/,$psLine); } if( substr( $progKeyToReturn,0,1) ne '[' and substr($progKeyToReturn,-1,1) ne ']' and substr( $cmdArgs[0],0,1) eq '[' and substr($cmdArgs[0],-1,1) eq ']' ) { #For defunct, zombie processes who appear in [ProcessName -argument] format; and user-specified progName doesn't contain [] $command = substr($cmdArgs[0],1) ; chop ($command); } else { #$command = basename($cmdArgs[0], ""); $command = $cmdArgs[0]; } #------------------------------------------------------------------------------ # compute the running max and total of cpu TIME & max cpu-TIME- PID #bug 5053887 - getting a blank line next if ($cpuTime =~ /^$/); my @cpuTimeArray = split(":",$cpuTime); my $days = 0; my $hours = 0; my $minutes = 0; my $seconds = 0; # For solaris and HP-UX cases, the format may be MM:SS or M:SS in some cases # Handle those cases my $timeNo=@cpuTimeArray; if ($timeNo eq 2) { $minutes = $cpuTimeArray[0]; $seconds = $cpuTimeArray[1]; } elsif ( !( ($cpuTimeArray[0] =~ /^[\d]{2}$/) and ($cpuTimeArray[1] =~ /^[\d]{2}$/) and ($cpuTimeArray[2] =~ /^[\d]{2}$/) ) and !( $cpuTimeArray[0] =~ /^[\d]+-[\d]{2}$/) ) { raise_error_and_exit("Unexpected format for cpuTime = $cpuTime", 7); } else { $minutes = $cpuTimeArray[1]; $seconds = $cpuTimeArray[2]; } # Handle the case ddd-hhh when the accumulated time is > 24 hours if ($cpuTimeArray[0] =~ /^[\d]+-[\d]{2}$/) { @cpuTimeArray = split("-",$cpuTimeArray[0]); $days = $cpuTimeArray[0]; $hours = $cpuTimeArray[1]; } else { if ($timeNo eq 2) { $hours =0; } else { $hours = $cpuTimeArray[0]; } } my $cpuTimeInSeconds = $days*24*3600 + $hours*3600 + $minutes*60 +$seconds; if ($flagCputime == 0) { my $key = $command . "," . $user . "," . $pid; $current_cputime{$key} = $cpuTimeInSeconds; } if( ($command =~ /^$progKeyToMatch$/) and ($user =~ /^$userKeyToMatch$/) ) { #-------------------------------------------------------------------------- #Computation of Cpu Utilisation my $key = $command . "," . $user . "," . $pid; if ( $previous_cputime{$key} && $previous_timestamp && ($current_timestamp - $previous_timestamp)>0 && ($cpuTimeInSeconds - $previous_cputime{$key} ) >= 0) { $pcntCpu = sprintf("%.2f", (($cpuTimeInSeconds - $previous_cputime{$key} ) *100) / ($current_timestamp - $previous_timestamp)); } #------------------------------------------------------------------------------- # compute the running max and total of cpu utilization & max cpu-utilization-PID if ($pcntCpu >= $maxPcntCpu ) { $maxPcntCpu = $pcntCpu; $maxPcntCpuPid = $pid; } $totPcntCpu += $pcntCpu; #------------------------------------------------------------------------------ # compute the running max and total of cpu TIME & max cpu-TIME- PID if ($cpuTimeInSeconds >= $maxCpuTime) { $maxCpuTime = $cpuTimeInSeconds; $maxCpuTimePid = $pid; } $totCpuTime += $cpuTimeInSeconds; #------------------------------------------------------------------------------- # keep track of max resident memory and the PID of this process if ( $resMem >= $maxMem ) { $maxMem = $resMem; $maxMemPid = $pid; } #-------------------------------------------------------------------------------- # append the PID of this process instance to PID list, & increment instance-count $pidStr .= "$pid\,"; $instanceCount++; next; } }# end: inner foreach $flagCputime = 1; # so that "storing of Cpu Times of all processes" is done only once. # --------------------------------------------------------------------- # all processes have been screened based on this rule. # output results # --------------------------------------------------------------------- if ( $pidStr ne "" ) { $pidStr =~ s/,$//; # remove trailing comma (,) } if ($maxMem >= 0) { # convert size in KB to size in MB and round up to 2 decimals $maxMemMB = sprintf("%.2f",$maxMem / 1024); } my $cpuCount = getCpuCount(); $totPcntCpu = $totPcntCpu /$cpuCount; $maxPcntCpu = $maxPcntCpu/$cpuCount; $maxCpuTime = sprintf("%.2f",$maxCpuTime/60); $totCpuTime = sprintf("%.2f",$totCpuTime/60); $maxPcntCpu = sprintf("%.2f",$maxPcntCpu); $totPcntCpu = sprintf("%.2f",$totPcntCpu); if (!$isTestMode) { print "em_result=$progKeyToReturn|$userKeyToReturn|$maxPcntCpu|$maxPcntCpuPid|$totPcntCpu|$maxCpuTime|$maxCpuTimePid|$totCpuTime|$maxMemMB|$maxMemPid|$instanceCount\n"; } else { print("em_result=prog_name=$progKeyToReturn|owner=$userKeyToReturn|maxPcntCpu=$maxPcntCpu|maxPcntCpuPid=$maxPcntCpuPid|totPcntCpu=$totPcntCpu|maxCpuTime=$maxCpuTime|maxCpuTimePid=$maxCpuTimePid|totCpuTime=$totCpuTime|maxMemMB=$maxMemMB|maxMemPid=$maxMemPid|instanceCount=$instanceCount\n"); } # EMD_PERL_DEBUG("em_result=prog_name=$progKeyToReturn|owner=$userKeyToReturn|maxPcntCpu=$maxPcntCpu|maxPcntCpuPid=$maxPcntCpuPid|totPcntCpu=$totPcntCpu|maxCpuTime=$maxCpuTime|maxCpuTimePid=$maxCpuTimePid|totCpuTime=$totCpuTime|maxMemMB=$maxMemMB|maxMemPid=$maxMemPid|instanceCount=$instanceCount|pidStr=$pidStr"); } # end of outer foreach saveStateFile(); # save the state for %cpu utilization computation ############################################################################# #-----------------------getCpuCount-------------------- ############################################################################# sub getCpuCount() { # Support Multiple platforms for getCpuCount method if ($os eq "LNX") { my @processorLines = `grep '^processor[[:space:]]*:' /proc/cpuinfo`; if ($? != 0) { EMD_PERL_ERROR("error in grep from /proc/cpuinfo file"); } elsif ( @processorLines > 1 ) { return @processorLines; } return 1; } elsif ($os eq "SOL") { my @processorLines = `/usr/sbin/psrinfo`; if ($? != 0) { EMD_PERL_ERROR(" error during psrinfo"); } elsif ( @processorLines > 1 ) { my $cpuCount = @processorLines; return $cpuCount; } return 1; } elsif ($os eq "HP") { my $cpuCount= ` /sbin/ioscan/ -kC processor | grep processor | wc -l`; if ($? != 0) { EMD_PERL_ERROR(" error during /sbin/ioscan/"); } elsif ($cpuCount > 1) { return $cpuCount; } return 1; } elsif ($os eq "AIX") { my $cpuCount = `lsdev -C|grep Process|wc -l`; if ($? != 0) { EMD_PERL_ERROR(" error during lsdev"); } elsif ($cpuCount > 1) { return $cpuCount; } return 1; } return 1; } ############################################################################# #-----------------------addDefaultConditionContext-------------------- ############################################################################# sub addDefaultConditionContext () { my ($conditionContextAref )= @_; my @currentKeys = (); my %currentKey1 = ("keyName" => "prog_name", "keyOperator" => "1", # LIKE is defined as 1 "keyValueToReturn" => "%", "keyValueToMatch" => ".*"); push(@currentKeys, \%currentKey1); my %currentKey2 = ("keyName" => "owner", "keyOperator" => "1", # LIKE is defined as 1 "keyValueToReturn" => "%", "keyValueToMatch" => ".*"); push(@currentKeys, \%currentKey2); my %currentCondition = ("conditionColumnName" => "", "conditionOperator" => "", "criticalThreshold" => "", "warningThreshold" => "", "keyColumnAref" => \@currentKeys); push @{$conditionContextAref}, \%currentCondition; return $conditionContextAref; } sub raise_error_and_exit() { my ($message, $exit_status) = @_; EMD_PERL_ERROR($message); print STDERR "$message \n"; exit $exit_status; } ############################################################################# #-----------------------getStateFileName-------------------- ############################################################################# sub getStateFileName { unless( exists $ENV{EMSTATE} or defined $ENV{EMSTATE} ) { &raise_error_and_exit("The environment variable EMSTATE needs to be set in order to run progResUtil.pl",2); } my $os; if (($os = get_osType()) eq "-1") { &raise_error_and_exit("Unsupported OS", 20); } my $separator = '/'; #default to UNIX path seperator $separator = '\\' if($os eq "WIN"); my $agentStateDir = $ENV{EMSTATE}; EMD_PERL_DEBUG("progResUtil.pl EMSTATE directory is $agentStateDir\n"); my $separator = $^O =~ m/MSWin32/ ? "\\" : "\/"; my $stateFile = $agentStateDir.$separator."sysman"."$separator"."emd"."$separator"."state"."$separator"."progResUtil.log"; return $stateFile; } ############################################################################# #-----------------------getPreviousState-------------------- ############################################################################# sub getPreviousState { my $stateFileName = getStateFileName(); open(STATE, "< $stateFileName"); my @stateLines = <STATE>; close STATE; # This state file is maintained for %cpu-utilization calculation. Its format is - # first line contains the "previous time_stamp" # remaining lines contains following entries-> "command,user,pid|||totCpuTimeInSeconds" $previous_timestamp = shift @stateLines; chomp $previous_timestamp; foreach my $process_state (@stateLines) { chomp($process_state); if ($process_state) { my @tokens = split ('\|\|\|', $process_state); $previous_cputime{$tokens[0]} = $tokens[1]; } } } ############################################################################# #-----------------------saveStateFile-------------------- ############################################################################# sub saveStateFile { my $stateFileName = getStateFileName(); open(STATE, "> $stateFileName"); my $prog_owner_pid; print STATE "$current_timestamp\n"; foreach $prog_owner_pid (keys %current_cputime) { print STATE "$prog_owner_pid|||$current_cputime{$prog_owner_pid}\n"; } close(STATE); }
Ms-Dos/Windows
Unix
Write backup
jsp File Browser version 1.2 by
www.vonloesch.de