上司がアクセス数を出せって言うから...

エンジニアの重田です。

上司がアクセス数を出せって言うから...

man_perl.png

上司がログからアクセス数を出せって言うから、今日はコマンドの話をします。

とりあえずファイルの中身を見るには cat ですね。

$ cat /var/log/nginx/access.log | grep favicon.ico
192.168.56.1 - - [07/Apr/2012:15:58:58 +0900] "GET /favicon.ico HTTP/1.1" 200 133 "-" "Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0"
192.168.56.1 - - [07/Apr/2012:15:58:58 +0900] "GET /favicon.ico HTTP/1.1" 200 133 "-" "Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0"
192.168.56.1 - - [07/Apr/2012:16:02:20 +0900] "GET /favicon.ico HTTP/1.1" 200 133 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.152 Safari/535.19"
192.168.56.1 - - [07/Apr/2012:16:05:56 +0900] "GET /favicon.ico HTTP/1.1" 200 133 "-" "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)"

この例では grep を使って favicon.ico という文字が含まれる行を抽出してます。これで favicon.ico へのアクセスが分かりますね。
そして現在進行形での様子を見たいときには tail です。

$ tail -f /var/log/nginx/access.log | grep favicon.ico


-f オプションでログを流しつつ、この例では favicon.ico へのアクセスを見ています。
眺めていると安心して tail -f しているプロセスを消し忘れるので、確認が終わったら ctrl-c で終了しませう。

こうやって見ていると User Agent が気になりますよね。
たとえば次のようなログフォーマットだったとします。

192.168.56.1 - - [07/Apr/2012:16:29:33 +0900] "GET /index.html HTTP/1.1" 200 151 "http://192.168.56.101/" "Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0"

awk を使って細工します。

$ cat /var/log/nginx/access.log | awk -F '"' '{print $6}'
curl/7.21.6 (i686-pc-linux-gnu) libcurl/7.21.6 OpenSSL/1.0.0e zlib/1.2.3.4 libidn/1.22 librtmp/2.3
Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0
Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0
Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0
Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.152 Safari/535.19
Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.152 Safari/535.19
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0
Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0

-F は区切り文字の指定です。ここでは " を区切り文字として6番目に出てくる文字列を抽出しています。私はこういうのは cut コマンドよりも awk でやっつけちゃいます。

そして User Agent が重複しているのでそれを除きたいですよね。

$ cat /var/log/nginx/access.log | awk -F '"' '{print $6}' | sort | uniq
curl/7.21.6 (i686-pc-linux-gnu) libcurl/7.21.6 OpenSSL/1.0.0e zlib/1.2.3.4 libidn/1.22 librtmp/2.3
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.152 Safari/535.19
Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0

ほしがりなあなたは件数まで見たいとおっしゃる。uniq コマンドの -c オプションを使って。

$ cat /var/log/nginx/access.log | awk -F '"' '{print $6}' | sort | uniq -c
1 curl/7.21.6 (i686-pc-linux-gnu) libcurl/7.21.6 OpenSSL/1.0.0e zlib/1.2.3.4 libidn/1.22 librtmp/2.3
2 Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
2 Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.152 Safari/535.19
5 Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0

そうですよね。多い順に並べたいですよね。sort に -n と -r オプションをつけます。-n オプションは数値的にソートして、-r は逆順にソートします。

$ cat /var/log/nginx/access.log | awk -F '"' '{print $6}' | sort | uniq -c | sort -nr
5 Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0
2 Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.152 Safari/535.19
2 Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
1 curl/7.21.6 (i686-pc-linux-gnu) libcurl/7.21.6 OpenSSL/1.0.0e zlib/1.2.3.4 libidn/1.22 librtmp/2.3

これで上司に User Agent のランキングを見せることができますね。

あー。上司は母数を明示しないと納得しない人だと。おっしゃる通りです。ということでログファイルの行数が知りたいですよね。wc コマンドで -l オプションを使って行数を見てみましょう。

$ wc -l /var/log/nginx/access.log
10 /var/log/nginx/access.log

ついでに favicon.ico のアクセス数の母数も知りたいと。どんだけ favicon が好きなんでしょうね。

$ cat /var/log/nginx/access.log | grep favicon.ico | wc -l
4


こんな感じで行数を出せます。でも grep した後で wc で行数をカウントすると「無駄」って同僚に怒られます。

$ cat /var/log/nginx/access.log | grep -c favicon.ico
4

grep コマンドだって件数のカウントできます。これでコマンド呼び出す回数が減りましたね。
あ、そもそも cat いらないじゃんって。その通り!

$ grep -c favicon.ico /var/log/nginx/access.log
4

なんとコマンド一個で足りました ;p

知っているコマンドを列挙するだけでも実現できるけど実はそこには無駄があったりするので man コマンドを使ってその詳細を見てみるとよいでしょう。ここまでくればあなたはもうコマンドラインの虜です。

私もまだまだ使ったことないオプションもあるので今回の話は本当に触りの部分だけですがこの記事がターミナルに触れるきっかけとなるといいですね。

また今回は Perl を使っていませんがここに Perl を組み合わせるとより強力なことができます。それはまたの機会に。

そんな Perl ですが、今年も最大のイベント YAPC::Asia 2012 が開催されます。ご興味ある人は予定を空けておいてくださいね。現在はスポンサーを募集しておりますのでご興味がありましたらサイトをご覧ください

では素敵なコマンドライフを。

Six Apart をフォローしませんか?

次の記事へ

もしもZenbackが1万人の村だったら~アクセス解析にみるZenbackの特性~

前の記事へ

オフ会・勉強会で、Movable Type ユーザーの和を広げませんか?