[Box Backup] Re:BoxReport.pl (was ChrisMerge_1828)
Matt Brown
boxbackup@fluffy.co.uk
Fri, 21 Sep 2007 18:56:42 +0100
--Apple-Mail-10--510678738
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
delsp=yes;
format=flowed
>>> P.S If anyone is interested in the boxreport.pl script (its a
>>> rehash of the sa-stats.pl script for spamassassin) they are
>>> welcome :-)
>>
>> Yes I would like to try out this script to see what it does. It
>> lets the clients know something is going on.
>
> Here is the first version I rushed together, I am sure it can be
> made a lot nicer and more streamlined - I am not great with perl,
> but does the trick for me. I am looking to put an array in for the
> bits to capture rather than lots of if statements, sort out the
> reporting dates etc...
>
> Anyway, the usual - if it breaks, deletes anything etc - use at own
> risk applies :-)
>
> I will be making some changes to this script and will post back to
> the list when done.
>
Hi,
Ok this version is a little more together, the report now includes
the ability to create a report for a specified period.
The script can be run by hand with or without command line parameters
(will default to the last found backup in the log file). Script does
require ExtendedLogging = yes to get the data it needs.
Options are:
Usage: boxreport.pl [options]
Options:
-l, --logfile=filename logfile to read
(default: /var/log/box)
-h, --help Displays this message
-D, --debug Sets debug mode
-V, --verbose Even more debug output
(more output, but performance hit)
--mail=emailaddress Sends report to emailaddress
--sendmail=/path/to/sendmail Location of sendmail binary
(default: /usr/sbin/sendmail)
--from=emailaddress Sets From: field of email
--start=01/01/1999 Report files from this date (optional)
--end=31/12/1999 Report files to this date (optional)
Enjoy. Please let me know feedback good, bad or indifferent.
-- Chris I might try altering the code for the backup-client to call
boxreport.pl if it finds ReportScript = /usr/local/bin/boxreport.pl
(or similar) in bbackupd.conf (if I can work out how to do it :-)
that way I can get the the report to generate and mail right after
the backup has completed rather than having to wait for cron etc.
Regards
Matt Brown
--Apple-Mail-10--510678738
Content-Transfer-Encoding: 7bit
Content-Type: text/x-perl-script;
x-mac-type=54455854;
x-unix-mode=0644;
x-mac-creator=21526368;
name=boxreport.pl
Content-Disposition: attachment;
filename=boxreport.pl
#!/usr/bin/perl
# Purpose : To report all files that have been sent to BoxBackup server from a log file.
# Author : Matt Brown <matt@mbrown.co.uk> 21st September 2007
#
# Credits
# Code use based upon elements of the sa-stats.pl script written for SpamAssassin.
use Parse::Syslog;
use Getopt::Long;
use Pod::Usage;
use Date::Manip;
use POSIX qw/strftime floor/;
use Time::Local;
use strict;
# Configuration section
my %opt = ();
$opt{'logfile'} = '/var/log/box'; # Default Log file
$opt{'sendmail'} = '/usr/sbin/sendmail'; # Path to sendmail stub
$opt{'from'} = 'Box Backup Admin <box@aquilar.co.uk>'; # Who is the mail from
#$opt{'mail'} = 'julian@aquilar.co.uk,matt@3aitsupport.com'; # Email address to send to
Date_Init("Language=English","DateFormat=non-US");
#####################################################################################
# Set vars to satisfy Use Strict;
my (@debug,@edates,@sdates,$start,$end,$bbstart,$bbend,$seconds,$minutes,$hours,
$date,$f1,$f2,$s1,$s2,$s3,$data,$summary);
# Get options
Getopt::Long::Configure("bundling");
GetOptions('logfile|l=s' => \$opt{'logfile'},
'debug|D' => \$opt{'debug'},
'mail=s' => \$opt{'mail'},
'sendmail=s' => \$opt{'sendmail'},
'from=s' => \$opt{'from'},
'help|h' => \$opt{'help'},
'start=s' => \$opt{'start'},
'verbose|V' => \$opt{'verbose'},
'end=s' => \$opt{'end'})
or pod2usage({-verbose => 0, -message => "Unknown options.", -exitval => 2});
# Get report period, if not set get last backup entry in log.
if (!$opt{'start'} || !$opt{'end'}){
push(@debug,'[Notice] No dates supplied, getting last backup info');
&getLastEntry;
} else {
$start = UnixDate(ParseDate($opt{'start'}), "%s");
$end = UnixDate(ParseDate($opt{'end'}), "%s")+86399;
push(@debug,'[Notice] Period requested ' . $opt{'start'} . ' to ' . $opt{'end'});
}
# show help on usage
if ($opt{'help'}) {
pod2usage();
}
# Now start getting the relevant bits from
# log file we want .. very messy but works
# (but only if extended logging enabled)
my $parser = Parse::Syslog->new( $opt{'logfile'} );
parseloop:
while (my $sl = $parser->next) {
next parseloop if ($sl->{'timestamp'} <= $start);
if ($sl->{'program'} =~ /\bBox Backup\b/i && $opt{debug}){
push(@debug,'[Notice] Found log entry at ' . UnixDate(ParseDate("epoch $sl->{'timestamp'}"),
'%d/%m/%y %H:%M:%S') . ' (' . $sl->{'timestamp'} . ') for ' . $sl->{'program'} .
' containing ' . $sl->{'text'}) if $opt{verbose};
}
if ($sl->{'text'} =~ /\bbackup-start\b/i){
push(@debug,"[Regex Match] " . UnixDate(ParseDate("epoch $sl->{'timestamp'}"),
'%d/%m/%y %H:%M:%S') . ' (' . $sl->{'timestamp'} . ') ' . $sl->{'host'} . ' '
. $sl->{'program'} . ' ' . $sl->{'pid'} . ' ' . $sl->{'text'}) if $opt{debug};
$date = UnixDate(ParseDate("epoch $sl->{'timestamp'}"), '%d/%m/%y %H:%M:%S');
$bbstart = $date;
}
if ($sl->{'text'} =~ /\bStoreFile\b/i){
push(@debug,"[Regex Match] " . UnixDate(ParseDate("epoch $sl->{'timestamp'}"),
'%d/%m/%y %H:%M:%S') . ' (' . $sl->{'timestamp'} . ') ' . $sl->{'host'} . ' ' .
$sl->{'program'} . ' ' . $sl->{'pid'} . ' ' . $sl->{'text'}) if $opt{debug};
($f1, $f2) = split ('"',$sl->{'text'});
$data .= $f2 ."\n";
}
if ($sl->{'text'} =~ /\bFile statistics\b/i){
push(@debug,"[Regex Match] " . UnixDate(ParseDate("epoch $sl->{'timestamp'}"), '%d/%m/%y %H:%M:%S') .
' (' . $sl->{'timestamp'} . ') ' . $sl->{'text'}) if $opt{debug};
($s1, $s2, $s3) = split (':', $sl->{'text'});
$summary = <rim($s2) . ":" . $s3;
}
if ($sl->{'text'} =~ /\bbackup-finish\b/i){
push(@debug,"[Regex Match] " . UnixDate(ParseDate("epoch $sl->{'timestamp'}"), '%d/%m/%y %H:%M:%S') .
' (' . $sl->{'timestamp'} . ') ' . $sl->{'host'} . ' ' . $sl->{'program'} . ' ' . $sl->{'pid'} . ' '
. $sl->{'text'}) if $opt{debug};
$date = UnixDate(ParseDate("epoch $sl->{'timestamp'}"), '%d/%m/%y %H:%M:%S');
$bbend = $date;
}
last parseloop if ($sl->{'timestamp'} >= $end);
}
# Call Build Report - here we can add later maybe
# html or something else more creative PDF ?
my $rpt = '';
$rpt = &build_text_report();
# Send report via email
if ($opt{'mail'}) {
open (SENDMAIL, "|$opt{'sendmail'} -oi -t -odb") or die "Can't open sendmail: $!\n";
print SENDMAIL "From: $opt{'from'}\n";
print SENDMAIL "To: $opt{'mail'}\n";
print SENDMAIL "Subject: Box Backup Report\n\n";
print SENDMAIL $rpt;
close (SENDMAIL);
} else {
print $rpt;
}
if ($opt{debug}){
&dbg;
}
#All done
exit 0;
##########################################
# Sub Routines
#########################################
sub ltrim($){
# Perl does not seem to have a trim function ?
# so this does the trick for a left trim :-)
my $string = shift;
$string =~ s/^\s+//;
return $string;
}
sub dbg{
# Ouput debug info from array when called !
print "------------------\nDebug Output\n------------------\n\n";
foreach(@debug){
print $_ . "\n";
}
print "\n------------------\n";
}
sub getLastEntry {
# Go through the entire log file and find all instances of backup-start and
# backup-end and then take the last array index in both arrays to work out
# last start and end times.
my $parser = Parse::Syslog->new( $opt{'logfile'} );
while (my $sl = $parser->next) {
if ($sl->{'text'} =~ /\bbackup-start\b/i){
push(@sdates, $sl->{'timestamp'});
} else {
if ($sl->{'text'} =~ /\bFile statistics\b/i){
push(@edates, $sl->{'timestamp'});
}
}
}
$start = $sdates[-1];
$end = $edates[-1];
push(@debug, '[Notice] Using ' . UnixDate(ParseDate("epoch $start"),
'%d/%m/%y %H:%M:%S') . ' as start of report');
push(@debug, '[Notice] Using ' . UnixDate(ParseDate("epoch $end"),
'%d/%m/%y %H:%M:%S') . ' as end of report');
return $start,$end;
}
sub build_text_report {
my $rpt = '';
$rpt .= "-----------------------------------------------------------------------------\n";
$rpt .= "Report Title : Box Backup - Backup Statistics\n";
$rpt .= "Report Date : " . strftime("%d-%m-%Y %H:%M:%S", localtime) . "\n";
if ($opt{debug}){
$rpt .= "Report Period : " . UnixDate(ParseDate("epoch $start"), '%d/%m/%y %H:%M:%S')
. " (" . $start . ") - " . UnixDate(ParseDate("epoch $end"), '%d/%m/%y %H:%M:%S') . " (" . $end . ")\n";
} else {
$rpt .= "Report Period : " . UnixDate(ParseDate("epoch $start"), '%d/%m/%y %H:%M:%S')
. " - " . UnixDate(ParseDate("epoch $end"), '%d/%m/%y %H:%M:%S') . "\n";
}
$rpt .= "-----------------------------------------------------------------------------\n\n";
if ($data){
$rpt .= "Files sent during this backup:\n\n";
$rpt .= $data . "\n";
} else {
$rpt .= "No files were backed up during this session.\n\n";
}
if ($summary){
$rpt .= $summary . "\n\n";
$rpt .= "<--------------- End of report --------------->\n";
}
return $rpt;
}
__END__
=head1 NAME
boxreport.pl - Reports list of files submitted to Box Backup server from a chosen logfile
=head1 VERSION
$Revision: 1.4 $
=head1 SYNOPSIS
Usage: boxreport.pl [options]
Options:
-l, --logfile=filename logfile to read
(default: /var/log/box)
-h, --help Displays this message
-D, --debug Sets debug mode
-V, --verbose Even more debug output
(more output, but performance hit)
--mail=emailaddress Sends report to emailaddress
--sendmail=/path/to/sendmail Location of sendmail binary
(default: /usr/sbin/sendmail)
--from=emailaddress Sets From: field of email
--start=01/01/1999 Report files from this date
--end=31/12/1999 Report files to this date
=cut
--Apple-Mail-10--510678738--