#!/usr/bin/perl -w ########################################################################### # # qhist --> displays info about completed jobs # # Copyright 2008,2012 Philip Johnson. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published # by the Free Software Foundation, either version 3 of the License, # or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License at for # more details. # # Version history: # 1.0 --> Mar 2008 # 1.1 --> Oct 2012 Report number CPUs requested if more than 1 # ########################################################################### use strict; use POSIX qw(strftime); my $arg = join("' '", @ARGV); $arg = "'".$arg."'" if length($arg); my $majorVersion; { my @r = `condor_version`; die "ERROR: is condor installed & in path?\n" if $? != 0; ($majorVersion) = $r[0] =~ /\s(\d+)\./; } my $opt = ($majorVersion >= 7) ? '-backwards -long' : '-l'; open QPIPE, "condor_history $opt $arg|" or die $!; printf "%-9s%-10s%-3s%-10s%-12s%s\n", 'ID', 'OWNER', 'ST', 'RUNTIME', 'COMPLETED@', 'CMD'; my %s; while () { if (/^$/) { $s{suspendTime} = 0 if !defined($s{suspendTime}); my $runtime = '--'; my $completeTime = '--'; if (defined $s{currStart}) { if (defined $s{completionDate} && $s{completionDate} > 0) { $completeTime = StringifyDate($s{completionDate}); } $runtime =StringifyElapsedTime($s{RemoteWallClock}-$s{suspendTime}); if ($s{cpus} > 1) { $runtime = $s{cpus}.'x'.$runtime; } } if (!defined $s{cmd}) { $s{cmd} = '[?? -- not submitted using qsub]'; } printf "%-9s%-10s%-3s%-10s%-12s%s\n", $s{clusterId}.'.'.$s{procId}, $s{owner}, $s{status}, $runtime, $completeTime, $s{cmd}; undef %s; } if (/^ClusterId/) { ($s{clusterId}) = /(\d+)/; } elsif (/^ProcId/) { ($s{procId}) = /(\d+)/; } elsif (/^Owner/) { ($s{owner}) = /"(\S+)"/; } elsif (/^JobStatus/) { ($s{status}) = /(\d+)/; $s{status} = ('?', 'I', 'R', 'X', 'C', 'H')[$s{status}]; } elsif (/^CompletionDate/) { ($s{completionDate}) = /(\d+)/; # } elsif (/^LastVacateTime/) { # ($s{vacateDate}) = /(\d+)/; } elsif (/^CumulativeSuspensionTime/) { ($s{suspendTime}) = /(\d+)/; } elsif (/^JobCurrentStartDate/) { ($s{currStart}) = /(\d+)/; } elsif (/^RemoteWallClock/) { ($s{RemoteWallClock}) = /(\d+)/; } elsif (/^EnteredCurrentStatus/) { ($s{EnteredCurrentStatus}) = /(\d+)/; } elsif (/^Env =/) { ($s{cmd}) = /CONDOR_CMD_LINE=(.+?);/; if (defined $s{cmd}) { $s{cmd} =~ s/SeMiCoLoN/;/g; $s{cmd} =~ s/\\"/"/g; #condor escapes quotes in Env on output } } elsif (/^RequestCpus/) { ($s{cpus}) = /(\d+)/; } } close QPIPE; # ------------------------------------------------------------------------- # Take an elapsed time in seconds and make meaningful string # sub StringifyElapsedTime { my ($t) = @_; my $s = ''; if (int($t / (24*3600))) { $s .= int($t / (24*3600)). 'd:'; $s .= int(($t % (24*3600))/3600). 'h'; } elsif (int(($t % (24*3600))/3600)) { $s .= int(($t % (24*3600))/3600). 'h:'; $s .= int(($t % 3600)/60). 'm'; } elsif (int(($t % 3600)/60)) { $s .= int(($t % 3600)/60). 'm:'; $s .= ($t % 60). 's'; } else { $s .= $t.'s'; } return $s; } # ------------------------------------------------------------------------- # Take a date in seconds since epoch and make meaningful string # sub StringifyDate { return strftime "%m/%d %H:%M", localtime($_[0]); }