#!/usr/bin/perl # Author: Alan J. Pippin # Description: This script parses logfiles generated by the following zfs scripts: # zfs-replicate $logfile=shift(@ARGV); $startdate=shift(@ARGV); $backup_pool="backups"; sub usage { print "Usage: $0 \n"; exit 0; } if(! -f "$logfile") { &usage; } $kilo = 1024; $mega = 1024 * 1024; $giga = 1024 * 1024 * 1024; %month2num = ( "Jan" => "01", "Feb" => "02", "Mar" => "03", "Apr" => "04", "May" => "05", "Jun" => "06", "Jul" => "07", "Aug" => "08", "Sep" => "09", "Oct" => "10", "Nov" => "11", "Dec" => "12"); sub time_to_seconds { my ($hour,$minute,$sec) = @_; $seconds = ($hour * 60 * 60) + ($minute * 60) + ($sec); return($seconds); } sub adjust_duration { my ($duration) = @_; if($duration > 3600) { $duration=int($duration/3600); $duration.="h"; } elsif($duration > 60) { $duration=int($duration/60); $duration.="m"; } else { $duration.="s"; } return $duration; } sub adjust_data { my ($data) = @_; if(abs($data) > ($giga)) { $data = $data / $giga; $data = sprintf("%2.2fGb",$data); } elsif(abs($data) > ($mega)) { $data = int($data / $mega); $data = "$data"."Mb"; } elsif(abs($data) > ($kilo)) { $data = int($data / $kilo); $data = "$data"."Kb"; } return $data; } sub parse_replicate_logfile { $in_replicate=0; $date=""; %totals=(); while() { $line = $_; if(($in_replicate == 0) && ("$startdate" ne "") && ($line !~ /$startdate/)) { next; } if($line =~ /(\S+)\s+(\S+)\s+(\d+)\s+(\d+):(\d+):(\d+)\s+(\S+)\s+(\S+)/) { $dayname=$1; $month=$2; $daynum=$3; $hour=$4; $minute=$5; $sec=$6; $year=$8; if(($in_replicate == 0) && ($line =~ /replicate started/)) { $in_replicate = 1; $date="$dayname $month $daynum $hour:$minute:$sec $year"; $totals{$date}{data} = 0; $totals{$date}{transfertime} = 0; $totals{$date}{duration} = time_to_seconds($hour,$minute,$sec); } elsif(($in_replicate == 1) && ($line=~ /replicate complete/)) { $in_replicate = 0; $totals{$date}{duration} = time_to_seconds($hour,$minute,$sec) - $totals{$date}{duration}; } } if(($in_replicate == 1) && ($line =~ /received ([\d\.]+)(\w+)/)) { $data = $1; $size = $2; if($size =~ /Kb/i) { $data = $data * $kilo; } if($size =~ /Mb/i) { $data = $data * $mega; } if($size =~ /Gb/i) { $data = $data * $giga; } chomp($line); $totals{$date}{data} += $data; } if(($in_replicate == 1) && ($line =~ /in (\d+) seconds/)) { $transfertime = $1; $totals{$date}{transfertime} += $transfertime; } } foreach $date (keys %totals) { $duration=adjust_duration($totals{$date}{duration}); $data=adjust_data($totals{$date}{data}); $transfertime=adjust_duration($totals{$date}{transfertime}); if($totals{$date}{transfertime} > 0) { $rate = adjust_data(int($totals{$date}{data}/$totals{$date}{transfertime})); } else { $rate = 0; } print "$date: data=${data} transfertime=$transfertime rate=${rate}/sec duration=$duration\n"; } } sub parse_snapshot_totals_logfile { %totals=(); $in_totals=0; $maxlen=0; $found_startdate=0; $header=""; while() { $line = $_; if($line =~ /logfile turned over/) { next; } if(($in_totals == 0) && ("$startdate" ne "") && ($line !~ /$startdate/) && ($found_startdate==0)) { next; } if(($in_totals == 0) && ("$startdate" ne "") && ($line =~ /$startdate/) && ($found_startdate==0)) { $found_startdate=1; } if(($in_totals == 0) && ($line =~ /(\S+)\s+(\S+)\s+(\d+)\s+(\d+):(\d+):(\d+)\s+(\S+)\s+(\S+)/)) { $dayname=$1; $month=$2; $daynum=$3; $hour=$4; $minute=$5; $sec=$6; $year=$8; $in_totals = 1; $month = $month2num{$month}; if($daynum < 10) { $daynum = "0".$daynum; } $date="$month-$daynum-$year"; if(!defined $founddates{$date}) { $header .= $date . " "; } $founddates{$date} = 1; } elsif(($in_totals == 1) && ($line =~ /^\s+$/)) { $in_totals = 0; } elsif(($in_totals == 1) && ($line =~ /(\S+)\s+([\d\.]*)(\w+)\s+(\d+)/)) { $filesystem = $1; $data = $2; $size = $3; $num_snaps = $4; if($filesystem =~ /Snapshots/ || $filesystem =~ /Total/) { next; } if($filesystem =~ /^$backup_pool/) { next; } if(length($filesystem) > $maxlen) { $maxlen = length($filesystem); } if($size =~ /K/i) { $data = $data * $kilo; } if($size =~ /M/i) { $data = $data * $mega; } if($size =~ /G/i) { $data = $data * $giga; } chomp($line); $totals{$filesystem}{$date}{data} = $data; if($totals{$filesystem}{start_data} == 0) { $totals{$filesystem}{start_data} = $data; } $totals{$filesystem}{delta} = $data - $totals{$filesystem}{start_data}; } } $total_delta=0; printf("%-${maxlen}s %s %s\n","ZFS Filesystem","$header","Net Change"); foreach $filesystem (sort keys %totals) { $hashref = $totals{$filesystem}; $data=""; foreach $date (sort keys %$hashref) { if($date !~ /(\d+)-(\d+)-(\d+)/) { next; } $date_data=adjust_data($totals{$filesystem}{$date}{data}); if($date_data eq "") { $date_data = "0"; } $data .= sprintf("%10s",$date_data). " "; $date_totals{$date}{data} += $totals{$filesystem}{$date}{data}; } $data_total=adjust_data($data_total); $total_delta+=$totals{$filesystem}{delta}; $delta=adjust_data($totals{$filesystem}{delta}); printf("%-${maxlen}s %s %10s\n",$filesystem,$data,$delta); } $data=""; $data_len=length($data); $total_delta=adjust_data($total_delta); foreach $date (sort keys %date_totals) { $date_data=adjust_data($date_totals{$date}{data}); $data .= sprintf("%10s",$date_data). " "; } printf("%-${maxlen}s %-${data_len}s %10s\n","Totals:",$data,$total_delta); } ######### # MAIN ######### #print "-> Parsing $logfile\n"; if("$logfile" =~ /\.[bz2|gz]/) { open(FILE,"zcat $logfile|") || die "-E- Unable to open $logfile\n"; } else { open(FILE,"$logfile") || die "-E- Unable to open $logfile\n"; } if($logfile =~ /replicate/) { parse_replicate_logfile(); } if($logfile =~ /snapshot-totals/) { parse_snapshot_totals_logfile(); } close(FILE);