in reply to Error Handling the Perl script

Use a hash to store the output from the commands. Then process them all in a loop. I'm assuming the word 'error' or similar appear somewhere in the output for those commands that failed. Alternative use a word that means OK and reverse the logic. Here is your script refactored. Note the log file is only opened once at the start of the script rather than for each entry.

#!C:\Perl\bin\perl.exe use strict; use warnings; use Data::Dump 'pp'; #use diagnostics; # This script is created to put the servers # in unplanned outage as part of the tasks that # are received to stop the monitoring on the servers # due to some maintenance activity on the servers. # Author : ROHIT SHARMA (INYROHS) main(); sub main { my $result = {}; # holds result of commands my %count=( 'error' => 0, 'OK' => 0, ); my $path = 'E:/scripts/OutageNodes/'; require $path.'omwNodeDetails.pm'; open_log($path.'maintenanceMode_'); my $mode = get_mode($ARGV[0]); if ($mode eq 'error'){ print_log("ERROR Invalid Mode '$ARGV[0]'"); ++$count{'error'}; } else { my $nodelist = get_node($path.'serverlist.txt'); if (@$nodelist == 0){ print_log("ERROR No nodes found in serverlist.txt"); ++$count{'error'}; } else { if ( $mode eq 'enable'){ $result = enable_unplanned_outage($nodelist); } if ($mode eq 'disable'){ $result = disable_unplanned_outage($nodelist); } # count errors from results process_error(\%count,$result); # clear serverlist if ($count{'error'} == 0){ print_log("Truncating serverlist"); open SRV,'>',$path.'serverlist.txt' or die "Can't open SRV '$path.serverlist': $!"; close SRV; } } } close_log(); print "Completed Errors = $count{'error'} OK = $count{'OK'}\n"; # Data::Dump pretty print pp $result; } # expect values 'enable|disable' sub get_mode { my $maintMode = lc shift; if ($maintMode ne 'enable' && $maintMode ne 'disable'){ $maintMode = "error"; } return $maintMode; } sub get_node { my ($infile) = @_; my @nodelist = (); ##checks if the file exists and pulls the info out if (-e $infile){ open INFILE, '<', $infile or die "Could not open $infile : $!"; print_log("Scanning $infile"); while (my $node = <INFILE>){ chomp($node); my ($hostname) = split /\./, $node; my $fqdn = getNodeAttributes($hostname,'PrimaryNodeName'); if (length($fqdn) < 1) { print_log("No value returned from WMI, node ($node) doesn't ex +ists in OMW."); } else { print_log("$node => $hostname => $fqdn"); push @nodelist,$fqdn; } } close INFILE; } else { print_log("ERROR Cannot open $infile"); } return \@nodelist; } sub enable_unplanned_outage { my ($nodelist) = @_; my %result = (); foreach my $node (@$nodelist) { print_log ("===================\n Putting the server $node into outage."); my $cmd = "ovownodeutil.cmd -outage_node -unplanned -disable_heart +beat -delete_msgs -node_name $node -on "; print_log($cmd); my $output = `$cmd`; print_log($output); $result{$node}{'ovownodeutil'} = $output; } return \%result; } # When the servers is brought out of maintenance # the agent has to be recycled to reset all the monitors. sub disable_unplanned_outage { my ($nodelist) = @_; my %result=(); foreach my $node (@$nodelist) { print_log("Node $node >>> off"); my $cmd = "ovownodeutil.cmd -outage_node -unplanned -disable_heart +beat -delete_msgs -node_name $node -off "; print_log($cmd); my $output = `$cmd`; print_log($output); $result{$node}{'ovownodeutil'} = $output; my $cmdresopcmona = "ovdeploy -cmd \"ovc -restart opcmona\" -host +$node"; print_log($cmdresopcmona); $output = `$cmdresopcmona`; print_log($output); $result{$node}{'ovdeploy'} = $output; } return \%result; } # check results for error sub process_error { my ($count,$result) = @_; for my $node (sort keys %$result){ for my $cmd (sort keys %{$result->{$node}}){ my $text = $result->{$node}{$cmd}; if ( $text =~ /error/i){ ++$count->{'error'}; } else { ++$count->{'OK'}; } } } } sub print_log { my ($logLine) = @_; my $now = sprintf "%02d:%02d:%02d",(localtime)[2,1,0]; print LOG "$now $logLine\n"; } sub open_log { my ($filename) = @_; my ($day,$month,$year) = (localtime) [3..5]; my $date = sprintf "%04d%02d%02d",$year + 1900 , $month + 1 , $day ; my $logfile = $filename.$date.'.log'; open LOG,'>>',$logfile or die "Can't open LOG '$logfile': $!\n"; print LOG "\n--- START ---\n"; } sub close_log { print LOG "=== END ===\n"; close LOG; }
poj

