#!/usr/bin/env perl # # procmailsum - summarize procmail log extracts # # $Id$ # in my .forward I have the line: # # "| procmail 2>&1 | tee -a $HOME/Mail/procmail.log | { grep -vi '^procmail: [^m]'; echo; } >> $HOME/Mail/procmail.err" # # It is the procmail.err files that this script summarizes. # It could be extended to also parse unfiltered procmail logs. require 5.005; use warnings; use strict; use Getopt::Std; use List::Util qw(sum); my %opt; getopts( 'hadt:', \%opt ); HELP_MESSAGE() if $opt{'h'}; sub HELP_MESSAGE { print STDERR <) { if (/^From (.*\S)/) { $from = $1; $from =~ s/\s+\w+\s+\w+\s+\d+\s+[\d:]+\s+\d+|s*$//; next; } elsif ( !/^\s*Folder:\s+/ ) { next; } # we're on the Folder: line defined $from or next; my ( $header, $folder, $size ) = m#(\S+)\s+(.*\S)\s+(\S+)#; defined $size or next; $header eq 'Folder:' or next; ++$folder2from2count{$folder}->{$from}; if ( $size eq '' || $size =~ /\D/ ) { warn sprintf "strange size %s for destination %s, ignored\n", $size, $folder; } else { $folder2from2size{$folder}->{$from} += $size; } undef($from); } sub keys_by_num_value { my $hashref = $_[0]; sort { $hashref->{$a} <=> $hashref->{$b} } keys %$hashref; } sub println { print join( $sep, @_ ), "\n"; } if ( $opt{d} ) { # report per folder my %folder2count = map { $_ => scalar( values %{ ( $folder2from2size{$_} ) } ) } keys %folder2from2size; my %folder2size = map { $_ => sum( values %{ ( $folder2from2size{$_} ) } ) } keys %folder2from2size; foreach my $d ( keys_by_num_value( \%folder2size ) ) { if ( $opt{a} ) { # report per folder and From: address foreach my $a ( keys_by_num_value( $folder2from2size{$d} ) ) { println( $folder2from2count{$d}->{$a}, $folder2from2size{$d}->{$a}, $d, $a ); } } else { println( $folder2count{$d}, $folder2size{$d}, $d ); } } } elsif ( $opt{a} ) # report per From: address { my %from2count; my %from2size; foreach my $d ( keys %folder2from2count ) { foreach my $a ( keys %{ $folder2from2count{$d} } ) { $from2count{$a} += $folder2from2count{$d}->{$a}; $from2size{$a} += $folder2from2size{$d}->{$a}; } } foreach my $a ( keys_by_num_value( \%from2size ) ) { println( $from2count{$a}, $from2size{$a}, $a ); } } else # only report the grand total { my %folder2count = map { $_ => scalar( values %{ ( $folder2from2size{$_} ) } ) } keys %folder2from2size; my %folder2size = map { $_ => sum( values %{ ( $folder2from2size{$_} ) } ) } keys %folder2from2size; println( sum( values %folder2count ), sum( values %folder2size ) ); }