Help us understand the problem. What is going on with this article?

GoAccessでLTSV形式のアクセスログをリアルタイムに解析する

More than 1 year has passed since last update.

GoAccessとは

GoAccessは、CLIで動作するリアルタイムアクセスログ解析ツールです。
htopを眺める感覚でリアルタイムにログ解析ができます。

goaccess01

GoAccessでリアルタイムにアクセスログを解析する でより分かりやすく解説されています。

背景

リアルタイムアクセスログ解析といえば、いまどきは fluentd + elasticsearch + kibana3 のような構成が主流だと思います。簡単に設定できるうえ、見た目にもきれいで分かりやすいですからね。

fluentd + elasticsearch + kibana3 の構成を組む場合、ウェブサーバーのログをLTSV形式で出力するようにしておくと fluentd でパースするときに難解な正規表現を書く必要がなくなり便利なのですが、それだとGoAccessでパースができなくなります。

せっかくなので fluentd + elasticsearch + kibana3 の構成を組みつつ、GoAccessでも解析できるようにしたいと思います。

導入

早速、GoAccessをインストールしましょう。

環境

インストール(RHEL)

GoAccessは yumepel リポジトリを追加すれば簡単にインストールできます。

sudo yum --enablerepo=epel -y install goaccess

srcからビルドしたい場合は 公式ドキュメント を参照してください

設定

nginx

nginx.confにLTSV形式でログを出力するためのフォーマットを追加します。

/etc/nginx/nginx.conf
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形式で出力するように変更します。

/etc/nginx/conf.d/ap.conf
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のフォーマットと揃えるためのダミーです)

/etc/httpd/conf/httpd.conf
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形式で出力するように変更します。

/etc/httpd/conf.d/ap.conf
CustomLog logs/access_log ltsv

nginx同様、設定が終わったらapacheをリロードします。

sudo /bin/bash -c "service httpd configtest && service httpd reload"

GoAccess

LTSV形式のログをパースするためのカスタムログフォーマットを定義します。

nginx用

/etc/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:%^

この定義で、下記フォーマットのログをパースできるようになります。

/var/log/nginx/ap.access.log
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用

/etc/goaccess/ltsv.httpd
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:%^

この定義で、下記フォーマットのログをパースできるようになります。

/var/log/httpd/ap.access.log
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

ウェブサーバー側の設定

/etc/td-agent/conf.d/nginx.conf
# 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で特定のフィールドを数値に変換しています。

/etc/td-agent/conf.d/nginx.conf
# 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用

/etc/goaccess/ltsv.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":%^}

この定義で、下記フォーマットのログをパースできるようになります。

/var/log/td-agent/ap.access.log
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用

/etc/goaccess/ltsv.fluentd.httpd
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":%^}

この定義で、下記フォーマットのログをパースできるようになります。

/var/log/td-agent/ap.access.log
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 で集約しているログを解析する場合、解析されるタイミングは fluentdbuffer からログファイルに flush されるタイミングに依存するため、ウェブサーバーで直接ログファイルを解析している場合と比べリアルタイム性はかなり落ちます。

まとめ

インストールも使い方もとても簡単ですね。 tailgrep で地味にログをチェックするという作業に GoAccess で解析するという一手間を加えてみるといいです。

404 になっているファイルやロードに時間がかかっているリソースも一目瞭然なので開発時から活躍してくれると思います。

msykiino
SREチームリーダー
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした