#!/usr/bin/perl -w use strict; my $VERSION="1.0.0"; =INFORMATION autosys_job_reporter_1.0.0.pl is a simple and effective Autosys Job report Generator. ############################################# Add a alias in .profile/.bashrc file alias ajr=/path/autosys_job_reporter_1.0.0.pl OR alias b=/path/autosys_job_reporter_1.0.0.pl ############################################# =cut $|=10; my $id=`id`; chomp $id; my $user; my $box_log; my $log_flg=0; my $add_info=1; my $log_name="autosys_job_reporter.errlog"; if($id=~ /(\=\d+?)\s*\((.+?)\)/) { $user=$2; } if(defined $user) { if(-e "/home/$user" && -w "/home/$user") { $box_log="/home/$user/$log_name"; $log_flg=1; } elsif(-e "/$user" && -w "/$user") { $box_log="/$user/$log_name"; $log_flg=1; } } #print "$box_log\n"; my $job=&trim($ARGV[0]); $job=&valid($job); #print "JOB:--$job--\n"; my $num_arg=scalar(@ARGV); #print "ARGV--$num_arg--\n"; my $opts; if($num_arg > 1) { shift(@ARGV); foreach my $op (@ARGV) { &valid_opts($op); } $opts=join("",@ARGV); $opts=~ s/\-//g; &check_opts($opts); #print "MORE...$opts...\n"; } unless(defined $opts) { $opts="n"; } #print "OPTS=$opts=\n"; &job_check($job,$opts); #____PROG_END____# ####################### SUBROUTINE : job_check() #################### =head 1. Check the job whether exist or not. 2. Gathers required box job and desired job's infromated output and prints. 3. Prints Additional Information of the job. =cut sub job_check { my ($job, $opts)=@_; my $rec; $job=&trim($job); my $box_f=0; $rec=`autorep -J $job -q -l0`; $rec=&trim($rec); my $rec_orig=$rec; $rec=~ s/\n/_##_/g; $rec=$rec."_##_"; #print "$rec\n"; if(defined $job && $job ne "") { my $box; if($rec=~/Invalid\s+Job\s+Name/i) { print "$rec_orig\n"; $job=&valid(""); } if($rec=~/insert_job\s*\:\s*(.+?)\s*job_type:\s*b\s*_\#\#\_/) { $box=$1; $box_f=1; #print "---IN 1\n"; } if($rec=~/box_name\s*\:\s*(.+?)\s*\_\#\#\_/) { $box=$1; #print "---IN 2\n"; } if(defined $box && $box ne "") { print "\n\033[1m================================================================\033[0m\n"; print "\033[44m\033[37m\033[1mBox Information : $box\033[0m\n"; my $jr=`autorep -J $box`; my $w=&jr_wide_check($jr); if($w==1) { $jr=`autorep -J $box -w`; } my @lines=split(/\n/,$jr); foreach my $li (@lines) { if($li=~ /\b$job\b/) { print "\033[45m\033[37m\033[1m$li\033[0m\n"; } else { print "$li\n"; } } print "\n"; if($box_f==1) { print "\033[44m\033[37m\033[1mBox Jil : $job\033[0m\n"; print "\n$rec_orig\n"; print "\n\033[1m================================================================\033[0m\n"; #print "\n================================================================\n"; exit(0) if($opts eq 'n'); } } else { print "\n\033[1m================================================================\033[0m\n"; print "\033[44m\033[37m\033[1mNo Box Job Found for this Job.\033[0m\n"; my $jr=`autorep -J $job`; my $w=&jr_wide_check($jr); if($w==1) { $jr=`autorep -J $box -w`; } #print "$jr"; my @lines=split(/\n/,$jr); foreach my $li (@lines) { if($li=~ /\b$job\b/) { print "\033[45m\033[37m\033[1m$li\033[0m\n"; } else { print "$li\n"; } } } ##################################################################### if($box_f !=1) { my ($prof, $script, $out, $err, $watch, $desc, $cond); my $prof_f=0; if($rec=~/profile\s*\:\s*(.+?)\s*\_\#\#\_/) { $prof=$1; $prof=&trim($prof); if(defined $prof && $prof ne "") { $prof_f=1; } } print "\n================================================================\n"; print "\033[44m\033[37m\033[1mJob Information : $job\033[0m\n"; ################### Serching Important Attributes ################### if($rec=~ /description\s*\:\s*(.+?)\s*\_\#\#\_/) { $desc=$1; print "Description: $desc\n"; } if($rec=~ /condition\s*\:\s*(.+?)\s*\_\#\#\_/) { $cond=$1; print "Condition: $cond\n"; } print "\n"; if($rec=~ /command\s*\:\s*(.+?)\s*\_\#\#\_/) { $script=$1; } if($rec=~ /std_out_file\s*\:\s*(.+?)\s*\_\#\#\_/) { $out=$1; } if($rec=~ /std_err_file\s*\:\s*(.+?)\s*\_\#\#\_/) { $err=$1; } if($rec=~ /watch_file\s*\:\s*(.+?)\s*\_\#\#\_/) { $watch=$1; } ########################## Printing Attributes ###################### &print_attr($script, $prof_f,$prof,"ls-no","command"); &print_attr($out, $prof_f,$prof,"ls-yes","std_out_file"); &print_attr($err,$prof_f,$prof,"ls-yes","std_err_file"); &print_attr($watch, $prof_f,$prof,"ls-yes","watch_file"); &print_attr($prof, $prof_f,$prof,"ls-no","profile"); print "\n\033[1m================================================================\033[0m\n"; } ###################### Additional Information ####################### my $flg_p=0; if($opts ne "n") { my @all_opts=split(/|/,$opts); my $all=join(" ",@all_opts); if($all=~ /a/) { &jr_q($job) if($box_f !=1); &jr_u($job); &jr_d($job); &jr_p($job,1); &jr_t($job); $flg_p=1; } else { foreach my $op (@all_opts) { if($op eq "q" && $box_f !=1) { &jr_q($job); $flg_p=1; } if($op eq "u") { &jr_u($job); $flg_p=1; } if($op eq "d") { &jr_d($job); $flg_p=1; } if($op eq "p") { &jr_p($job,1); $flg_p=1; } if($op eq "t") { &jr_t($job); $flg_p=1; } if($op eq "h") { print "\033[44m\033[37m\033[1mInformation About $0 : [-h]\033[0m\n"; &usage(); $flg_p=1; } } } print "\n\033[1m================================================================\033[0m\n" if($flg_p==1); } }#job defined } ###################### SUBROUTINE : trim ()########################## #removes prefix and postfixed space/newline/tab from input string sub trim { my ($str)=@_; return undef unless(defined $str); $str=~s/^\s+|\s+$//g; return $str; } ###################### SUBROUTINE : valid ########################### #Checks the string not to be a NULL one. sub valid { my ($job)=@_; if(!defined $job) { &usage(); exit(11); } elsif($job eq "") { &usage(); exit(13); } elsif($job eq "-h") { print "\033[44m\033[37m\033[1mInformation About $0 : [-h]\033[0m\n"; &usage; exit(0); } else { return $job; } } ##################################################################### sub usage { print "\nUsage:\n\n$0 : Provides Information of Job's Important Attributes along with the Status & more...\n"; print "\nOptions :\n"; print "$0 \n"; print "$0 [<-adhpqtu>]\n\n"; print "-h : Help.\n-a : All Options.\n-u : Upstream Dependency.\n-d : Downstream Dependency.\n-p : Previous Runs.\n-q : Jil of Job.\n-t : Calculates the Run Time of All Previous Runs.\n\n"; } ####################### SUBROUTINE : valid_opts() ################### #checks the prefix of options. sub valid_opts { my ($str)=@_; unless($str=~ /^-/ && $str ne "-") { print "Invalid Option :$str\n"; &usage(); exit(1); } } ####################### SUBROUTINE : check_opts() ################### #validates the options provided sub check_opts { my ($str)=@_; my @all_opts=split(/|/,$str); #print "ALL_OPTS===@all_opts===\n"; foreach my $op (@all_opts) { unless($op=~ /a|h|p|q|t|u|d/) { print "Invalid Option :$op\n"; &usage(); exit(1); } } } ##################### SUBROUTINE : substitute_WIN() ################# #subtitutes Win NT charaters with Unix charaters. #This a tailor made subroutine can be changed as per the requirment. sub substitute_WIN { my ($str)=@_; $str=&ini($str); # ADD YOUR CODE HERE FOR HANDLING THE WIN<>UNIX PATH/ALIAS $str=~ s|\\|/|ig; return $str; } ###################### SUBROUTINE : ini ()########################### #initialize input string sub ini { my ($str)=@_; return "" unless(defined $str); return $str; } ################### SUBROUTINE : remove_env_str ##################### #removes unwanted lines/character from output after running the profile sub remove_env_str { my ($str)=@_; $str=&ini($str); my ($str_un,$str_nc)=split(/\//,$str,2); $str_nc=&ini($str_nc); if($str=~/\//) { $str_nc='/'.$str_nc; } $str_nc=&trim($str_nc); if($str_nc eq "") { $str_nc=$str; } return $str_nc; } ##################### SUBROUTINE : ls_file() ######################## # It lists the file. retuns not found message if the file can't be listed. sub ls_file { my ($file)=@_; my $ls_file; if(-f $file) { $ls_file=`ls -lrt $file`; chomp $ls_file; return $ls_file } else { return "$file [File Not Found]"; } } ################# SUBROUTINE : print_attr() ######################### # Prints the result in a desired format. sub print_attr { my ($attr, $flag, $prof,$ls_flg, $type)=@_; $attr=&trim($attr); #print "=====$attr, ===$flag, ==$prof,=$ls_flg, -$type\n"; if($flag==1) { if(defined $attr && $attr ne "") { $attr=~ s/\bcp\b/CP/g; $attr=~ s/\bmv\b/MV/g; $attr=~ s/\brm\b/RM/g; $attr=~ s/\>/\\>/g; $attr=~ s/\ $box_log \necho $attr`; } else { $val_scr=`__profile=$prof \n AUTO_JOB_NAME=$job \n . $prof \necho $attr`; } my $att_flg=0; if(defined $val_scr && $val_scr ne "") { $val_scr=&substitute_WIN($val_scr); $val_scr=&remove_env_str($val_scr); } else { $val_scr=$attr; $ls_flg='ls-no'; } $val_scr=~ s/\bCP\b/cp/g; $val_scr=~ s/\bMV\b/mv/g; $val_scr=~ s/\bRM\b/rm/g; $val_scr=~ s/\bAND\b/and/g; $val_scr=~ s/\bOR\b/or/g; $val_scr=~ s/\d{6}.out/*.out/g; $val_scr=~ s/\d{6}.err/*.err/g; if($ls_flg eq "ls-yes") { $val_scr=&ls_file($val_scr); } print "$type\: $val_scr\n"; } } else { if(defined $attr && $attr ne "") { my $val_scr=&substitute_WIN($attr); if($ls_flg eq "ls-yes") { $val_scr=&ls_file($val_scr); } print "$type\: $val_scr\n"; } } return; } ############### SUBROUTINE : jr_wide_check() ######################## =head Checks if there is a requirment of printing (wide spaced job report). sends a flag 1 if the job status string contains dots else 0 =cut sub jr_wide_check { my ($str)=@_; $str=~ s/\n/_#_#_/g; if($str=~ /\.\.\./) { return(1); } else { return(0); } } ######################### SUBROUTINE : jr_q() ####################### #shouws jil information of the job sub jr_q { my ($job)=@_; print "\n"; print "Please Wait..."; my $q=`autorep -J $job -q -l0`; $q=&trim($q); print "\r\033[44m\033[37m\033[1mAdditional Information #$add_info : [-q] Jil of ($job)\033[0m\n\n"; $add_info++; print "$q\n"; #print "\n\033[1m================================================================\033[0m\n"; return; } ######################### SUBROUTINE : jr_u() ####################### #shows upstream dependency sub jr_u { my ($job)=@_; print "\n"; print "Please Wait..."; my $res; my $u=`autorep -J $job -q -l0`; my @all_jil=split(/\n/, $u); my $cond; foreach my $ll (@all_jil) { if($ll=~ /condition\s*:\s*(.+)/) { $cond=$1; last; } } unless(defined $cond) { $res="No Upstream Dependency Found!\n"; } else { my @arr=split(/\(/,$cond); shift @arr; foreach my $u (@arr) { my ($val, $odd)=split(/\)/,$u,2); $val=&trim($val); my $jr=`autorep -J $val |grep "$val"`; chomp $jr; $res .=$jr."\n"; } } print "\r\033[44m\033[37m\033[1mAdditional Information #$add_info : [-u] Upstream Dependency of ($job)\033[0m\n\n"; $add_info++; print "$res"; #print "\n\033[1m================================================================\033[0m\n"; return; } ######################### SUBROUTINE : jr_d() ####################### #Shows Downstream Dependency sub jr_d { my ($job)=@_; print "\n"; print "Please Wait..."; my $res=`which job_depends`; if($res !~ /^no\s+/) { my $depend=`job_depends -c -J $job`; my $res; my @dep=split(/\n/,$depend); my @depend; foreach my $dd (@dep) { if($dd=~ /\.\.\./) { my ($val, $odd)=split(/SUCCESS/, $dd, 2); $val=&trim($val); push(@depend,$val); } } my $num=scalar(@depend); if($num == 0) { $res="No Downstream Dependency Found!\n"; } else { foreach my $d (@depend) { my $jr=`autorep -J $d|grep "$d"`; chomp $jr; $res .=$jr."\n"; } } print "\r\033[44m\033[37m\033[1mAdditional Information #$add_info : [-d] Downstream Dependency of ($job)\033[0m\n\n"; $add_info++; print "$res"; } else { print "\r\033[44m\033[37m\033[1mAdditional Information #$add_info : [-d] Downstream Dependency of ($job)\033[0m\n\n"; $add_info++; print "\r\033[41m\033[1mAutosys Command : \'job_depends\' Not Found!\033[0m\n"; } #print "\n\033[1m================================================================\033[0m\n"; return; } ######################### SUBROUTINE : jr_p() ####################### #shows previous job runs details sub jr_p { my ($job, $flg)=@_; print "\n" if($flg); print "Please Wait..." if($flg); my $res; #autorep -j $job -l0 -r -2|grep $job my $p=""; my $run=0; while( $p !~/Does\s+not\s+have\s+a\s+run/i) { $p=`autorep -j $job -l0 -r -$run|grep $job`; if($run==0 && $p !~/Does\s+not\s+have\s+a\s+run/i) { $res="Latest Run $run : $p"; $run++; } else { $res .="Previous Run $run : $p"; $run++; } } print "\r\033[44m\033[37m\033[1mAdditional Information #$add_info : [-p] Previous Runs of ($job)\033[0m\n\n" if($flg); $add_info++ if($flg); print "$res" if($flg); #print "\n\033[1m================================================================\033[0m\n"; return $res; } ######################### SUBROUTINE : jr_t() ####################### #shows time taken for job to complete. sub jr_t { my ($job)=@_; print "\n"; print "Please Wait..."; my $res=""; my $t=&jr_p($job,0); my @all=split(/\n/,$t); pop @all; foreach my $li (@all) { if($li =~ /\-\-/) { my ($prefix, $time_stamp)=split(/\:/,$li,2); my ($start, $end, $status); #yyyyyyyy ----- 02/24/2007 23:38:41 SU 0/0 if($time_stamp =~ m|\s+\-\-\-\-\-\s+(\d{2}/\d{2}/\d{4}\s+\d{2}:\d{2}:\d{2})\s+(\w{2})\s+|) { $end=$1; $status=$2; $end=~ s|(\d{2})/(\d{2})/(\d{4}) |$3-$1-$2|g; $start="####-##-## ##:##:##"; $res .="$prefix: $start to $end $status ==> N/A for Time Calc.\n"; } #zzzzzzxxxxxxx 03/04/2009 20:15:11 ----- RU 4411130/1 elsif($time_stamp =~ m|\s+(\d{2}/\d{2}/\d{4}\s+\d{2}:\d{2}:\d{2})\s+\-\-\-\-\-\s+(\w{2})\s+|) { $start=$1; $status=$2; $start=~ s|(\d{2})/(\d{2})/(\d{4}) |$3-$1-$2|g; $end="####-##-## ##:##:##"; $res .="$prefix: $start to $end $status ==> N/A for Time Calc.\n"; } elsif($time_stamp =~ m|\s+\-\-\-\-\-\s+\-\-\-\-\-\s+(\w{2})\s+|) { $status=$1; $res .="$prefix:####-##-## ##:##:## to ####-##-## ##:##:## $status ==> N/A for Time Calc.\n"; } } else { my ($prefix, $time_stamp)=split(/\:/,$li,2); #Latest Run 0 : xxxxxxxxx 03/04/2009 05:21:38 03/04/2009 05:21:40 SU 4403364/1 if($time_stamp=~ m|\s+(\d{2}/\d{2}/\d{4}\s+\d{2}:\d{2}:\d{2})\s+(\d{2}/\d{2}/\d{4}\s+\d{2}:\d{2}:\d{2})\s+(\w{2})\s+|) { my $start=$1; my $end=$2; my $status=$3; $start=~ s|(\d{2})/(\d{2})/(\d{4}) |$3-$1-$2|g; $end=~ s|(\d{2})/(\d{2})/(\d{4}) |$3-$1-$2|g; my ($days,$hr,$min, $sec)=&time_taken(date1 => $start,date2 => $end); $res .="$prefix: $start to $end $status ==> $days Days, $hr Hr, $min Min, $sec Sec.\n"; } } } print "\r\033[44m\033[37m\033[1mAdditional Information #$add_info : [-t] Run Time for ($job)\033[0m\n\n"; $add_info++; print "$res"; return; } ##################### SUBROUTINE : time_taken() ##################### =head Calculates the job run time. input string : key1 : Start date => value1 : YYYY-MM-DD hh:mm:ss key2 : End date => value2 : YYYY-MM-DD hh:mm:ss returns : days, hours, min, and sec. =cut sub time_taken (%) { my %args = @_; my @offset_days = qw(0 31 59 90 120 151 181 212 243 273 304 334); my $year1 = substr($args{'date1'}, 0, 4); my $month1 = substr($args{'date1'}, 5, 2); my $day1 = substr($args{'date1'}, 8, 2); my $hh1 = substr($args{'date1'},11, 2) || 0; my $mm1 = substr($args{'date1'},14, 2) || 0; my $ss1 = substr($args{'date1'},17, 2) if (length($args{'date1'}) > 16); $ss1 ||= 0; my $year2 = substr($args{'date2'}, 0, 4); my $month2 = substr($args{'date2'}, 5, 2); my $day2 = substr($args{'date2'}, 8, 2); my $hh2 = substr($args{'date2'},11, 2) || 0; my $mm2 = substr($args{'date2'},14, 2) || 0; my $ss2 = substr($args{'date2'},17, 2) if (length($args{'date2'}) > 16); $ss2 ||= 0; my $total_days1 = $offset_days[$month1 - 1] + $day1 + 365 * $year1; my $total_days2 = $offset_days[$month2 - 1] + $day2 + 365 * $year2; my $days_diff = $total_days2 - $total_days1; my $seconds1 = $total_days1 * 86400 + $hh1 * 3600 + $mm1 * 60 + $ss1; my $seconds2 = $total_days2 * 86400 + $hh2 * 3600 + $mm2 * 60 + $ss2; my $ssDiff = $seconds2 - $seconds1; my $dd = int($ssDiff / 86400); my $hh = int($ssDiff / 3600) - $dd * 24; my $mm = int($ssDiff / 60) - $dd * 1440 - $hh * 60; my $ss = int($ssDiff / 1) - $dd * 86400 - $hh * 3600 - $mm * 60; return ($dd, $hh, $mm , $ss); }