#!/usr/bin/perl -w # # groking from: # http://www.backupcentral.com/cgi-bin/netbackup-fom?_highlightWords=bpdbjobs&file=194 # # output's gr; this is just a filter version of bplogcheck.pl # # take it use, don't blame me if it breaks something use strict; use POSIX; use Data::Dumper; my @job_info_labels = ('jobid', 'jobtype', 'state', 'status', 'class', 'sched', 'client', 'server', 'start', 'elapsed', 'end', 'stunit', 'try', 'operation', 'kbytes', 'files', 'path_last_written', 'percent', 'jobpid', 'owner', 'subtype', 'classtype', 'schedtype', 'priority', 'group', 'master_server', 'retention_units', 'retention_period', 'compression', 'kbyteslastwritten', 'fileslastwritten', 'filelistcount'); my @job_try_labels_1 = ('trypid', 'trystunit', 'tryserver', 'trystarted', 'tryelapsed', 'tryended', 'trystatus', 'trystatusdescription', 'trystatuscount'); my @job_try_labels_2 = ('trybyteswritten','tryfileswritten'); my $reverse = 1; # Assuming you've got a lot of bpdbjobs output in a file, you # probably want this. # Jacked from the (TOTALLY UNDOCUMENTED SO I CAN'T USE IT WITHOUT # LOTS OF PAIN) NBU::Job. my %op_codes = ( -1 => ' - ', 25 => 'wai', 2 => 'con', 26 => 'con', 0 => 'act', 27 => 'mnt', 29 => 'pos', 3 => 'wri', 35 => 'wri', 5 => 'dup', ); # The rest are just from bpdbjobs(1M) (operation isn't discussed # there, jerks). my %jt_codes = ( 0 => 'b', 1 => 'a', 2 => 'r', 3 => 'V', 4 => 'd', 5 => 'i', 6 => 'c', 7 => 'v', ); my %state_codes = ( 0 => 'que', 1 => 'act', 2 => 'req', 3 => 'don', ); sub parse_line { chomp; # Yeah, they really include escaped ,s; ditch them # ... only but there are some legit \\, situations on Windows $_ =~ s#\\\\#//#g; # You can also specify multiple STUs for vaults through different # duplication rules, and there are separated by /, / in the -all_columns # output. (Could I make this stuff up? No.) $_ =~ s/, /; /g; $_ =~ s/\\[,;]//g; my $job; my @columns = split(','); my $idx = 0; foreach my $label (@job_info_labels) { $job->{$label} = $columns[$idx]; $idx++; } my @files = (); if ($job->{'filelistcount'} > 0) { @files = @columns[$idx..$idx+$job->{'filelistcount'}-1]; } $job->{'files'} = [@files]; $idx += $job->{'filelistcount'} ; $job->{'trycount'} = $columns[$idx]; # Now get the try data. Within the try data # is a list of try status lines. my @trylist = (); $idx++; my ($trydata, @trystatuslines); for (1..$job->{'trycount'}) { undef($trydata); foreach my $trylabel ( @job_try_labels_1 ) { $trydata->{$trylabel} = $columns[$idx++]; if ($trylabel eq 'trystunit') { # Vault duplication jobs have, without warning, multiple # STUs here until ($columns[$idx + 1] =~ m/^[0-9]+$/) { $trydata->{$trylabel} .= "; $columns[$idx++]"; } } } @trystatuslines = @columns[$idx..$idx+$trydata->{'trystatuscount'}-1]; $trydata->{'trystatuslines'} = [@trystatuslines]; $idx += $trydata->{'trystatuscount'}; foreach my $trylabel ( @job_try_labels_2 ) { $trydata->{$trylabel} = $columns[$idx]; $idx++; } push @trylist, $trydata; } $job->{'trylist'} = [@trylist]; return $job; } #while (($reverse == 1) ? reverse <> : <>) { while (<>) { my $start = (split(',', $_))[8]; my $job = parse_line($_); my ($policy, $sched, $client, $hours, $minutes, $seconds, $meta); $policy = substr($job->{'class'}, 0, 24); $sched = substr($job->{'sched'}, 0, 10); $client = substr($job->{'client'}, 0, 8); $hours = ($job->{'elapsed'} - ($job->{'elapsed'} % (60 * 60))) / (60 * 60); $minutes = (($job->{'elapsed'} - ($job->{'elapsed'} % 60)) / 60) - ($hours * 60); $seconds = $job->{'elapsed'} - ($hours * 60 * 60) - ($minutes * 60); if ($job->{'state'} == 3) { # done $meta = $job->{'status'}; } elsif ($job->{'state'} == 1) { # active $meta = $op_codes{$job->{'operation'}}; } else { # requeued or queued $meta = $state_codes{$job->{'state'}}; } $meta = '...' unless defined($meta); printf "%d %s %3s %24s %10s %8s %s %02d:%02d:%02d\n", $job->{'jobid'}, $jt_codes{$job->{'jobtype'}}, $meta, $policy, $sched, $client, strftime('%m%d %T', localtime($job->{'start'})), $hours, $minutes, $seconds; }