#!/usr/bin/perl # leech-detector -- analyze logs on stdin and print a summary on stdout # Copyright (C) 2004 Alex Schroeder # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . use Time::ParseDate; while () { m/^(\S+) \S+ \S+ \[(.*?)\] ".*?" (\d+)/ or die "Cannot parse:\n$_"; $ip = $1; $code = $3; $time = parsedate($2); $count{$ip}++; $first{$ip} = $time unless $first{$ip}; $last{$ip} = $time; $status{$ip} = () unless exists $status{$ip}; $status{$ip}{$code}++; $total++; } @result = sort {$count{$b} <=> $count{$a}} keys %count; foreach $ip (@result) { $avg = 0; if ($first{$ip} and $last{$ip} and $count{$ip} > 1) { $avg = ($last{$ip} - $first{$ip}) / ($count{$ip} -1); } printf "%20s %10d %3d%% %7s %s\n", $ip, $count{$ip}, 100 * $count{$ip} / $total, $avg ? sprintf('%.1fs', $avg) : '', join(', ', map { sprintf("%3d (%d%%)", $_, 100 * $status{$ip}{$_} / $count{$ip}) } sort { $status{$ip}{$b} <=> $status{$ip}{$a} } keys %{$status{$ip}}); }