#!/usr/local/bin/perl -- # -*- cperl -*- use strict; use diagnostics; use Text::CSV_XS; use IO::File; use Date::Manip; use FileHandle; use Getopt::Std; my $usage = qq{usage: $0 -c csv_file [-h host] [-p partition] [-l level] [-d end_time] [-t start_time] where csv_file - comma seperated file produced by parse_legato_log host - (default: all) filter for this hostname Ex: valid regexps, "host", "host2|host1" partition - (default: all) filter for this partition Ex: valid regexps, "C:", "REGISTRY", "REGISTRY|REPAIRDISK" level - (default: full) filter for this level Ex: valid regexps, "full", "full|incr", 9 start_time - (default: 24 hours ago) produce stats for this length of time Set period to "all" to get the stats from the whole log file. Ex: "-5 days", "three hours", "20 minutes", etc. end_time - (default: now) Stats will be printed for any backups performed within period before the day specified. Day may be in practially any format. Ex: "today", "three days ago", "June 15th", "last sunday", etc. Remember to quote it if it contains spaces. }; my $csv_h; # file handle for csv file my $want_host; # host to use my $want_part; # partition to use my $want_level; # level to use my $want_start_time; # the length of time to get stats for my $want_end_time; # the day to get stats for my $want_record; # flag used while reading file to # determine if we care about the # current record my $stat; # csv is read in here. my %opt; # holds cmd line options my $csv; # csv reader my $line; # columns from parsed log my $time_format; # How to format the time. sub format_bytes { my $bytes = shift; my $ret; if($bytes < 1024) { return sprintf("%.2f bytes", $bytes); } elsif ($bytes < 1024**2) { return sprintf("%.2f KB", ($bytes / 1024)); } elsif ($bytes < 1024**3) { return sprintf("%.2f MB", ($bytes / (1024**2))); } elsif ($bytes < 1024**4) { return sprintf("%.2f GB", ($bytes / (1024**3))); } else { return sprintf("%.2f TB", ($bytes / (1024**4))); } } $time_format = "%a, %B %E %i:%M%p"; # read in cmd line opts. getopt("c:h:p:l:d:t:", \%opt); die $usage if not defined $opt{c}; $csv_h = new IO::File("$opt{c}") or die $usage; $want_host = $opt{h} or undef; # host from cmd line if any $want_part = $opt{p} or undef; # partition " " if(defined $opt{l}) { # backup level $want_level = $opt{l}; } else { $want_level = "full"; } if(defined $opt{d}) { # date of backup $want_end_time = ParseDate($opt{d}); } else { $want_end_time = ParseDate("today"); } if(defined $opt{t}) { # period of time to use if($opt{t} eq "all") { $want_start_time = UnixDate("epoch 0", "%s"); } else { $want_start_time = UnixDate(DateCalc($opt{t}, $want_end_time), "%s"); } $want_end_time = UnixDate($want_end_time, "%s"); } else { $want_start_time = UnixDate(DateCalc("-1 day", $want_end_time), "%s"); $want_end_time = UnixDate($want_end_time, "%s"); } if($want_end_time < $want_start_time) { # swap vals if calculations # mix them up my $tmp = $want_start_time; $want_start_time = $want_end_time; $want_end_time = $tmp; } # setup the csv handler. $csv = new Text::CSV_XS({eol => "\n"}); $line = $csv->getline($csv_h); # parse the line while($#{$line} > -1) { # extract the variables my ($name, $start_time, $stop_time, $partition, $size, $level) = @{$line}; $want_record = 1; $want_record = undef if defined $want_host and not $name =~ /$want_host/; $want_record = undef if defined $want_level and not $level =~ /$want_level/; $want_record = undef if defined $want_part and not $partition =~ /$want_part/; $want_record = undef if (defined $want_start_time and defined $want_end_time) and ($start_time < $want_start_time or $start_time > $want_end_time); # stuff the info into our structure if($want_record) { $stat->{name}->{$name}->{$partition}->{total} += $size; $stat->{name}->{$name}->{$partition}->{$start_time} = $size; $stat->{"time"}->{$start_time}->{$name}->{total} += $size; $stat->{"time"}->{$start_time}->{$name}->{$partition}->{size} = $size; $stat->{"time"}->{$start_time}->{$name}->{$partition}->{level} = $level; $stat->{endtimes}->{$start_time} = $stop_time; } $line = $csv->getline($csv_h); } for my $name (sort keys %{$stat->{name}}) { print "Avg for $name:\n"; for my $partition (sort keys %{$stat->{name}->{$name}}) { print "\t$partition: " . format_bytes($stat->{name}->{$name}->{$partition}->{total} / ((scalar keys %{$stat->{name}->{$name}->{$partition}})-1)), "\n" unless $partition eq "total"; } } for my $time (sort keys %{$stat->{"time"}}) { my $time_f = UnixDate("epoch $time", $time_format); my $endtime_f = UnixDate("epoch " . $stat->{endtimes}->{$time}, $time_format); print "\n\n" if format_page_number STDOUT == 0; format_lines_left STDOUT 0; format_formfeed STDOUT "\n----------------------------------------------------------------------\n"; { local $^W = 0; eval "format STDOUT_TOP = Start Time: $time_f End Time: $endtime_f Machine Name Partition Size Level ------------- ----------------------------------- ------- ----- ."} for my $host (sort keys %{$stat->{"time"}->{$time}}) { PARTITION: for my $part (sort keys %{$stat->{"time"}->{$time}->{$host}}) { next PARTITION if $part eq "total"; my ($size, $level) = (format_bytes($stat->{"time"}->{$time}->{$host}->{$part}->{size}), $stat->{"time"}->{$time}->{$host}->{$part}->{level}); format STDOUT = @<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @>>>>>> @<<<< $host, $part, $size, $level . write; } } }