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; } } }
