httpd(Apache2)にて、httpdのアクセスログから上位のIP、国別表示をしたくなった。
IPの集計であれば、下記のようなコマンドで集計できるはず。
cat /var/log/httpd/access_log | grep "解析したいURL" | cut -d " " -f 1 | sort | uniq -c|sort -nr
実行すると、下記のようにIPアクセスの多い順に並びます。
550 XXX.XXX.XXX.1 543 XXX.XXX.XXX.2 383 XXX.XXX.XXX.3 97 XXX.XXX.XXX.4 77 XXX.XXX.XXX.5 76 XXX.XXX.XXX.6 30 XXX.XXX.XXX.7 11 XXX.XXX.XXX.8 10 XXX.XXX.XXX.9 8 XXX.XXX.XXX.10 :
上位のアクセス者はなんでこんなに多い?あ、自分でした。
さらに、IPアドレスから国名を出すスクリプトを追加で入れたなら、こんな感じに。
$ cat /var/log/httpd/access_log | grep "解析したいURL" | cut -d " " -f 1 | sort | perl ip2cc_stdin.pl |uniq -c|sort -nr|less
550 XXX.XXX.XXX.1 JP 543 XXX.XXX.XXX.2 JP 383 XXX.XXX.XXX.3 JP 97 XXX.XXX.XXX.4 JP 77 XXX.XXX.XXX.5 US 76 XXX.XXX.XXX.6 JP 30 XXX.XXX.XXX.7 JP 11 XXX.XXX.XXX.8 US 10 XXX.XXX.XXX.9 US 8 XXX.XXX.XXX.10 US
国別が出て良い感じです。ip2cc_stdin.plの元となるものは、こちらのサイトを参考させていただき、標準入力のIPから国別がでるようにしてみました。感謝!
$ cat ip2cc_stdin.pl #!/usr/bin/perl use strict; my $file = 'ipv4.txt'; my @ipv4db = &file($file); my @stdin =; foreach (@stdin) { my $ipad = $_; chomp($ipad); print $ipad ." ". &ip2cc(*ipv4db, $ipad) . "\n"; } sub file { my $file = shift; open(FH, $file); my @lines = ; close(FH); chomp @lines; return @lines; } sub ip2cc { *ipv4db = shift; my $addr = shift; return if ($addr !~ /^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/); my $num; $num = ($num << 8) + $_ foreach (split(/\./, $addr)); my ($l, $r, $m); $l = 0; $r = $#ipv4db; while ($l <= $r) { $m = int(($l + $r) / 2); my ($start, $end, $cc) = split(/\t/, $ipv4db[$m]); if ($start <= $num && $num < $end) { return $cc; } elsif ($end < $num) { $l = $m + 1; } elsif ($start >= $num) { $r = $m - 1; } else { return; } } }