2012年11月5日月曜日

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


今回は、fluentdを利用して、Apacheのログを別サーバーのMongoDBに保存してみようと思います。

前回のlogサーバー(10.0.0.16)にmongoDBをホストし、webサーバー(10.0.0.8)のtd-agentから直接mongoに保存します。

まずはlogサーバーにmongoDBをインストールします。
yumリポジトリとして以下を追加してからyumインストールを行います。
# vi /etc/yum.repos.d/10gen.repo]
---
[10gen]
name=10gen Repository
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/i686
gpgcheck=0
---

# yum install mongo-10gen mongo-10gen-server -y

mongoのインストールは完了しました。
起動しておきます。
# /etc/init.d/mongod start


続いてwebサーバー側にmongoプラグインを設定します。
mongo Output Pluginはビルトインではなく、td-agent用のrubygemでインストールして使用するため、以下のようにインストールを行います。
# /usr/lib/fluent/ruby/bin/fluent-gem install fluent-plugin-mongo
Fetching: fluent-plugin-mongo-0.6.10.gem (100%)
Successfully installed fluent-plugin-mongo-0.6.10
1 gem installed
Installing ri documentation for fluent-plugin-mongo-0.6.10...
Installing RDoc documentation for fluent-plugin-mongo-0.6.10...


設定ファイルには、以下のように出力先をtype mongoを設定します。これは、

source
 apacheフォーマットの/var/log/httpd/access_logファイルをtailし、apache.accessというタグをつける

match
  apache.accessタグの入力があったら、10.0.0.16のmongoDBのfluentデータベースへmemorycraftユーザーで接続し、hogeコレクションとしてデータを登録する

という意味になります。
# 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 mongo
  database fluent
  collection hoge
  host 10.0.0.16
  user memorycraft
  password ******
</match>

---


この時点ではwebサーバーからlogサーバーへmongoの接続ポートが閉じているので、まだ接続できません。
EC2で、mongoのデフォルトポートの27017番を開放します。




ここで一度webサーバー側のtd-agentを再起動しておきます。
# /etc/init.d/td-agent restart


この時点でmongoに接続すると、fluentデータベースはできているようです。
ここで、認証用にユーザーを作成します。
# mongo
MongoDB shell version: 2.2.1
connecting to: test

> use fluent
switched to db fluent
> db.addUser("memorycraft", "*****")
{
 "_id" : ObjectId("5096e46f1b4da85be896fb1e"),
 "user" : "memorycraft",
 "readOnly" : false,
 "pwd" : "2922d9ce24a959b1f359f7ba2d044017"
}

これで認証が設定されたので、webサーバー側のtd-agentを改めて再起動します。
# /etc/init.d/td-agent restart


ここで、mongoシェルに接続してみるとfluentというDBにhogeというコレクションができていることがわかります。
# mongo
MongoDB shell version: 2.2.1
connecting to: test
> use fluent
switched to db fluent
> show collections
system.indexes
system.users
hoge


中身を見てみると、、、
> db.hoge.find()
{ "_id" : ObjectId("5096e4e5a3441113d4000001"), "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", "time" : ISODate("2012-11-04T21:57:09Z") }
{ "_id" : ObjectId("5096e4e5a3441113d4000002"), "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", "time" : ISODate("2012-11-04T21:57:10Z") }
{ "_id" : ObjectId("5096e4e5a3441113d4000003"), "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", "time" : ISODate("2012-11-04T21:57:10Z") }
{ "_id" : ObjectId("5096e4e5a3441113d4000004"), "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", "time" : ISODate("2012-11-04T21:57:10Z") }



おおー。データが入っています。
たとえば、pathが"/"のデータのみのログも簡単に抽出できるようになりました!
> db.hoge.find({path:"/"})
{ "_id" : ObjectId("5096e4e5a3441113d4000001"), "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", "time" : ISODate("2012-11-04T21:57:09Z") }


このようにfluentdを用いると、ログの集約や集計がデイリーやマンスリーではなく準リアルタイムで行えるようになります。とても便利ですね。

今回はここまで。