Saturday, December 8, 2007

NetBackup Activity Report Script

Here's a little something extra for this week that I cooked up to help me be able to get a quick glance at the previous night's NetBackup activity. It's called bpreport.pl

In a future post, we'll explore the finer points of the script. For now, feel free to enjoy the fruits of my labor ;)

This Perl script parses the output of the bpdbjobs command (with the "-all_columns") switch and converts that nasty gigantic wad of codes and unix time stamps into a presentable daily report. We list the error (or problem) jobs at the top of the email sent to us in the morning (or a nice message indicating there were no errors) and also include the details of each job's progress/completion.

Since I wrote this specifically for myself, I only report on the Server Name, Policy Name, Kb backed up, number of minutes Elapsed during the backup, the start date and time and the end date and time. Note the report_span subroutine. You can feed this any number of seconds (86400 in a day) to determine how far back you want information regarding your backups' status from this script when you run it

I hope you enjoy it, or it makes your life easier (assuming you use NetBackup for your backup software).

If you do find it useful, and make use of it, including a link back to here in your code would be nice :)

Enjoy!

Creative Commons License
bpreport.pl by Mike Golvach is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 United States License.
Based on a work at linuxshellaccount.blogspot.com.
Permissions beyond the scope of this license may be available at http://linuxshellaccount.blogspot.com.

#!/usr/bin/perl
#
# bpreport.pl
#
# bpreport.pl by Mike Golvach is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 United States License. Based on a work at linuxshellaccount.blogspot.com. Permissions beyond the scope of this license may be available at http://linuxshellaccount.blogspot.com.
# 2007 - Mike Golvach - eggi@comcast.net
#

$first_tmp = $$;
$offset = $ARGV[0];

if ( -f "tmp.$first_tmp" ) {
unlink("tmp.$first_tmp")
}
if ( $#ARGV != 0 ) {
print "Usage: $0 TimeInSecondsToReportBack";
exit(1)
}

system("/usr/openv/netbackup/bin/admincmd/bpdbjobs -all_columns >>tmp.$first_tmp");

open(FT, "<tmp.$first_tmp");
@all_jobs = <FT>;
close(FT);
if ( -f "tmp.$first_tmp" ) {
unlink("tmp.$first_tmp")
}

$global_error_flag = 0;
$separator = "***************************************************";

foreach $job (@all_jobs) {
@file_list="";
@job = split(/,/, $job);
chomp($job[14]);
if ( $job[14] =~ /^$/ ) {
$job[14] = "0";
}
$error_flag = 0;
$report_time = $job[8];
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($job[8]);
$today = parse_date($sec,$min,$hour,$mday,$mon,$year,$wday);
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($job[10]);
$today_end = parse_date($sec,$min,$hour,$mday,$mon,$year,$wday);
if ( $today_end =~ /12\/31\/69/ ) {
$today_end = "JOB IN PROGRESS";
}
$today_span_pre = ( $job[9] / 60 );
$today_span = sprintf("%.2f", $today_span_pre);
$actual_time = time;
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$right_now = parse_date($sec,$min,$hour,$mday,$mon,$year,$wday);
report_span($report_time, $actual_time, $offset);
next if $dont_report;
if ( $job[3] > 1 ) {
@error_condition = `/usr/openv/netbackup/bin/admincmd/bperror -S $job[3]`;
$error_condition = $error_condition[0];
$job[3] = $error_condition;
$error_flag = 1;
$global_error_flag = 1;
}
next if ( $job[6] eq "backuphost" && $job[14] == 0 && ! $error_flag );
$file_list=32;
$file_list_still_going = 1;
$just_starting = 1;
while ($file_list_still_going) {
if ( $job[$file_list] =~ /(\/|\\|ALL)/ ) {
if ( $just_starting ) {
push(@file_list, "$job[$file_list] ");
$file_list++;
$just_starting = 0;
} else {
push(@file_list, "| $job[$file_list] ");
$file_list++;
}
} else {
$file_list_still_going = 0;
}
}
if ( $error_flag ) {
push(@job_errors, "$job[6] | $job[5] | $job[14] kb | $today_span | $today | $today_end\n${job[3]}@{file_list}\n$separator\n");
} else {
push(@job_successes, "$job[6] | $job[5] | $job[14] kb | $today_span | $today | $today_end\n@file_list\n$separator\n");
}
}
$|=1;
open(MAIL, "|/usr/lib/sendmail -t");
select(MAIL);
print "Subject: NetBackup Status Report - $right_now\n";
print "From: root\@backuphost\n";
print "Reply-To: root\@backuphost\n";
print "To: you\@yourdomain.com\n";
print "\n\n";
print "NetBackup Status Report\n";
print "-----------------------------------------------\n";
print "\n";
print "Jobs With Errors To Report!\n\n$separator\n";
print "Server | Policy | Kb | Min Elapsed | Start Date | Time |End Date | Time\n";
print "Error\n";
print "File List\n";
print "$separator\n\n";
@job_errors = sort @job_errors;
$job_error_count = @job_errors;
if ( $job_error_count ) {
print "@job_errors\n";
} else {
print "NO ERRORS TO REPORT!!!\n\n"
}
print "-----------------------------------------------\n";
print "\nJobs Completed Successfully!\n\n$separator\n\n";
print "Server | Policy | Kb | Min Elapsed | Start Date | Time |End Date | Time\n";
print "File List\n";
print "$separator\n\n";
@job_successes = sort @job_successes;
print "@job_successes\n";
select(STDOUT);
close(MAIL);

sub parse_date {

my ($sec,$min,$hour,$mday,$mon,$year,$wday) = @_;
%months = qw(0 Jan 1 Feb 2 Mar 3 Apr 4 May 5 Jun 6 Jul 7 Aug 8 Sep 9 Oct 10 Nov 11 Dec);
%weekdays = qw(0 Sun 1 Mon 2 Tue 3 Wed 4 Thu 5 Fri 6 Sat);
if ( $sec < 10 ) {
$sec = "0" . $sec;
}
if ( $min < 10 ) {
$min = "0" . $min;
}
if ( $hour < 10 ) {
$hour = "0" . $hour;
}
if ( $mday < 10 ) {
$mday = "0" . $mday;
}
if ( $yday < 10 ) {
$yday = "0" . $yday;
}
$mon = $mon + 1;
if ( $mon < 10 ) {
$mon = "0" . $mon;
}
$wday = $weekdays{$wday};
$year = 1900 + $year;
$year =~ s/^..(.*)$/$1/;
$nice_date = "${mon}/${mday}/$year | ${hour}:${min}:$sec";
}

sub report_span {

my ($report_time,$actual_time,$offset) = @_;
$dont_report = 0;
$more_than_offset_hours_old = $actual_time - $report_time;
if ( $more_than_offset_hours_old > $offset ) {
$dont_report = 1;
}
}


, Mike