2012年11月5日月曜日

Fluentdってなんじゃ?(Apache編)

前回は同じサーバー内でコマンドからファイル出力を行いました。
内容としては以下のような流れです。

  +--------------------------------------+
  | server                               |
  +--------------------------------------+
  |                fluentd               |
  |                                      |
  | +-------------+       +------------+ |
  | |    input    |       |   output   | |
  | |-------------| +---> |------------| |
  | |command(tcp) |       |    file    | |
  | +-------------+       +------------+ |
  +--------------------------------------+

今回はApacheのログを別のサーバーにファイル転送してみたいと思います。
以下のようなイメージです。
  +--------------------------------------+   +--------------------------------------+
  | web server (10.0.0.8)                |   | log server (10.0.0.16)               |
  +--------------------------------------+   |--------------------------------------|
  |                fluentd               |   |               fluentd                |
  |                                      |   |                                      |
  | +-------------+       +------------+ |   | +------------+       +-------------+ |
  | |    input    |       |   output   | |   | |   input    |       |    output   | |
  | |-------------| +---> |------------| +---> |------------| +---> |-------------| |
  | |    tail     |       |    tcp     | |   | |   tcp      |       |    file     | |
  | +-------------+       +------------+ |   | +------------+       +-------------+ |
  +--------------------------------------+   +--------------------------------------+


まず、送信側のwebサーバーでは、以下のようにアパッチのログをapache.accessというタグでtailし、tcp送信するように設定します。

source

 ログのフォーマット指定でapacheを指定することでapacheのログ構造をJSON化できるようになります。
そのほかにはsyslogのフォーマットがプリセットで指定できますが、その他アプリのログなどは名前付きキャプチャの正規表現で指定することにより、任意のプロパティ名でJSON化できます。

match

 matchディレクティブで設定するforwardは、Bufferd Outputプラグインというタイプで、デフォルトではメモリにデータをバッファし60秒でflushします。
つまり60秒に一回まとめて送信を行います。今回はわかりやすくリアルタイムで行うよう、flush_intervalを0sとし、0秒でflushするように設定してみます。
また、serverディレクティブで送信先のサーバーのIPを指定します。 特に指定しない場合、ポートは24224番が使用されます。

# vim /etc/td-agent/td-agent.conf
---
<source>
  type tail
  format apache
  path /var/log/httpd/access_log
  tag apache.access
</source>

<match apache.access>
  type forward
  flush_interval 0s
  <server>
    host 10.0.0.16
  </server>
</match>
---

# /etc/init.d/td-agent restart


受信側のサーバーにもtd-agentをインストールし、以下のように、tcpを受信しファイルに出力するように設定します。

source
 webサーバーのtcpから受信するためforward Input Pluginを指定します。

match
 apache.accessタグのデータを/var/log/fluent/apache_access_log***に書き出します。

# mkdir /var/log/fluent
# chown td-agent:td-agent /var/log/fluent
# vim /etc/td-agent/td-agent.conf
---
<source>
  type forward  
</source>

<match apache.access>
  type file
  path /var/log/fluent/apache_access_log
</match>
---

# /etc/init.d/td-agent start

ここで、webサーバーとlogサーバーの間にFWなどがある場合、fluentdのポートを開放する必要があります。 今回はEC2を使用しているので、Security Groupの設定でTCPの24224番を開放します。また、データ転送にはTCPを使用しますが、死活監視にはUDPが使われるので、両方を開放しておきます。



webサーバーのコンテンツにブラウザからアクセスしてみます。



すると、logサーバー側の/var/log/fluent/apache_access_log.xxxというファイルにJSONが記録されているのがわかります。
tail -1000f /var/log/fluent/apache_access_log.20121105.b4cdb099dbbaa1e42
---
2012-11-05T05:20:11+09:00 apache.access {"host":"219.117.233.241","user":"-","method":"GET","path":"/","code":"403","size":"5039","referer":"-","agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.1 Safari/537.17"}
2012-11-05T05:20:11+09:00 apache.access {"host":"219.117.233.241","user":"-","method":"GET","path":"/icons/poweredby.png","code":"304","size":"-","referer":"http://54.249.23.246/","agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.1 Safari/537.17"}
2012-11-05T05:20:11+09:00 apache.access {"host":"219.117.233.241","user":"-","method":"GET","path":"/icons/apache_pb.gif","code":"304","size":"-","referer":"http://54.249.23.246/","agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.1 Safari/537.17"}
2012-11-05T05:20:11+09:00 apache.access {"host":"219.117.233.241","user":"-","method":"GET","path":"/favicon.ico","code":"404","size":"288","referer":"-","agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.1 Safari/537.17"}

これで、リモートのサーバーにログを送ることができました。 また、このようにApacheのログがオブジェクト化されることで、後々集計集約しやすくなりました。

次回は、ログをDBに送り、抽出してみたいと思います。
以上です。