GoAccessとは
GoAccessは、CLIで動作するリアルタイムアクセスログ解析ツールです。
htopを眺める感覚でリアルタイムにログ解析ができます。
GoAccessでリアルタイムにアクセスログを解析する でより分かりやすく解説されています。
背景
リアルタイムアクセスログ解析といえば、いまどきは fluentd + elasticsearch + kibana3
のような構成が主流だと思います。簡単に設定できるうえ、見た目にもきれいで分かりやすいですからね。
fluentd + elasticsearch + kibana3
の構成を組む場合、ウェブサーバーのログをLTSV形式で出力するようにしておくと fluentd
でパースするときに難解な正規表現を書く必要がなくなり便利なのですが、それだとGoAccessでパースができなくなります。
せっかくなので fluentd + elasticsearch + kibana3
の構成を組みつつ、GoAccessでも解析できるようにしたいと思います。
導入
早速、GoAccessをインストールしましょう。
環境
- DigitalOcean
- CentOS6.5 x86_64
- nginx 1.4.3
- goaccess 0.7.1
インストール(RHEL)
GoAccessは yum
に epel
リポジトリを追加すれば簡単にインストールできます。
sudo yum --enablerepo=epel -y install goaccess
srcからビルドしたい場合は 公式ドキュメント を参照してください
設定
nginx
nginx.confにLTSV形式でログを出力するためのフォーマットを追加します。
log_format ltsv "host:$remote_addr"
"\tuser:$remote_user"
"\ttime:$time_local"
"\treq:$request"
"\tstatus:$status"
"\tsize:$body_bytes_sent"
"\treferer:$http_referer"
"\tua:$http_user_agent"
"\tforwardedfor:$http_x_forwarded_for"
"\treqtime:$request_time"
"\tapptime:$upstream_response_time";
nginx.confにフォーマットを追加したら、アクセスログをLTSV形式で出力するように変更します。
access_log /var/log/nginx/ap.access.log ltsv;
設定が終わったらnginxをリロードします。
sudo /bin/bash -c "service nginx configtest && service nginx reload"
apache
apacheの場合は以下の設定をLogFormatとして追加します。
(最後のapptimeの項目は便宜上nginxのフォーマットと揃えるためのダミーです)
LogFormat "\
host:%h\
\tuser:%u\
\ttime:%t\
\ttime:%{%d/%b/%Y:%T %z}t\
\treq:%r\
\tstatus:%>s\
\tsize:%b\
\treferer:%{Referer}i\
\tua:%{User-Agent}i\
\tforwardedfor:%{X-Forwarded-For}i\
\treqtime:%D\
\tapptime:%D" ltsv
フォーマットを追加したら、アクセスログをLTSV形式で出力するように変更します。
CustomLog logs/access_log ltsv
nginx同様、設定が終わったらapacheをリロードします。
sudo /bin/bash -c "service httpd configtest && service httpd reload"
GoAccess
LTSV形式のログをパースするためのカスタムログフォーマットを定義します。
nginx用
color_scheme 2
date_format %d/%b/%Y
time_format %H:%M:%S
log_format host:%h\tuser:%^\ttime:%d:%t %^\treq:%r\tstatus:%s\tsize:%b\treferer:%R\tua:%u\tforwardedfor:%^\treqtime:%T\tapptime:%^
この定義で、下記フォーマットのログをパースできるようになります。
host:192.168.1.23 user:- time:18/Mar/2014:04:46:39 +0000 req:GET /fonts/fontawesome-webfont.woff?v=4.0.3 HTTP/1.1 status:200 size:44432 referer:https://example.com/invitation ua:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36 forwardedfor:192.168.1.23 reqtime:0.006 apptime:0.006
apache用
color_scheme 2
date_format %d/%b/%Y:%T %z
log_format host:%h\tuser:%^\ttime:%d\treq:%r\tstatus:%s\tsize:%b\treferer:%R\tua:%u\tforwardedfor:%^\treqtime:%D\tapptime:%^
この定義で、下記フォーマットのログをパースできるようになります。
host:192.168.1.23 user:- time:18/Mar/2014:04:46:39 +0900 req:GET /fonts/fontawesome-webfont.woff?v=4.0.3 HTTP/1.1 status:200 size:7149 referer:- ua:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1) forwardedfor:- reqtime:435959 apptime:435965
使い方
使い方はとても簡単、解析したいログファイル
と カスタムログフォーマット
を指定するだけです。
goaccess -f /var/log/nginx/ap.access.log -p /etc/goaccess/ltsv.nginx
おまけ
上記の使い方では、サーバー毎のアクセス解析しかできません。
ウェブサーバーが複数台あれば fluentd
でアクセスログをログサーバーに集約していることが多いと思います。
せっかくなので、fluentd
が集約している最中のアクセスログも解析できるようにしてみましょう。
td-agent
ウェブサーバー側の設定
# input
<source>
type tail
format ltsv
path /var/log/nginx/ap.access.log
pos_file /var/log/td-agent/nginx.ap.access.log.pos
time_format %d/%b/%Y:%H:%M:%S %z
tag nginx.ap.access.log
</source>
# output
<match nginx.ap.access.log>
type forward
send_timeout 60s
recover_wait 60s
heartbeat_interval 1s
phi_threshold 8
hard_timeout 60s
<server>
name logme
host 192.168.1.45
port 24224
weight 60
</server>
</match>
ログサーバー側の設定
fluent-plugin-typecastで特定のフィールドを数値に変換しています。
# input
<source>
type forward
port 24224
bind 0.0.0.0
</source>
# output
<match nginx.ap.access.log>
type typecast
item_types time:time,status:integer,size:integer,reqtime:float,apptime:float
time_format %d/%b/%Y:%H:%M:%S %z
prefix cast
</match>
<match cast.nginx.ap.access.log>
type file
path /var/log/td-agent/ap.access.log
time_slice_format %Y%m%d
time_slice_wait 5m
compress gzip
</match>
各ウェブサーバーのアクセスログがログサーバーに集約されます。
-rw-r--r-- 1 td-agent td-agent 8345 3月 20 00:05 2014 ap.access.log.20140319_0.log.gz
-rw-r--r-- 1 td-agent td-agent 5490 3月 21 00:05 2014 ap.access.log.20140320_0.log.gz
-rw-r--r-- 1 td-agent td-agent 5852 3月 21 09:36 2014 ap.access.log.20140321.b4f51468d38e9c1d8
GoAccess
fluentd
が出力するログをパースするためのカスタムログフォーマットを定義します。
nginx用
color_scheme 2
date_format %F
log_format %dT%^\t%^\t{"host":"%h","user":"%^","req":"%r","status":%s,"size":%b,"referer":"%R","ua":"%u","forwardedfor":"%^","reqtime":%T,"apptime":%^}
この定義で、下記フォーマットのログをパースできるようになります。
2014-03-21T04:30:51+00:00 cast.nginx.ap.access.log {"host":"192.168.1.23","user":"-","req":"GET /test HTTP/1.1","status":302,"size":0,"referer":"https://example.com/invitation","ua":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36","forwardedfor":"192.168.1.23","reqtime":1.012,"apptime":1.012}
apache用
color_scheme 2
date_format %F
log_format %dT%^\t%^\t{"host":"%h","user":"%^","req":"%r","status":%s,"size":%b,"referer":"%R","ua":"%u","forwardedfor":"%^","reqtime":%D,"apptime":%^}
この定義で、下記フォーマットのログをパースできるようになります。
2014-03-21T04:30:51+00:00 cast.httpd.ap.access.log {"host":"192.168.1.23","user":"-","req":"GET /test HTTP/1.1","status":302,"size":0,"referer":"https://example.com/invitation","ua":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36","forwardedfor":"192.168.1.23","reqtime":435959,"apptime":435959}
使い方
使い方はこうなります。
goaccess -f /var/log/td-agent/ap.access.log.20140321.b4f51468d38e9c1d8 -p /etc/goaccess/ltsv.fluentd.nginx
fluentd
で集約しているログを解析する場合、解析されるタイミングは fluentd
の buffer
からログファイルに flush
されるタイミングに依存するため、ウェブサーバーで直接ログファイルを解析している場合と比べリアルタイム性はかなり落ちます。
まとめ
インストールも使い方もとても簡単ですね。 tail
や grep
で地味にログをチェックするという作業に GoAccess
で解析するという一手間を加えてみるといいです。
404
になっているファイルやロードに時間がかかっているリソースも一目瞭然なので開発時から活躍してくれると思います。