Linuxサーバ管理:apacheログを集計する
まず、apacheのログのありかを捜します。Debianなどは「/var/log/apache2/」にあるaccess.logがそれに当たります。まずはこれを普通に見てみます。
catコマンドで見ていると山のようにテキストが表示されます。(IPアドレスはxxxに直してます)
以下、太字が入力したコマンド、それ以降がサーバからの表示です。
# cat /var/log/apache2/access.log
::1 - - [28/Mar/2010:06:25:06 +0900] "OPTIONS * HTTP/1.0" 200 - "-" "Apache/2.2.9 (Debian) PHP/5.2.6-1+lenny8 with Suhosin-Patch (internal dummy connection)"
115.177.61.xxx - - [28/Mar/2010:06:32:31 +0900] "POST /getip.php HTTP/1.0" 200 13 "-" "Mozilla/8.0libwww-perl/5.53"
61.115.200.xxx - - [28/Mar/2010:06:33:21 +0900] "GET /getip.php HTTP/1.1" 200 14 "-" "Mozilla/4.0 (compatible;)"
122.249.79.xxx - - [28/Mar/2010:06:51:11 +0900] "GET /getip.php HTTP/1.0" 200 14 "-" "ipcheck/1.0"
119.63.198.xxx - - [28/Mar/2010:07:11:23 +0900] "GET /robots.txt HTTP/1.1" 200 89 "-" "Baiduspider+(+http://www.baidu.com/search/spider.htm)"
1行は長いですがよくみるとIPアドレスや日付など一定のフォーマットになっていることがわかります。詳しく知りたい方は勉強してみてください。
ここからgrepコマンドを使ってdownloadを含む行だけを表示させます。googleのようにマッチした行だけを表示してくれるようになります。
# grep '/download' /var/log/apache2/access.log
67.195.112.xxx - - [28/Mar/2010:08:37:44 +0900] "GET /download/marmi-src090.7z HTTP/1.0" 200 652328 "-" "Mozilla/5.0 (compatible; Yahoo! Slurp/3.0; http://help.yahoo.com/help/us/ysearch/slurp)"
202.248.175.xxx - - [28/Mar/2010:13:05:33 +0900] "GET /download/Marmi0984.zip HTTP/1.1" 404 335 "-" "libwww-perl/5.833"
67.195.112.xxx - - [28/Mar/2010:13:31:15 +0900] "GET /download/ubuntu-ja-7.10-vpc.7z HTTP/1.0" 200 518661663 "-" "Mozilla/5.0 (compatible; Yahoo! Slurp/3.0; http://help.yahoo.com/help/us/ysearch/slurp)"
58.94.212.xxx - - [28/Mar/2010:16:31:35 +0900] "GET /download/ HTTP/1.1" 200 878 "https://yk.tea-nifty.com/netdev/2009/07/marmi-e771.html" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; GTB0.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)"
ただ、かなり見づらいですね。今回欲しいのは1行にファイル名だけなので表示をファイル名だけに絞ります。
これにはawkコマンドを使うのが簡単です。今回、ファイル名部分は英単語的に空白区切りで数えると行の7つめにあります。これをパイプ(|という記号です)を使ってgrepコマンドの結果をawkコマンドに渡します。
# grep '/download' /var/log/apache2/access.log | awk '{print $7;}'
/download/marmi-src090.7z
/download/Marmi0984.zip
/download/ubuntu-ja-7.10-vpc.7z
/download/
/icons/blank.gif
/icons/back.gif
/icons/compressed.gif
/icons/unknown.gif
/download/
/download/CSTimer152src.zip
/download/Marmi0984a.zip
/download/
ここまでで大分見やすくなりました。これを並び替えてみます。並び替えはsortコマンドを使います。またパイプします。並び替えするのは訳があって、いろいろなところに分散していると見づらいのと数を数えるのに支障をきたすからです。このsortコマンドと次に出てくるuniqコマンドはセットで使うことが多いです。
# grep '/download' /var/log/apache2/access.log | awk '{print $7;}' | sort
/download/
/download/
/download/
/download/CSTimer152src.zip
/download/Marmi0984.zip
/download/Marmi0984a.zip
/download/marmi-src090.7z
/download/ubuntu-ja-7.10-vpc.7z
/icons/back.gif
/icons/blank.gif
/icons/compressed.gif
/icons/unknown.gif
数を数えるのはuniqコマンドを使います。本来は重複した行を削る(ユニークな行だけを残す)コマンドですが、オプションの”-c”を使うことで何行出現したかも数えてくれます。
# grep '/download' /var/log/apache2/access.log | awk '{print $7;}' | sort | uniq -c
3 /download/
1 /download/CSTimer152src.zip
1 /download/Marmi0984.zip
1 /download/Marmi0984a.zip
1 /download/marmi-src090.7z
1 /download/ubuntu-ja-7.10-vpc.7z
1 /icons/back.gif
1 /icons/blank.gif
1 /icons/compressed.gif
1 /icons/unknown.gif
これでまずは目的達成ですが、これだけだとaccess.log1つだけしか集計されていません。実際にはapacheのログはいくつもあってこれらをすべて集計したいところです。
# ls /var/log/apache2/
access.log access.log.31.gz error.log.1 error.log.32.gz
access.log.1 access.log.32.gz error.log.10.gz error.log.33.gz
access.log.10.gz access.log.33.gz error.log.11.gz error.log.34.gz
access.log.11.gz access.log.34.gz error.log.12.gz error.log.35.gz
access.log.12.gz access.log.35.gz error.log.13.gz error.log.36.gz
access.log.13.gz access.log.36.gz error.log.14.gz error.log.37.gz
access.log.14.gz access.log.37.gz error.log.15.gz error.log.38.gz
access.log.15.gz access.log.38.gz error.log.16.gz error.log.39.gz
access.log.16.gz access.log.39.gz error.log.17.gz error.log.4.gz
access.log.17.gz access.log.4.gz error.log.18.gz error.log.40.gz
access.log.18.gz access.log.40.gz error.log.19.gz error.log.41.gz
access.log.19.gz access.log.41.gz error.log.2.gz error.log.42.gz
access.log.2.gz access.log.42.gz error.log.20.gz error.log.43.gz
このようにaccessログはログローテートという仕組みによって(たとえば)一日一回別ファイルに分離されます。また古いファイルはgzという形式の圧縮ファイルになっています。
これらをすべて対象とするにはgrepコマンドを圧縮ファイル対応のzgrepコマンドに変更し、対象ファイル名をaccess.log*と「アスタリスク *」印をつけることで全ファイルへ対処します。
# zgrep '/download' /var/log/apache2/access.log* | awk '{print $7;}' | sort | uniq -c
17 /
26 /download
280 /download/
6 /download/?C=D;O=A
3 /download/?C=D;O=D
17 /download/?C=M;O=A
6 /download/?C=M;O=D
6 /download/?C=N;O=A
20 /download/?C=N;O=D
12 /download/?C=S;O=A
5 /download/?C=S;O=D
2 /download/CSTimer120src.zip
45 /download/CSTimer1520src.zip
46 /download/CSTimer152src.zip
299 /download/CSTimer153src.zip
1 /download/Marmi09.zip
2 /download/Marmi090.zip
25 /download/Marmi092-src.zip
43 /download/Marmi092.zip
ということでおしまい。検索など必要ない場合は圧縮ファイル対応のzcatコマンドを使うだけでもよいでしょう。
| 固定リンク

コメント