A perlmonk (sundialsvc4) beat me to it as usual, here's some more:
The first example was bare as possible to
show the basic principle. In practice logs
have lots of redundancy so you should cache
and handle lookup errors. If this was run
for a very long time or a super busy site
you'd clear the cache once in a while too (with Vins reminder that
gethostbyaddr is obsolete (and slow)):
use strict;
use feature qw(say);
use Socket;
use File::Tail;
my $file = File::Tail->new("/some/log/file");
my $seen = {};
my $line;
while (defined($line = $file->read)) {
if ($line =~ /^DATE (IP) (WHATEVER)/) {
my $remote_ip = $1;
my $whatever = $2;
my $remote_host;
if ($seen->{$remote_ip}) {
$remote_host = $seen->{$remote_ip};
else {
$remote_host = getaddrinfo(inet_pton($remote_ip),AF_INET) |
+| 'none';
$seen->{$remote_ip} = $remote_host;
}
say join "\t", qw/$remote_ip $remote_host $whatever/;
}
}