varnish のアクセスログをvarnishncsaでvirtualhostごとにログを取る

twitterでつぶやいてたら@xcir さんから回答もらった。

ログを取りたいvirtualhostごとにvarnishncsaを起動して、-m "RxHeader:^Host: a.example.net$" というオプションをつけてrequestヘッダ中のhostの内容がマッチしたものだけ特定のファイルにログを取るという方法。
もちろん教えていただいたこの方法でも良いのだけれど、virtualhostが増えてきたときにその数だけvarnishncsaを常駐させない方法はあるのだろうか?と考えたのでやってみた。

varnishncsaで1つのログに出力して、後で何とかする方法

varnishncsa のformatオプションの先頭に"%{host}i" を付けて、request中のhost ヘッダをログの先頭に追加する。

  • ex
FORMAT='%{host}i %h %l %u %t "%m %U%q %H" %s %b "%{Referer}i" "%{User-agent}i"'

これでvarnishncsaを起動すると、こんなログになる。

$ cat varnishncsa.log
foo.example.com 127.0.0.1 - - [21/Mar/2012:13:25:31 +0900] "GET / HTTP/1.1" 200 4439 "-" "curl"
bar.example.com 192.168.0.1 - - [21/Mar/2012:13:25:39 +0900] "GET / HTTP/1.1" 200 4439 "-" "curl"

あとはgrepを使ったり、apacheのsourceのsupportに含まれているsplit-logfile を使うなりで適当に処理する。

split-logfile

split-logfile を使うと

$ ls 
varnishncsa.log
$ split-logfile < varnishncsa.log 
$ ls
bar.example.com.log  foo.example.com.log  varnishncsa.log
$ cat foo.example.com.log
127.0.0.1 - - [21/Mar/2012:13:25:31 +0900] "GET / HTTP/1.1" 200 4439 "-" "curl"
$ cat bar.example.com.log 
192.168.0.1 - - [21/Mar/2012:13:25:39 +0900] "GET / HTTP/1.1" 200 4439 "-" "curl"
split-logfile を使うときの注意

(これはDNS、サイトの作り方にもよるけど) host headerでファイルを分けているだけなので、example.com と www.example.com は違うファイルになる。ログが散らばるのが嫌な場合はwebサーバ側で、example.comに来たらwww.example.com にリダイレクトする、というような処理をしておく。これでexample.com.log には30X redirectするログしか残らなくなり、www.example.com.log でアクセス解析等をすれば良い。もしくはsplit-logfile を改良 or スクリプトを自作する、など。



ref.