« Direct2D | トップページ | Xperia購入! »

Linuxサーバ管理:apacheログを集計する

少しずつですがUNIX/Linuxサーバやネットワークの管理者として必要な基本的なことを書いていこうと思います。

今回はWebサーバのdownloadフォルダからどのファイルが何回ダウンロードされているのかをコマンドで集計して表示させます。こんな感じです。

result

これを表示させるコマンドは初めて見ると魔法に見えるのですが実際はすごく単純です。

まず、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 "http://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コマンドを使うだけでもよいでしょう。

|

« Direct2D | トップページ | Xperia購入! »

パソコン・インターネット」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/2371/47933380

この記事へのトラックバック一覧です: Linuxサーバ管理:apacheログを集計する:

« Direct2D | トップページ | Xperia購入! »