[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 = &ltrim($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--