shroh has asked for the wisdom of the Perl Monks concerning the following question:

Hi Experts, I am trying to process time to execute commands on each element on of an array and print that in the log file, I included the code in the enable_unplanned_outage subroutine to do that, just figuring out if it can be included in the main subroutine or can be called as a separate subroutine so that i dont have to write the same code in Disable_Unplanned_Outage subroutine as both the above subroutines are executing commands on each element of an array. Below is the complete code
#!C:\Perl\bin\perl.exe use strict; use warnings; #use diagnostics; #===================================================================== +========================== # # This script is leveraged by an OMW tool and is used to [enable | d +isable] unplanned outage # mode on a list of servers. It requires two arguments [action] and + [filename]. #===================================================================== +========================== &main(); sub main { my $path = 'E:/scripts/MaintenanceMode/'; require $path.'omwNodeDetails.pm'; open_log($path.'maintenanceMode'); my $mode=get_mode(); my ($node_ref,$error_ref)=get_node(); my @nodes=@$node_ref; my @errorlist=@$error_ref; if( $mode eq 'enable'){ enable_unplanned_outage(@nodes); } elsif($mode eq 'disable'){ disable_unplanned_outage(@nodes); } else { printLog("Error invalid Mode $mode"); } printLog("There were ".scalar @errorlist." failed servers in serverlis +t"); # clear serverlist printLog ("Truncating serverlist"); open( SRV,'>',$path.'serverlist.txt') or die "Can't open SRV '$path.serverlist': $!"; close SRV; close_log(); } sub get_mode { # expect values 'enable|disable' my $maintMode = lc $ARGV[0]; chomp($maintMode); if ($maintMode ne 'enable' && $maintMode ne 'disable'){ $maintMode="error"; } return $maintMode; } sub get_node { my @errorlist=(); my $sPath='e:/scripts/MaintenanceMode/'; my $sInFile=$sPath.'serverlist.txt'; my @sContent=(); my $sText; ##checks if the file exists and pulls the info out if (-e $sInFile){ open INFILE, '<', $sInFile or die "Could not open $sInFile : $!"; while (<INFILE>){ chomp; $sText="$_"; push @sContent,$sText; } close INFILE; } else { printLog("ERROR Cannot open $sInFile"); } # check serverlist had entries if (@sContent == 0){ printLog("ERROR No nodes found in serverlist.txt"); close_log(); exit; } #get FQDN************ my $hostname; my $fqdn; my @serverlist; for my $NODE (@sContent){ ($hostname) = split /\./, $NODE; $fqdn = getNodeAttributes($hostname,'PrimaryNodeName'); if(length($fqdn) < 1) { printLog("No value returned from WMI, node ($NODE) doesn't ex +ists in OMW."); push @errorlist,$fqdn; next; } else { push(@serverlist,$fqdn); } } return(\@serverlist, \@errorlist); } sub enable_unplanned_outage { my($i,$avgTime,$cumulativeTime)=0; my @nodelist=@_[0..$#_]; foreach my $FQDN (@nodelist) { my $timeStart=time(); $i++; printLog ("===================\n Putting the server $FQDN into outage."); my $cmd = "ovownodeutil.cmd -outage_node -unplanned -disable_he +artbeat -delete_msgs -node_name $FQDN -on "; my $output =`$cmd`; `$cmd`; printLog($output); #This code is to calculate the time to process my $timeTook= time() - $timeStart; $cumulativeTime=$cumulativeTime + $timeTook; $avgTime=$cumulativeTime/$i; print("Took this long, " . $timeTook . "(s), for node: " . $FQDN . + ".\nNow averaging $avgTime seconds per node.\n"); } printLog("\nTook this long, " . $cumulativeTime . "(sec) total for $i +nodes, an average of $avgTime (sec) per node....\n\n"); } sub disable_unplanned_outage { my @sContent = @_[0..$#_]; ####When the servers is brought out of maintenance the agent has to be + recycled to reset all the monitors. foreach my $FQDN (@sContent) { printLog ("===================\n Bringing the server $FQDN out of outage."); my $cmd = "ovownodeutil.cmd -outage_node -unplanned -disable_ +heartbeat -delete_msgs -node_name $FQDN -off "; `$cmd`; my $output=`$cmd`; printLog($output); printLog("Restarting the opcmona to reset the monitors"); my $cmdresopcmona = "ovdeploy -cmd \"ovc -restart opcmona\" - +host $FQDN"; `$cmdresopcmona`; } } sub printLog { my ($logLine) = @_; my ($day,$month,$year) = (localtime) [3..5]; my $time = sprintf "%02d:%02d:%02d",(localtime)[2,1,0]; my $date = sprintf "%04d/%02d/%02d",$year + 1900 , $month + 1 , $day + ; print LOG "$date $time $logLine\n"; } sub open_log { my ($filename) = @_; my $logfile = $filename.'.log'; open LOG,'>>',$logfile or die "Can't open LOG '$logfile': $!\n"; print LOG "\n====SCRIPT START====\n"; } sub close_log { print LOG "====SCRIPT END====\n"; close LOG; }
  • Comment on Calculating the time to execute commands on each element of an array
  • Download Code

Replies are listed 'Best First'.
Re: Calculating the time to execute commands on each element of an array
by ww (Archbishop) on Sep 28, 2015 at 19:04 UTC

    Do you have a question or is this a request for comments/critiques?

    If the latter, are you satisfied with your results? If the former, where is the result less than satisfactory? Please include narrative description of your problem with this (large) snippet and error messages/warnings/inaccurate output.


    ++$anecdote ne $data

    check Ln42!

      Hi, This is a question, as you can see in the subroutine enable_unplanned_outage i have a code to calculate the total time taken by all the nodes/servers , same code i have to use in the subroutine disable_unplanned_outage. Since it is exactly same code, i was thinking of creating another subroutine which will do that for me.

        I don't have the time at the moment to go through it all line-by-line, but after a quick glance, it appears that you can move most of that code as-is to a new sub, then call it like this:

        for my $FQDN (@things){ my $start_time = time_and_log($FQDN); # do stuff with $FQDN time_and_log($FQDN, $start_time); }

        ...and in the sub...

        sub time_and_log { my $FQDN = shift; my $start = shift; if (! $start){ # do start stuff $start = time; return $start; } else { # use $start for calculations, # then log } }