Replies are listed 'Best First'.
Re^2: Error Handling the Perl script
by shroh (Acolyte) on Aug 12, 2015 at 21:46 UTC
    Hi Poj, I am only looking to capture the error where it says that "No Value returned from WMI, node doesnt exists in OMW" in the get_node subroutine. Any how i want to capture the total number of this error an print it finally in the log file.
    #!C:\Perl\bin\perl.exe use strict; use warnings; use Data::Dump 'pp'; #use diagnostics; # This script is created to put the servers # in unplanned outage as part of the tasks that # are received to stop the monitoring on the servers # due to some maintenance activity on the servers. # Author : ROHIT SHARMA (INYROHS) main(); sub main { my $result = {}; # holds result of commands my %count=( 'error' => 0, 'OK' => 0, ); my $path = 'E:/scripts/OutageNodes/'; require $path.'omwNodeDetails.pm'; open_log($path.'maintenanceMode_'); my $mode = get_mode($ARGV[0]); if ($mode eq 'error'){ print_log("ERROR Invalid Mode '$ARGV[0]'"); ++$count{'error'}; ##I dont want to capture this error. } else { my $nodelist = get_node($path.'serverlist.txt'); if (@$nodelist == 0){ print_log("ERROR No nodes found in serverlist.txt"); ++$count{'error'}; ## I dont want to capture this error; } else { if ( $mode eq 'enable'){ $result = enable_unplanned_outage($nodelist); } if ($mode eq 'disable'){ $result = disable_unplanned_outage($nodelist); } # count errors from results process_error(\%count,$result); # clear serverlist if ($count{'error'} == 0){ print_log("Truncating serverlist"); open SRV,'>',$path.'serverlist.txt' or die "Can't open SRV '$path.serverlist': $!"; close SRV; } } } close_log(); print "Completed Errors = $count{'error'} OK = $count{'OK'}\n"; # Data::Dump pretty print pp $result; } # expect values 'enable|disable' sub get_mode { my $maintMode = lc shift; if ($maintMode ne 'enable' && $maintMode ne 'disable'){ $maintMode = "error"; } return $maintMode; } sub get_node { my ($infile) = @_; my @nodelist = (); ##checks if the file exists and pulls the info out if (-e $infile){ open INFILE, '<', $infile or die "Could not open $infile : $!"; print_log("Scanning $infile"); while (my $node = <INFILE>){ chomp($node); my ($hostname) = split /\./, $node; my $fqdn = getNodeAttributes($hostname,'PrimaryNodeName'); if (length($fqdn) < 1) { print_log("No value returned from WMI, node ($node) doesn't ex +ists in OMW."); ++$count{'error'}; ## I want to capture these errors for each +element of the array. Want to see how many servers out of total are g +iving this error. } else { print_log("$node => $hostname => $fqdn"); push @nodelist,$fqdn; } } close INFILE; } else { print_log("ERROR Cannot open $infile"); } return \@nodelist; } sub enable_unplanned_outage { my ($nodelist) = @_; my %result = (); foreach my $node (@$nodelist) { print_log ("===================\n Putting the server $node into outage."); my $cmd = "ovownodeutil.cmd -outage_node -unplanned -disable_heart +beat -delete_msgs -node_name $node -on "; print_log($cmd); my $output = `$cmd`; print_log($output); $result{$node}{'ovownodeutil'} = $output; } return \%result; } # When the servers is brought out of maintenance # the agent has to be recycled to reset all the monitors. sub disable_unplanned_outage { my ($nodelist) = @_; my %result=(); foreach my $node (@$nodelist) { print_log("Node $node >>> off"); my $cmd = "ovownodeutil.cmd -outage_node -unplanned -disable_heart +beat -delete_msgs -node_name $node -off "; print_log($cmd); my $output = `$cmd`; print_log($output); $result{$node}{'ovownodeutil'} = $output; my $cmdresopcmona = "ovdeploy -cmd \"ovc -restart opcmona\" -host +$node"; print_log($cmdresopcmona); $output = `$cmdresopcmona`; print_log($output); $result{$node}{'ovdeploy'} = $output; } return \%result; } # check results for error sub process_error { my ($count,$result) = @_; for my $node (sort keys %$result){ for my $cmd (sort keys %{$result->{$node}}){ my $text = $result->{$node}{$cmd}; if ( $text =~ /error/i){ ++$count->{'error'}; } else { ++$count->{'OK'}; } } } } sub print_log { my ($logLine) = @_; my $now = sprintf "%02d:%02d:%02d",(localtime)[2,1,0]; print LOG "$now $logLine\n"; } sub open_log { my ($filename) = @_; my ($day,$month,$year) = (localtime) [3..5]; my $date = sprintf "%04d%02d%02d",$year + 1900 , $month + 1 , $day ; my $logfile = $filename.$date.'.log'; open LOG,'>>',$logfile or die "Can't open LOG '$logfile': $!\n"; print LOG "\n--- START ---\n"; } sub close_log { print LOG "=== END ===\n"; close LOG; }

      Create an errorlist the same as nodelist

      sub get_node { my ($infile) = @_; my @nodelist = (); my @errorlist = (); ##checks if the file exists and pulls the info out if (-e $infile){ open INFILE, '<', $infile or die "Could not open $infile : $!"; print_log("Scanning $infile"); while (my $node = <INFILE>){ chomp($node); my ($hostname) = split /\./, $node; my $fqdn = getNodeAttributes($hostname,'PrimaryNodeName'); if (length($fqdn) < 1) { print_log("No value returned from WMI, node ($node) doesn't ex +ists in OMW."); push @errorlist,$node; } else { print_log("$node => $hostname => $fqdn"); push @nodelist,$fqdn; } } close INFILE; } else { print_log("ERROR Cannot open $infile"); } return (\@nodelist,\@errorlist); }
      And return the value to main
      my ($nodelist,$errorlist) = get_node($path.'serverlist.txt');
      and add line after clearing server list
      print_log("There were ".scalar @$errorlist." errors in serverlist");

      delete the process_error code.

      poj
        Hi Poj, Thanks for analysing the script. But when i am calling the subroutine i am only calling like this: my @nodes=get_node(); How do i retrun @nodelist,@errorlist to the same subroutine when i am not passsing any argument to the argument while calling it. Also when i return the reference to the array, it gave me some kind of memory error.