A colleague of mine crapped it's .forward file and lost all email sent to him during the holidays. He asked me to retrieve from log files the address of each sender.
Postfix puts the sender and the adressee on separated lines, prefixing them with an ID; e.g.:
Aug 12 11:41:40 my.server.name postfix/qmgr[20459]: 6D41B1059: from=<sesso@email.it>, size=1008 (queue active)So I thought that was an easy thing to do: get all IDs of messages addressed to my colleague, then use the selected IDs to find the sender and you are done. After all, how many repeated IDs could there be in a week of logs?
Unfortunately, many!
That approach failed, I decided to scan the file line by line to find "from" and "to" lines, and keeping track of the encountered IDs with a hash. As soon as an hash value is completed (that is, you have all the three filled in: ID, "from" and "to"), check if the referred message was addressed to my colleague and, in case, save it for the report; then, in any case, cleanup the completed slot.
The whole script and its output are quite raw; in particular, the output could be easily beautified with formats, but this is a quick-and-dirty script, and it did the job, and it's free; could you ask for more? :-)
I would be happy if this code could help anyone; also, I would be happy if anyone could take a few seconds to write in some comments to it; I'd apreciate it a lot!
--bronto
#!/usr/bin/perl use strict ; use constant DEBUG => 0 ; my %counter ; { my %slots ; my @delivered ; open LOG,"< mail.log.filtered" or die $! ; while (<LOG>) { chomp ; my $id ; if (/(from|to)=<(\S+)>/) { my $direct = $1 ; my $actor = $2 ; $id = (split)[5] ; $id =~ s/:$// ; $slots{$id}{$direct} = $actor ; } if (defined $id and exists $slots{$id}{from} and exists $slots{$id}{to} ) { my ($from,$to) = @{$slots{$id}}{qw(from to)} ; print STDERR "DEBUG: [$from]->[$to]\n" if DEBUG ; push @delivered,[$id,$from,$to] if $to =~ /^cxpanico/ ; delete $slots{$id} ; } } close LOG or warn $! ; foreach my $ref (@delivered) { my ($id,$from,$to) = @$ref ; $counter{$from}++ ; } } foreach my $sender (reverse sort { $counter{$a} <=> $counter{$b} } keys %counter ) { print "$sender: $counter{$sender} mail" ; print "s" if $counter{$sender} > 1 ; print "\n" ; }
|
|---|